From 570f2d0c74073366084c337398b212aa648bade6 Mon Sep 17 00:00:00 2001 From: glihm Date: Sun, 17 Dec 2023 15:25:36 -0600 Subject: [PATCH 01/42] fix(katana-core): add missing submodule file (#1298) fix: add missing submodule file --- crates/katana/core/contracts/messaging/solidity/.gitignore | 1 - crates/katana/core/contracts/messaging/solidity/lib/forge-std | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 160000 crates/katana/core/contracts/messaging/solidity/lib/forge-std diff --git a/crates/katana/core/contracts/messaging/solidity/.gitignore b/crates/katana/core/contracts/messaging/solidity/.gitignore index 921f19d973..e7bddf5b3f 100644 --- a/crates/katana/core/contracts/messaging/solidity/.gitignore +++ b/crates/katana/core/contracts/messaging/solidity/.gitignore @@ -2,7 +2,6 @@ cache/ out/ logs/ -lib/forge-std/ # Ignores development broadcast logs !/broadcast diff --git a/crates/katana/core/contracts/messaging/solidity/lib/forge-std b/crates/katana/core/contracts/messaging/solidity/lib/forge-std new file mode 160000 index 0000000000..2f11269750 --- /dev/null +++ b/crates/katana/core/contracts/messaging/solidity/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 2f112697506eab12d433a65fdc31a639548fe365 From fc24a5a23584a847d2a69523671d4926dd899fe7 Mon Sep 17 00:00:00 2001 From: glihm Date: Sun, 17 Dec 2023 19:27:42 -0600 Subject: [PATCH 02/42] feat(katana-rpc): add ContractErrorData when it applies (#1297) * feat(katana-rpc): add ContractErrorData when it applies * fix: adjust StarknetApiError enum to include data * fix: clippy * fix: rework enum for StarknetApiError * fix: sort StarknetApiError code into ascending order * fix: group common fields at the bottom * fix: get StarknetApiError error fields before consuming it --- crates/katana/rpc/src/api/starknet.rs | 111 ++++++++++++++++++-------- crates/katana/rpc/src/starknet.rs | 12 ++- 2 files changed, 88 insertions(+), 35 deletions(-) diff --git a/crates/katana/rpc/src/api/starknet.rs b/crates/katana/rpc/src/api/starknet.rs index cefd0f1bcb..e619dc8156 100644 --- a/crates/katana/rpc/src/api/starknet.rs +++ b/crates/katana/rpc/src/api/starknet.rs @@ -16,73 +16,120 @@ use katana_rpc_types::transaction::{ DeclareTxResult, DeployAccountTxResult, InvokeTxResult, Tx, }; use katana_rpc_types::{ContractClass, FeeEstimate, FeltAsHex, FunctionCall}; -use starknet::core::types::TransactionStatus; +use starknet::core::types::{ContractErrorData, TransactionStatus}; -#[derive(thiserror::Error, Clone, Copy, Debug)] +#[derive(thiserror::Error, Clone, Debug)] +#[repr(i32)] pub enum StarknetApiError { #[error("Failed to write transaction")] - FailedToReceiveTxn = 1, + FailedToReceiveTxn, #[error("Contract not found")] - ContractNotFound = 20, + ContractNotFound, #[error("Invalid message selector")] - InvalidMessageSelector = 21, + InvalidMessageSelector, #[error("Invalid call data")] - InvalidCallData = 22, + InvalidCallData, #[error("Block not found")] - BlockNotFound = 24, + BlockNotFound, #[error("Transaction hash not found")] - TxnHashNotFound = 29, + TxnHashNotFound, #[error("Invalid transaction index in a block")] - InvalidTxnIndex = 27, + InvalidTxnIndex, #[error("Class hash not found")] - ClassHashNotFound = 28, + ClassHashNotFound, #[error("Requested page size is too big")] - PageSizeTooBig = 31, + PageSizeTooBig, #[error("There are no blocks")] - NoBlocks = 32, + NoBlocks, #[error("The supplied continuation token is invalid or unknown")] - InvalidContinuationToken = 33, + InvalidContinuationToken, #[error("Contract error")] - ContractError = 40, + ContractError { revert_error: String }, #[error("Invalid contract class")] - InvalidContractClass = 50, + InvalidContractClass, #[error("Class already declared")] - ClassAlreadyDeclared = 51, + ClassAlreadyDeclared, #[error("Invalid transaction nonce")] - InvalidTransactionNonce = 52, + InvalidTransactionNonce, #[error("Max fee is smaller than the minimal transaction cost (validation plus fee transfer)")] - InsufficientMaxFee = 53, + InsufficientMaxFee, #[error("Account balance is smaller than the transaction's max_fee")] - InsufficientAccountBalance = 54, + InsufficientAccountBalance, #[error("Account validation failed")] - ValidationFailure = 55, + ValidationFailure, #[error("Compilation failed")] - CompilationFailed = 56, + CompilationFailed, #[error("Contract class size is too large")] - ContractClassSizeIsTooLarge = 57, + ContractClassSizeIsTooLarge, #[error("Sender address in not an account contract")] - NonAccount = 58, + NonAccount, #[error("A transaction with the same hash already exists in the mempool")] - DuplicateTransaction = 59, + DuplicateTransaction, #[error("The compiled class hash did not match the one supplied in the transaction")] - CompiledClassHashMismatch = 60, + CompiledClassHashMismatch, #[error("The transaction version is not supported")] - UnsupportedTransactionVersion = 61, + UnsupportedTransactionVersion, #[error("The contract class version is not supported")] - UnsupportedContractClassVersion = 62, + UnsupportedContractClassVersion, #[error("An unexpected error occured")] - UnexpectedError = 63, + UnexpectedError, #[error("Too many storage keys requested")] - ProofLimitExceeded = 10000, + ProofLimitExceeded, #[error("Too many keys provided in a filter")] - TooManyKeysInFilter = 34, + TooManyKeysInFilter, #[error("Failed to fetch pending transactions")] - FailedToFetchPendingTransactions = 38, + FailedToFetchPendingTransactions, +} + +impl StarknetApiError { + fn code(&self) -> i32 { + match self { + StarknetApiError::FailedToReceiveTxn => 1, + StarknetApiError::ContractNotFound => 20, + StarknetApiError::InvalidMessageSelector => 21, + StarknetApiError::InvalidCallData => 22, + StarknetApiError::BlockNotFound => 24, + StarknetApiError::InvalidTxnIndex => 27, + StarknetApiError::ClassHashNotFound => 28, + StarknetApiError::TxnHashNotFound => 29, + StarknetApiError::PageSizeTooBig => 31, + StarknetApiError::NoBlocks => 32, + StarknetApiError::InvalidContinuationToken => 33, + StarknetApiError::TooManyKeysInFilter => 34, + StarknetApiError::FailedToFetchPendingTransactions => 38, + StarknetApiError::ContractError { .. } => 40, + StarknetApiError::InvalidContractClass => 50, + StarknetApiError::ClassAlreadyDeclared => 51, + StarknetApiError::InvalidTransactionNonce => 52, + StarknetApiError::InsufficientMaxFee => 53, + StarknetApiError::InsufficientAccountBalance => 54, + StarknetApiError::ValidationFailure => 55, + StarknetApiError::CompilationFailed => 56, + StarknetApiError::ContractClassSizeIsTooLarge => 57, + StarknetApiError::NonAccount => 58, + StarknetApiError::DuplicateTransaction => 59, + StarknetApiError::CompiledClassHashMismatch => 60, + StarknetApiError::UnsupportedTransactionVersion => 61, + StarknetApiError::UnsupportedContractClassVersion => 62, + StarknetApiError::UnexpectedError => 63, + StarknetApiError::ProofLimitExceeded => 10000, + } + } } impl From for Error { fn from(err: StarknetApiError) -> Self { - Error::Call(CallError::Custom(ErrorObject::owned(err as i32, err.to_string(), None::<()>))) + let code = err.code(); + let message = err.to_string(); + + let data = match err { + StarknetApiError::ContractError { revert_error } => { + Some(ContractErrorData { revert_error }) + } + _ => None, + }; + + Error::Call(CallError::Custom(ErrorObject::owned(code, message, data))) } } diff --git a/crates/katana/rpc/src/starknet.rs b/crates/katana/rpc/src/starknet.rs index 6e8ea78d0b..8d8d13ff1f 100644 --- a/crates/katana/rpc/src/starknet.rs +++ b/crates/katana/rpc/src/starknet.rs @@ -367,7 +367,9 @@ impl StarknetApiServer for StarknetApi { let res = self.sequencer.call(request, block_id).map_err(|e| match e { SequencerError::BlockNotFound(_) => StarknetApiError::BlockNotFound, SequencerError::ContractNotFound(_) => StarknetApiError::ContractNotFound, - SequencerError::EntryPointExecution(_) => StarknetApiError::ContractError, + SequencerError::EntryPointExecution(e) => { + StarknetApiError::ContractError { revert_error: e.to_string() } + } _ => StarknetApiError::UnexpectedError, })?; @@ -449,7 +451,9 @@ impl StarknetApiServer for StarknetApi { let res = self.sequencer.estimate_fee(transactions, block_id).map_err(|e| match e { SequencerError::BlockNotFound(_) => StarknetApiError::BlockNotFound, - SequencerError::TransactionExecution(_) => StarknetApiError::ContractError, + SequencerError::TransactionExecution(e) => { + StarknetApiError::ContractError { revert_error: e.to_string() } + } _ => StarknetApiError::UnexpectedError, })?; @@ -473,7 +477,9 @@ impl StarknetApiServer for StarknetApi { .estimate_fee(vec![tx], block_id) .map_err(|e| match e { SequencerError::BlockNotFound(_) => StarknetApiError::BlockNotFound, - SequencerError::TransactionExecution(_) => StarknetApiError::ContractError, + SequencerError::TransactionExecution(e) => { + StarknetApiError::ContractError { revert_error: e.to_string() } + } _ => StarknetApiError::UnexpectedError, })? .pop() From 1411e2a772b56cdf2174fbd2f97555aaf1f36ee9 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Mon, 18 Dec 2023 23:21:41 +0800 Subject: [PATCH 03/42] Benchmark contract class de/compression (#1292) * add bench for contract compression --- Cargo.lock | 121 + crates/katana/storage/db/Cargo.toml | 6 + .../db/benches/artifacts/dojo_world_240.json | 12613 ++++++++++++++++ crates/katana/storage/db/benches/codec.rs | 47 + 4 files changed, 12787 insertions(+) create mode 100644 crates/katana/storage/db/benches/artifacts/dojo_world_240.json create mode 100644 crates/katana/storage/db/benches/codec.rs diff --git a/Cargo.lock b/Cargo.lock index 4732f7ffd8..974617abcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "0.6.5" @@ -1729,6 +1735,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.83" @@ -1769,6 +1781,33 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -2102,6 +2141,42 @@ dependencies = [ "winapi", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits 0.2.17", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam" version = "0.8.2" @@ -4474,6 +4549,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "handlebars" version = "4.5.0" @@ -5380,7 +5461,9 @@ dependencies = [ "anyhow", "bincode 1.3.3", "blockifier", + "cairo-lang-starknet", "cairo-vm", + "criterion", "katana-primitives", "page_size", "parking_lot 0.12.1", @@ -6816,6 +6899,34 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits 0.2.17", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polling" version = "2.8.0" @@ -9282,6 +9393,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/crates/katana/storage/db/Cargo.toml b/crates/katana/storage/db/Cargo.toml index a0432e0fb0..75870a70fd 100644 --- a/crates/katana/storage/db/Cargo.toml +++ b/crates/katana/storage/db/Cargo.toml @@ -31,6 +31,8 @@ package = "reth-libmdbx" rev = "b34b0d3" [dev-dependencies] +cairo-lang-starknet.workspace = true +criterion = "0.5.1" starknet.workspace = true tempfile = "3.8.1" @@ -38,3 +40,7 @@ tempfile = "3.8.1" default = [ "postcard" ] postcard = [ "dep:postcard" ] test-utils = [ "dep:tempfile" ] + +[[bench]] +harness = false +name = "codec" diff --git a/crates/katana/storage/db/benches/artifacts/dojo_world_240.json b/crates/katana/storage/db/benches/artifacts/dojo_world_240.json new file mode 100644 index 0000000000..51587e589e --- /dev/null +++ b/crates/katana/storage/db/benches/artifacts/dojo_world_240.json @@ -0,0 +1,12613 @@ +{ + "sierra_program": [ + "0x1", + "0x4", + "0x0", + "0x2", + "0x4", + "0x0", + "0x8b0", + "0x750", + "0xe4", + "0x506564657273656e", + "0x800000000000000100000000000000000000000000000000", + "0x556e696e697469616c697a6564", + "0x800000000000000200000000000000000000000000000001", + "0x1", + "0x0", + "0x75313238", + "0x800000000000000700000000000000000000000000000000", + "0x537472756374", + "0x800000000000000700000000000000000000000000000003", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x2", + "0x7538", + "0x4e6f6e5a65726f", + "0x800000000000000700000000000000000000000000000001", + "0x4", + "0x800000000000000700000000000000000000000000000002", + "0x5", + "0x800000000000000f00000000000000000000000000000001", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x22", + "0x800000000000000300000000000000000000000000000003", + "0x7", + "0x8", + "0x456e756d", + "0x61021b87bfddaed5690a1345623b249d8c10a98a5a713f2a4a521d1567126f", + "0x6", + "0x9", + "0x25e2ca4b84968c2d8b83ef476ca8549410346b00836ce79beaf538155990bb2", + "0xb", + "0xc", + "0x2a5d3c8622e550c6ea23180508b4fc17d3289f39036e68ddad11bd6a05c4ae5", + "0xd", + "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", + "0xf", + "0x10", + "0x3212619536443ad5ebedb7943a63ca0a270a26dd62320088e42057755d6b4b7", + "0x12", + "0x3490b45e9ebba149ad563aedee5ac231cce0b220754f2e0b3a3fb3075bae907", + "0x13", + "0x553132384d756c47756172616e746565", + "0x28edf843b90fd4464a9cf1779d01f8e7ce719fb66247954f300bf315f31bb23", + "0x17", + "0x38e5e97b4fd4b5ec8653ac59ee5e53c9a5f1b69275cba05f7228126a7004485", + "0x18", + "0x12867ecd09c884a5cf1f6d9eb0193b4695ce3bb3b2d796a8367d0c371f59cb2", + "0x1c", + "0x2ce4352eafa6073ab4ecf9445ae96214f99c2c33a29c01fcae68ba501d10e2c", + "0x536e617073686f74", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x20", + "0x66656c74323532", + "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", + "0x800000000000000700000000000000000000000000000005", + "0x21", + "0x23", + "0x6674d95cd1bd0dbe726032fc9199ab86923a7c44cdd22efabbc3bdeb4dd800", + "0x24", + "0x26", + "0x34c1a4ee6ef3ec231b7e21635f0ab0f5e73f747e42beb02d65fc54c8e0e0575", + "0x27", + "0x28", + "0xc048ae671041dedb3ca1f250ad42a27aeddf8a7f491e553e7f2a70ff2e1800", + "0x800000000000000300000000000000000000000000000005", + "0x148ac8a1a92f797fc0df7a766d21db68e3b15883eaacab5f2f750e883d74f3", + "0x2b", + "0x426f78", + "0x53ab85eada0a6ea028c03d62be3bee85e33846f2cb70861f36156d3c342647", + "0x2d", + "0x800000000000000300000000000000000000000000000007", + "0x366297339d1e0201b5a58c410076507621ab70e220d351d6614955cea9d16f6", + "0x30", + "0x2360086d8de14207bc705f7c51c3fc6bb6de6b826f1a4576e4db739d8b5edaf", + "0x32", + "0x34dec06b88f7854dce5a4288dde0eaff2dfb5f30900147a9c479e8300ae4ea0", + "0x34", + "0x1f5d91ca543c7f9a0585a1c8beffc7a207d4af73ee640223a154b1da196a40d", + "0x36", + "0x38", + "0x39", + "0x28f8d296e28032baef1f420f78ea9d933102ba47a50b1c5f80fc8a3a1041da", + "0x800000000000000300000000000000000000000000000004", + "0x3b", + "0x322c567022c4c08d2a5871dd773376f5aaadec29efd48cea7c33970c963c577", + "0x3c", + "0x14edfa2cfd8b5d67fab5028191e2fb4b5621cd19f55a2393ef2bfd5fa83988c", + "0x3e", + "0x949e9fd3b1ab222a7de8378c2d7759b5d9450bd4a5d812efdca682d9654cba", + "0x40", + "0x53746f726167654261736541646472657373", + "0x42", + "0x10a4ad544c3e0608b1a9e1ff69b5fdc230bace25740547273d3877854c8b722", + "0x6c", + "0xfeece2ea7edbbbebeeb5f270b77f64c680a68a089b794478dd9eca75e0196a", + "0x45", + "0x1166fe35572d4e7764dac0caf1fd7fc591901fd01156db2561a07b68ab8dca2", + "0x436f6e747261637441646472657373", + "0x1a99c1b614cd93625c69ae02a5553101decaee53ffa7db718e59eff185daf16", + "0x48", + "0x2451e06797647a3e95fc97c1e1f47212701fe5152a5120d4247f7dab43172c4", + "0x49", + "0x800000000000000300000000000000000000000000000002", + "0x4a", + "0x1122eaa6e4c0bd118679fcf107da7e4e36cc6b9bab8c946a30ecea3a78b4185", + "0x4b", + "0x2bcddf47e99bd2b365b672ce4ab3c5daf69bca568e14d0c1ccc9cee29ffaf43", + "0x4d", + "0x594b3f1a08277a00b497fbb1188a95b20ea7057b5de533ee96a550d3b80167", + "0x19d4b8cccf30503fa12e56f1e2d3f4febb93fbc007a09cd46d3020df9cd39ff", + "0x50", + "0x2a594b95e3522276fe0ac7ac7a7e4ad8c47eaa6223bc0fd6991aa683b7ee495", + "0x52", + "0x800000000000000700000000000000000000000000000004", + "0x753332", + "0x39a088813bcc109470bd475058810a7465bd632650a449e0ab3aee56f2e4e69", + "0x55", + "0x1289347a53bd537cb2be622dc3ef1bae97ae391de352ed7871b08a409f130a8", + "0x161ee0e6962e56453b5d68e09d1cabe5633858c1ba3a7e73fee8c70867eced0", + "0x436c61737348617368", + "0x14a7ddbb1150a2edc3d078a24d9dd07049784d38d10f9253fc3ece33c2f46a3", + "0x59", + "0x248e8fae2f16a35027771ffd74d6a6f3c379424b55843563a18f566bba3d905", + "0x104eb68e98232f2362ae8fd62c9465a5910d805fa88b305d1f7721b8727f04", + "0x5c", + "0x2b7d7ba3941973848ac6cf54700aef16585308fda69a60339f4fcd1909a664f", + "0x1208056def375849c0911a718ade519d5927c964cb7a78beb7d643e7a9d33ac", + "0x3fea2de5dea9ec02619bd14314e9e3ccb68732927bf526d266ecaadbe93d7f", + "0x1cbb1269d92ec36a7bf9fd3d23e2ad0b9f621a30a3f8f4f1993644a73dfbd0", + "0x98bcad38a1a94be3866c9d87e811e547fe33dd80c6f2176fe024ad550b9090", + "0x15fc3f2996a740deed181ceb9631ab6c546686707b024102a190759806ad46e", + "0x3e541896aa9b9130a72dc3eb093cae9289ec3be07dee8a8d5b9e571bc1f71c6", + "0x35448bc088c3a4485029bb4d2378b76f535f0302c7f3509ea17daeaeeb1e3a3", + "0x37a5fc2e601efdb2e85df52d91d2dae963e63eaabeab6b2184460ad25a00f2", + "0x223a83099e5edb29230e1cfd796cc57ce903e56ba7139eaed8d8349a81ca007", + "0x25aaa7227de9c717e2b86fab2ab1e3d8ee1a9fd1bcc5f636024c170fab865de", + "0x80000000000000070000000000000000000000000000000c", + "0x566a72c78d3c6621a5923e72ad255532a593e418cdab28b16b485bfd0d6c5e", + "0x5e", + "0x5f", + "0x60", + "0x61", + "0x62", + "0x63", + "0x64", + "0x65", + "0x66", + "0x67", + "0x68", + "0x6e", + "0x7a", + "0x800000000000000700000000000000000000000000000006", + "0x7d4d99e9ed8d285b5c61b493cedb63976bc3d9da867933d829f49ce838b5e7", + "0x6a", + "0x6b", + "0x753634", + "0x3808c701a5d13e100ab11b6c02f91f752ecae7e420d21b56c90ec0a475cc7e5", + "0x6d", + "0x2ca39cde64b91db1514d78c135ee79d71b3b57fffee52f1a3ef96618a34d8c8", + "0x6f", + "0x90d0203c41ad646d024845257a6eceb2f8b59b29ce7420dd518053d2edeedc", + "0x53746f7261676541646472657373", + "0xd2796e631062a6e7753698c5a7e289cd7bfa0c5bad46cd79c9a48fbab165aa", + "0x800000000000000f00000000000000000000000000000003", + "0x73", + "0x11210600628e948dc4cbd7a4c1a072850b384b77f05ac8982539ffdb74d676b", + "0x74", + "0x79", + "0x76", + "0x1597b831feeb60c71f259624b79cf66995ea4f7e383403583674ab9c33b9cec", + "0x77", + "0x3342418ef16b3e2799b906b1e4e89dbb9b111332dd44f72458ce44f9895b508", + "0x80000000000000070000000000000000000000000000000e", + "0x348a62b7a38c0673e61e888d83a3ac1bf334ee7361a8514593d3d9532ed8b39", + "0x78", + "0xa36a0a15af8cf1727a3a4fd9137671f23256b1f42299af56605a6910c522ce", + "0x7b", + "0x249125c42ab4a3dd2cca39221975297c741616320e73cf9c1c38606846766fa", + "0x7d", + "0x2219c07543986c5816cf8bd258df534e58f0c680e29dee0626e9be2a8854c6a", + "0x7e", + "0x1834d9f21285dab3ceae2a1d7c63c33d50a37dc56a931cf4fd0155cce48b722", + "0x80", + "0x2218e77a9d79bf2e592d48c40da370b545e224269ca2374c6281c9f50438541", + "0x4f", + "0x8d223e2f861f40c8e59a552d286b25ad43d4944c8215cd83f2af9dc8e75813", + "0x7da71e1dc546b96d9fd53438ce53f427347947c6c30c6495690af26972951f", + "0x84", + "0x172b2d029d59f97d93dd24b7cc98c01ca8efd7bf422afd18e9041d6a1a5c170", + "0x87", + "0x30f87c80a9ff91f3ba0997da70c24279680d81f2429f998f2964b1a555ebb1a", + "0x88", + "0x101dc0399934cc08fa0d6f6f2daead4e4a38cabeea1c743e1fc28d2d6e58e99", + "0x303117fb6f52227932d33a0574f22f70e3772c669c8fc05beadcb42e937ab71", + "0x8b", + "0x944a38f602dab9d32eb7dff5d1e279b127a3fcd64c78c5598d46d55a12a8c5", + "0x8c", + "0x3ab802bcce3a9ca953b0e1f31a5b29eb27a9b727c891e24300e1b5cc57387ba", + "0x8e", + "0xeafea52cfe71ec7c04decc186b7ba777db00e3392a885fbc3cefa21dc94638", + "0x91", + "0x525df73114b9ba6aedae0cfaac67628b09a84fea935dd481de14e22c9049da", + "0x92", + "0x242ab892b168865613d6bf48e23e6f2bf6bd4155b5adb58517a5ceeef69ebb", + "0x1f7c3c6dd5c14e521341ad5548817e5d1b9064f53c07f40114e072754c4f3f9", + "0x96", + "0x1203c3503955628887ebd724e5b8433579aa40dae9f37b31bfcf22e83dd73f0", + "0x97", + "0x9a", + "0x3ae40d407f8074730e48241717c3dd78b7128d346cf81094e31806a3a5bdf", + "0x9b", + "0x9d", + "0x16538afa8d67796a3f3ad75502c66231f14f82fce99a967cfaea2898dafbb", + "0x9f", + "0x2605bf00882f2fb47fd8f563bd0d1ba133e374a6860ea821465e1c5547e6f85", + "0xa0", + "0x30e3eb8f25604d564c2a8ee4a19405da626c3280586a18d89a2eafc5c9e86ce", + "0xa2", + "0x254bc03a4cb72e461fc4d3c101146f4423544989f203597f8044f96a19d2ea4", + "0xa3", + "0x3c93a24cd28b2b55d07633b11b14589ee9e0ec6c77fdf60576a04b17b045b26", + "0xa6", + "0x216ddce31c4b83af240278b16337bc80e15f78e1da60146aa3866fae1e8d9b1", + "0xa7", + "0x33cd6920cb494447f7ccaf0dbf3afce50039f3b0eb2a0369b285e06e8a31d7d", + "0xa9", + "0x27d6228f579b54e8a8059dc6c6a78c72c7e94e752c12c80bcba98e53610bcd2", + "0xab", + "0x10203be321c62a7bd4c060d69539c1fbe065baa9e253c74d2cc48be163e259", + "0xad", + "0x3e1934b18d91949ab9afdbdd1866a30ccca06c2b1e6581582c6b27f8b4f6555", + "0xb0", + "0x2975894f46cb99cad1bc7b4a8dac743f915530add47fff44edfb2fc60b6fced", + "0xb1", + "0x32ae48d6764693e076d982989640a356d60f77ede38bc686485a133d5845fda", + "0x19b9ae4ba181a54f9e7af894a81b44a60aea4c9803939708d6cc212759ee94c", + "0x42697477697365", + "0xb7", + "0x506f736569646f6e", + "0xb9", + "0x1285071ce26920dc861d902176f38b138552fe3ec227c3561fcaff97a2dd005", + "0xbb", + "0x119c26188880fdcee8029867a41d2495e669cebdd4311df3065292f4b52505c", + "0xbc", + "0x3b9ddf97bd58cc7301a2107c3eabad82196f38221c880cd3645d07c3aac1422", + "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", + "0x800000000000000f00000000000000000000000000000002", + "0xcc5e86243f861d2d64b08c35db21013e773ac5cf10097946fe0011304886d5", + "0xc2", + "0x17b6ecc31946835b0d9d92c2dd7a9c14f29af0371571ae74a1b228828b2242", + "0xc4", + "0x34f9bd7c6cb2dd4263175964ad75f1ff1461ddc332fbfb274e0fb2a5d7ab968", + "0xc5", + "0x800000000000000f00000000000000000000000000000008", + "0x3e74e36f022d24067823b338fa5223c9d6e4fb2d36a7b76deca37686422a908", + "0xc8", + "0x1a4b9d6a46239fb7607a1f85f5201d6c8446b5d0cd0c227a2e70e314c1a4176", + "0xc9", + "0x61e8b04c2d3e4e254d754b346ee4e01b07a0ea7bed1e8486d11b0361dda457", + "0xcb", + "0x387efa6e0840a32fa82f7c5edb3a29dbe8ee992b95bc65bef574a0617a4853", + "0xcd", + "0x224a57ba2504f0018c4fd92c0f0e6ef13a37bf8d3d6479b8faa16fc36f624d2", + "0xcf", + "0x11771f2d3e7dc3ed5afe7eae405dfd127619490dec57ceaa021ac8bc2b9b315", + "0xa853c166304d20fb0711becf2cbdf482dee3cac4e9717d040b7a7ab1df7eec", + "0xd2", + "0x3d37ad6eafb32512d2dd95a2917f6bf14858de22c27a1114392429f2e5c15d7", + "0x1fbbaba2608edc21a853642c7ca4b44f476d497f59dbacfc98e12f81eac5dd3", + "0xd5", + "0x1d49f7a4b277bf7b55a2664ce8cef5d6922b5ffb806b89644b9e0cdbbcac378", + "0xd7", + "0x13fdd7105045794a99550ae1c4ac13faa62610dfab62c16422bfcf5803baa6e", + "0xd8", + "0x74584e9f10ffb1a40aa5a3582e203f6758defc4a497d1a2d5a89f274a320e9", + "0xdb", + "0x4275696c74696e436f737473", + "0x53797374656d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0xdd", + "0x4761734275696c74696e", + "0x52616e6765436865636b", + "0xdf", + "0x411", + "0x616c6c6f635f6c6f63616c", + "0x66696e616c697a655f6c6f63616c73", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x73746f72655f74656d70", + "0x66756e6374696f6e5f63616c6c", + "0x3", + "0xe2", + "0x656e756d5f6d61746368", + "0x7374727563745f6465636f6e737472756374", + "0x61727261795f6c656e", + "0x736e617073686f745f74616b65", + "0x64726f70", + "0x7533325f636f6e7374", + "0x72656e616d65", + "0x7533325f6571", + "0xe3", + "0x61727261795f6e6577", + "0x66656c743235325f636f6e7374", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x61727261795f617070656e64", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f696e6974", + "0xe0", + "0xe1", + "0x6765745f6275696c74696e5f636f737473", + "0xde", + "0x77697468647261775f6761735f616c6c", + "0x19", + "0x73746f72655f6c6f63616c", + "0x1a", + "0xdc", + "0x4f7574206f6620676173", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x1b", + "0xd9", + "0xd6", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0xda", + "0x1d", + "0xd4", + "0x1e", + "0xd3", + "0x1f", + "0x25", + "0xd1", + "0xd0", + "0x29", + "0xce", + "0x2a", + "0xcc", + "0x2c", + "0xca", + "0x7533325f746f5f66656c74323532", + "0xc6", + "0x2e", + "0xc3", + "0xc7", + "0x656e61626c655f61705f747261636b696e67", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0xbf", + "0x6a756d70", + "0x756e626f78", + "0x2f", + "0xbe", + "0x64697361626c655f61705f747261636b696e67", + "0xbd", + "0x31", + "0x4661696c656420746f20646573657269616c697a6520706172616d202335", + "0xc1", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", + "0xc0", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x33", + "0xb5", + "0xb8", + "0xba", + "0xb6", + "0x35", + "0xb3", + "0xb2", + "0x37", + "0xb4", + "0x3a", + "0xaf", + "0x3d", + "0x647570", + "0xae", + "0x66656c743235325f616464", + "0x3f", + "0xac", + "0x41", + "0x6e6f74206f776e6572", + "0xff", + "0x7533325f6f766572666c6f77696e675f737562", + "0x6d6574616461746120746f6f206c6f6e67", + "0x43", + "0xaa", + "0x44", + "0xa8", + "0x21adb5788e32c84f69a1863d85ef9394b7bf761a0ce1190f826984e5075c371", + "0xa5", + "0x46", + "0x47", + "0xa4", + "0x6e6f74206f776e6572206f7220777269746572", + "0xa1", + "0x4c", + "0x636c6173735f686173685f7472795f66726f6d5f66656c74323532", + "0x361458367e696363fbcc70777d07ebbd2394e89fd0adcaf147faccd1d294d60", + "0x4e", + "0x9c", + "0x636c6173735f686173685f636f6e7374", + "0x636c6173735f686173685f746f5f66656c74323532", + "0x66656c743235325f737562", + "0x66656c743235325f69735f7a65726f", + "0x99", + "0x6f6e6c79206f776e65722063616e20757064617465", + "0x98", + "0x51", + "0x9e", + "0x6465706c6f795f73797363616c6c", + "0x94", + "0x53", + "0x93", + "0x90", + "0x54", + "0x636f6e74726163745f616464726573735f746f5f66656c74323532", + "0x95", + "0x56", + "0x57", + "0x58", + "0x8f", + "0x5a", + "0x8d", + "0x656d69745f6576656e745f73797363616c6c", + "0x8a", + "0x5b", + "0x75385f7472795f66726f6d5f66656c74323532", + "0x89", + "0x5d", + "0x85", + "0x75385f636f6e7374", + "0x86", + "0x7533325f7472795f66726f6d5f66656c74323532", + "0x83", + "0x517565726965732062792076616c756573206e6f7420696d706c", + "0x82", + "0x6f6e6c79206f776e65722063616e20736574206578656375746f72", + "0x81", + "0x69", + "0x7f", + "0x626f6f6c5f6e6f745f696d706c", + "0x696e76616c696420636c6173735f68617368", + "0x7c", + "0x6f6e6c79206f776e65722063616e2075706772616465", + "0x7265706c6163655f636c6173735f73797363616c6c", + "0x75", + "0x70", + "0x71", + "0x73746f726167655f616464726573735f66726f6d5f62617365", + "0x73746f726167655f726561645f73797363616c6c", + "0x72", + "0x73746f726167655f77726974655f73797363616c6c", + "0x626f6f6c5f746f5f66656c74323532", + "0x61727261795f676574", + "0x496e646578206f7574206f6620626f756e6473", + "0x4e6f6e20436c61737348617368", + "0x73746f726167655f626173655f616464726573735f636f6e7374", + "0x36d13f3f96a254c70c8330b71d2bd1ddec5e51f41977e0a2581409a42320efc", + "0xf2f7c15cbe06c8d94597cd91fd7f3369eae842359235712def5584f8d270cd", + "0x63616c6c5f636f6e74726163745f73797363616c6c", + "0x6e6f7420777269746572", + "0x2b1577440dd7bedf920cb6de2f9fc6bf7ba98c78c85a3fa1f8311aac95e1759", + "0x53746f7265553332202d206e6f6e20753332", + "0x7533325f6f766572666c6f77696e675f616464", + "0x7533325f616464204f766572666c6f77", + "0x646f6a6f5f73746f72616765", + "0x1e1a4f440a09e62552e8b84a50e697fb4320c97ca40a405efbfac1d14b300c2", + "0x526573756c743a3a756e77726170206661696c65642e", + "0x1cdc902ca80aea4fa41f94d35654158d368cd858e75e9f2426d204944eef764", + "0x706564657273656e", + "0xad292db4ff05a993c318438c1b6c8a8303266af2da151aa28ccece6726f1f1", + "0x6765745f657865637574696f6e5f696e666f5f76325f73797363616c6c", + "0x20f4a9eb90c382f623710b9c287e5c670ffc7e969860c063aa3ea54cf7325e7", + "0x26b160f10156dea0639bec90696772c640b9706a47f5b8c52ea1abe5858b34d", + "0x8248d60b6c95dac1563fa392e8dfc0cb968be73d80faedfe9a90e66811b45f", + "0x2399aa6e1326b07d2fd6c8c467f11b0fb5ed23db5f8723a777dca0f37d48bcf", + "0x290118457a640990dbcdeb696bd7f53f1d7d71d19b7d566efd42da398c908d3", + "0x2474f33346a1e5cfe0f6bedbc1facc0224efeb1be69ea9160b8dd8886a100dd", + "0x1a2f334228cee715f1f0f54053bb6b5eac54fa336e0bc1aacf7516decb0471d", + "0x669efaa2192f54841ccb92b165625cca30ec440cfe380667975cb01226a100", + "0x22cf28ad915d4655dcd87526f5461f2c386e0d8ae93d31dff5725b4777cb549", + "0x1062404958dc8c1108761b486c079063d18e574094add29f4cecada8fed72d", + "0x22e066b6a70387f706dbbcab0d2a7e9090fca9489df0398d5ad334b26875acc", + "0x1cba22b2cafd524314ce673fe23829450404e65620365072db7e950762157aa", + "0x11d1dfbcd3e2040f863a35b6bab2a2134c9c4423d1eb9352c6e60807dafff85", + "0x31a75a0d711dfe3639aae96eb8f9facc2fd74df5aa611067f2511cc9fefc229", + "0x52657475726e6564206461746120746f6f2073686f7274", + "0x29c799c764f5d22f9cdca7532b4515f2506acb3d56008546d9cc1994a04373", + "0x68616465735f7065726d75746174696f6e", + "0x4e6f6e20436f6e747261637441646472657373", + "0xa", + "0x75385f746f5f66656c74323532", + "0x6d69736d61746368656420696e707574206c656e73", + "0x61727261795f706f705f66726f6e74", + "0x2679d68052ccd03a53755ca9169677965fbd93e489df62f5f40d4f03c24f7a4", + "0x646f6a6f5f696e6465785f6c656e73", + "0x646f6a6f5f696e6465785f696473", + "0x646f6a6f5f696e6465786573", + "0x757063617374", + "0xfb", + "0x646f6a6f5f696e6465785f6b65795f6c656e", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x75385f6f766572666c6f77696e675f616464", + "0x75385f616464204f766572666c6f77", + "0x646f6a6f5f696e6465785f6b6579", + "0x75385f6f766572666c6f77696e675f737562", + "0x62697477697365", + "0x753132385f636f6e7374", + "0x75385f6571", + "0x75385f737562204f766572666c6f77", + "0x75313238735f66726f6d5f66656c74323532", + "0x8000000000000110000000000000000", + "0x753132385f6f766572666c6f77696e675f737562", + "0x753132385f6571", + "0x753132385f746f5f66656c74323532", + "0x100000000000000000000000000000000", + "0x66656c743235325f6d756c", + "0x753235365f737562204f766572666c6f77", + "0x753235365f6d756c204f766572666c6f77", + "0x753235365f736166655f6469766d6f64", + "0x16", + "0x15", + "0x4469766973696f6e2062792030", + "0x14", + "0x75385f736166655f6469766d6f64", + "0x11", + "0xe", + "0x753132385f6d756c5f67756172616e7465655f766572696679", + "0x753132385f67756172616e7465655f6d756c", + "0x753132385f6f766572666c6f77696e675f616464", + "0x753235362069732030", + "0x75382069732030", + "0x753235365f69735f7a65726f", + "0x75385f69735f7a65726f", + "0x39f1", + "0xffffffffffffffff", + "0x131", + "0x120", + "0x117", + "0x106", + "0xf6", + "0xee", + "0x1cc", + "0x1bc", + "0x1ab", + "0x168", + "0x19b", + "0x193", + "0x25e", + "0x24e", + "0x23d", + "0x202", + "0x22d", + "0x225", + "0x2f0", + "0x2e0", + "0x2cf", + "0x294", + "0x2bf", + "0x2b7", + "0x38b", + "0x37b", + "0x36a", + "0x327", + "0x35a", + "0x352", + "0x41e", + "0x40e", + "0x3fd", + "0x3c2", + "0x3ed", + "0x3e5", + "0x4b1", + "0x4a1", + "0x490", + "0x455", + "0x480", + "0x478", + "0x52b", + "0x51b", + "0x4e2", + "0x50c", + "0x504", + "0x5ad", + "0x59d", + "0x55c", + "0x58e", + "0x586", + "0x647", + "0x637", + "0x626", + "0x5e4", + "0x616", + "0x60e", + "0x6e1", + "0x6d1", + "0x6c0", + "0x67e", + "0x6b0", + "0x6a8", + "0x745", + "0x70c", + "0x738", + "0x731", + "0x7ee", + "0x7e6", + "0x7d6", + "0x7ce", + "0x7be", + "0x785", + "0x7af", + "0x7a8", + "0x94d", + "0x937", + "0x929", + "0x913", + "0x81d", + "0x822", + "0x8fb", + "0x8f2", + "0x8e4", + "0x8ce", + "0x8c0", + "0x8aa", + "0x861", + "0x895", + "0x88b", + "0x903", + "0xa38", + "0xa24", + "0xa18", + "0xa04", + "0x9f8", + "0x9e4", + "0x99f", + "0x9d1", + "0x9c7", + "0xbd7", + "0xbbf", + "0xbaf", + "0xb97", + "0xa6e", + "0xa73", + "0xb7d", + "0xb71", + "0xa86", + "0xa8b", + "0xb57", + "0xb4b", + "0xb3b", + "0xb23", + "0xac2", + "0xb0c", + "0xb03", + "0xafa", + "0xb62", + "0xb88", + "0xd59", + "0xd41", + "0xd29", + "0xd19", + "0xd01", + "0xc16", + "0xc1b", + "0xce7", + "0xcdb", + "0xccb", + "0xcb3", + "0xc52", + "0xc9c", + "0xc93", + "0xc8a", + "0xcf2", + "0xdfb", + "0xde9", + "0xd97", + "0xdd8", + "0xdd0", + "0xdc8", + "0xe77", + "0xe67", + "0xe2e", + "0xe58", + "0xe50", + "0xedd", + "0xea2", + "0xed0", + "0xec9", + "0xf42", + "0xf07", + "0xf35", + "0xf2e", + "0xfbb", + "0xfab", + "0xf72", + "0xf9c", + "0xf94", + "0x104e", + "0x103e", + "0x102d", + "0xff2", + "0x101d", + "0x1015", + "0x1064", + "0x1069", + "0x1073", + "0x10b2", + "0x10aa", + "0x10d7", + "0x10e5", + "0x10ea", + "0x1114", + "0x110e", + "0x1106", + "0x11d1", + "0x11c5", + "0x1147", + "0xe5", + "0xe6", + "0xe7", + "0xe8", + "0xe9", + "0x1165", + "0xea", + "0xeb", + "0xec", + "0x11b5", + "0xed", + "0xef", + "0xf0", + "0x11ab", + "0xf1", + "0xf2", + "0xf3", + "0x119d", + "0xf4", + "0xf5", + "0x11f0", + "0xf7", + "0x11e9", + "0xf8", + "0xf9", + "0xfa", + "0xfc", + "0xfd", + "0xfe", + "0x120f", + "0x100", + "0x101", + "0x102", + "0x103", + "0x121e", + "0x104", + "0x1222", + "0x105", + "0x12cf", + "0x107", + "0x12c2", + "0x1261", + "0x1255", + "0x108", + "0x126c", + "0x109", + "0x1280", + "0x10a", + "0x10b", + "0x12b2", + "0x10c", + "0x10d", + "0x10e", + "0x10f", + "0x12aa", + "0x1381", + "0x1374", + "0x1313", + "0x1307", + "0x131e", + "0x1332", + "0x110", + "0x1364", + "0x135c", + "0x111", + "0x13a6", + "0x1454", + "0x1447", + "0x13e6", + "0x13da", + "0x13f1", + "0x1405", + "0x112", + "0x113", + "0x114", + "0x1437", + "0x115", + "0x116", + "0x118", + "0x142f", + "0x1538", + "0x152b", + "0x149c", + "0x148e", + "0x14a6", + "0x14c9", + "0x14bd", + "0x14d5", + "0x14e9", + "0x151b", + "0x1513", + "0x1556", + "0x119", + "0x154f", + "0x11a", + "0x11b", + "0x11c", + "0x11d", + "0x1678", + "0x11e", + "0x11f", + "0x121", + "0x166c", + "0x122", + "0x123", + "0x124", + "0x1660", + "0x125", + "0x126", + "0x127", + "0x128", + "0x164c", + "0x129", + "0x12a", + "0x12b", + "0x12c", + "0x15d2", + "0x15bf", + "0x1600", + "0x12d", + "0x163e", + "0x15f8", + "0x12e", + "0x12f", + "0x130", + "0x162c", + "0x132", + "0x133", + "0x134", + "0x1624", + "0x135", + "0x136", + "0x169c", + "0x137", + "0x138", + "0x139", + "0x13a", + "0x13b", + "0x13c", + "0x13d", + "0x1767", + "0x13e", + "0x16cd", + "0x13f", + "0x140", + "0x141", + "0x16d2", + "0x142", + "0x143", + "0x144", + "0x1753", + "0x145", + "0x146", + "0x147", + "0x148", + "0x149", + "0x14a", + "0x173f", + "0x14b", + "0x172a", + "0x1719", + "0x14c", + "0x14d", + "0x14e", + "0x1710", + "0x14f", + "0x150", + "0x151", + "0x152", + "0x153", + "0x154", + "0x17d8", + "0x155", + "0x17cd", + "0x17c2", + "0x156", + "0x157", + "0x158", + "0x17b9", + "0x159", + "0x15a", + "0x15b", + "0x15c", + "0x15d", + "0x15e", + "0x15f", + "0x1825", + "0x160", + "0x161", + "0x162", + "0x1816", + "0x163", + "0x164", + "0x1808", + "0x165", + "0x166", + "0x167", + "0x169", + "0x183b", + "0x1840", + "0x185c", + "0x1856", + "0x16a", + "0x16b", + "0x16c", + "0x16d", + "0x16e", + "0x1895", + "0x16f", + "0x187f", + "0x170", + "0x171", + "0x1884", + "0x172", + "0x173", + "0x188f", + "0x174", + "0x175", + "0x176", + "0x177", + "0x178", + "0x18a3", + "0x179", + "0x17a", + "0x18a8", + "0x17b", + "0x18b1", + "0x18b6", + "0x18e0", + "0x17c", + "0x17d", + "0x17e", + "0x17f", + "0x18da", + "0x180", + "0x181", + "0x18d2", + "0x182", + "0x183", + "0x184", + "0x185", + "0x186", + "0x187", + "0x188", + "0x189", + "0x18a", + "0x1972", + "0x1960", + "0x18b", + "0x194e", + "0x18c", + "0x18d", + "0x193f", + "0x18e", + "0x18f", + "0x190", + "0x1935", + "0x191", + "0x1a8d", + "0x1a79", + "0x1a61", + "0x192", + "0x194", + "0x195", + "0x1a49", + "0x196", + "0x1a31", + "0x197", + "0x198", + "0x1a1c", + "0x199", + "0x1a09", + "0x19a", + "0x19c", + "0x19ff", + "0x19d", + "0x19e", + "0x19f", + "0x1aa8", + "0x1a0", + "0x1a1", + "0x1aad", + "0x1a2", + "0x1ad8", + "0x1a3", + "0x1acf", + "0x1b18", + "0x1afa", + "0x1af5", + "0x1b08", + "0x1a4", + "0x1a5", + "0x1b11", + "0x1a6", + "0x1a7", + "0x1b0c", + "0x1a8", + "0x1b3d", + "0x1a9", + "0x1aa", + "0x1ac", + "0x1ad", + "0x1ae", + "0x1b56", + "0x1af", + "0x1b0", + "0x1b1", + "0x1b7e", + "0x1b2", + "0x1b3", + "0x1b78", + "0x1b4", + "0x1b5", + "0x1b9b", + "0x1c27", + "0x1c1d", + "0x1bcb", + "0x1b6", + "0x1b7", + "0x1b8", + "0x1b9", + "0x1c0d", + "0x1ba", + "0x1bb", + "0x1bd", + "0x1bfd", + "0x1be", + "0x1bf", + "0x1c0", + "0x1c1", + "0x1c2", + "0x1c3", + "0x1bf5", + "0x1c4", + "0x1c49", + "0x1c5", + "0x1c6", + "0x1c7", + "0x1c8", + "0x1c65", + "0x1c86", + "0x1c8b", + "0x1c9", + "0x1ca0", + "0x1ca", + "0x1cb", + "0x1d1b", + "0x1cd", + "0x1ce", + "0x1cf", + "0x1d0", + "0x1d1", + "0x1d11", + "0x1cd5", + "0x1d2", + "0x1d3", + "0x1ce1", + "0x1ce6", + "0x1d4", + "0x1d06", + "0x1d5", + "0x1d6", + "0x1d7", + "0x1cfe", + "0x1dc4", + "0x1d8", + "0x1db3", + "0x1d9", + "0x1da", + "0x1da3", + "0x1d94", + "0x1db", + "0x1d84", + "0x1dc", + "0x1dd", + "0x1de", + "0x1df", + "0x1d7c", + "0x1e0", + "0x1e1", + "0x1e2", + "0x1e3", + "0x1e4", + "0x1e5", + "0x1e6", + "0x1dde", + "0x1e7", + "0x1e8", + "0x1de3", + "0x1e9", + "0x1ea", + "0x1def", + "0x1eb", + "0x1ec", + "0x1ed", + "0x1ee", + "0x1e4c", + "0x1e0e", + "0x1ef", + "0x1f0", + "0x1f1", + "0x1e40", + "0x1e38", + "0x1f2", + "0x1e9b", + "0x1e6c", + "0x1e71", + "0x1e8d", + "0x1e87", + "0x1e94", + "0x1ee2", + "0x1eba", + "0x1f3", + "0x1ed8", + "0x1ed2", + "0x1f4", + "0x1f5", + "0x1f03", + "0x1f6", + "0x1f7", + "0x1f8", + "0x1f9", + "0x1fa", + "0x1fb", + "0x1fc", + "0x1f19", + "0x1f1e", + "0x1f2a", + "0x1fd", + "0x1fe", + "0x1ff", + "0x200", + "0x201", + "0x203", + "0x204", + "0x205", + "0x206", + "0x207", + "0x1f6f", + "0x208", + "0x1f55", + "0x1f5a", + "0x1f66", + "0x1fcf", + "0x1f85", + "0x1f8a", + "0x1fc3", + "0x1fb9", + "0x1fb1", + "0x209", + "0x20a", + "0x20b", + "0x20c", + "0x20d", + "0x200c", + "0x2001", + "0x2006", + "0x20e", + "0x20f", + "0x2011", + "0x210", + "0x211", + "0x201d", + "0x212", + "0x213", + "0x203b", + "0x2040", + "0x204c", + "0x214", + "0x215", + "0x216", + "0x217", + "0x218", + "0x2091", + "0x2077", + "0x207c", + "0x2088", + "0x219", + "0x20c5", + "0x20ba", + "0x20bf", + "0x20ca", + "0x20d6", + "0x21a", + "0x20ef", + "0x20f4", + "0x2100", + "0x21b", + "0x21c", + "0x21d", + "0x21e", + "0x21f", + "0x2145", + "0x212b", + "0x2130", + "0x213c", + "0x2175", + "0x220", + "0x216e", + "0x221", + "0x2186", + "0x222", + "0x223", + "0x224", + "0x226", + "0x227", + "0x21b6", + "0x228", + "0x21a7", + "0x229", + "0x22a", + "0x21bc", + "0x22b", + "0x22c", + "0x21c8", + "0x21e1", + "0x21e6", + "0x21f2", + "0x22e", + "0x22f", + "0x230", + "0x231", + "0x232", + "0x2237", + "0x221d", + "0x2222", + "0x222e", + "0x233", + "0x234", + "0x2262", + "0x2254", + "0x2268", + "0x2273", + "0x235", + "0x2280", + "0x236", + "0x237", + "0x238", + "0x239", + "0x23a", + "0x23b", + "0x23c", + "0x229b", + "0x23e", + "0x22a0", + "0x23f", + "0x240", + "0x22ab", + "0x241", + "0x242", + "0x22ed", + "0x22d3", + "0x22d8", + "0x22e4", + "0x2399", + "0x2388", + "0x237e", + "0x2375", + "0x236d", + "0x2364", + "0x235c", + "0x2355", + "0x243", + "0x2394", + "0x2390", + "0x244", + "0x245", + "0x246", + "0x247", + "0x248", + "0x23df", + "0x23c5", + "0x23ca", + "0x23d6", + "0x249", + "0x240a", + "0x23fc", + "0x24a", + "0x24b", + "0x2410", + "0x24c", + "0x24d", + "0x24f", + "0x250", + "0x241b", + "0x251", + "0x252", + "0x253", + "0x2428", + "0x254", + "0x255", + "0x242c", + "0x256", + "0x257", + "0x258", + "0x2437", + "0x244c", + "0x2451", + "0x245b", + "0x259", + "0x25a", + "0x25b", + "0x25c", + "0x25d", + "0x2468", + "0x24c6", + "0x247f", + "0x25f", + "0x260", + "0x261", + "0x2489", + "0x248e", + "0x24b8", + "0x24b2", + "0x262", + "0x24ac", + "0x263", + "0x264", + "0x24bf", + "0x265", + "0x266", + "0x267", + "0x268", + "0x269", + "0x24ed", + "0x26a", + "0x26b", + "0x26c", + "0x2517", + "0x26d", + "0x255c", + "0x2542", + "0x2547", + "0x2553", + "0x25a7", + "0x26e", + "0x26f", + "0x259e", + "0x2596", + "0x2590", + "0x270", + "0x271", + "0x272", + "0x273", + "0x274", + "0x25cc", + "0x275", + "0x2610", + "0x25f6", + "0x25fb", + "0x2607", + "0x276", + "0x263a", + "0x277", + "0x278", + "0x2679", + "0x279", + "0x27a", + "0x266f", + "0x27b", + "0x27c", + "0x27d", + "0x27e", + "0x27f", + "0x280", + "0x281", + "0x26a0", + "0x282", + "0x26e8", + "0x283", + "0x26df", + "0x284", + "0x285", + "0x26d7", + "0x286", + "0x26fd", + "0x287", + "0x2705", + "0x288", + "0x289", + "0x28a", + "0x28b", + "0x272c", + "0x28c", + "0x28d", + "0x28e", + "0x2725", + "0x28f", + "0x290", + "0x291", + "0x292", + "0x293", + "0x2747", + "0x295", + "0x296", + "0x297", + "0x298", + "0x278a", + "0x2770", + "0x2775", + "0x2781", + "0x27a4", + "0x299", + "0x29a", + "0x29b", + "0x29c", + "0x29d", + "0x29e", + "0x27b5", + "0x29f", + "0x27f5", + "0x27db", + "0x27e0", + "0x27ec", + "0x280d", + "0x2812", + "0x281c", + "0x2a0", + "0x2a1", + "0x2a2", + "0x2a3", + "0x2835", + "0x2a4", + "0x2877", + "0x285d", + "0x2862", + "0x286e", + "0x2a5", + "0x2a6", + "0x2a7", + "0x2a8", + "0x2a9", + "0x2aa", + "0x2893", + "0x2ab", + "0x28a0", + "0x2ac", + "0x2ad", + "0x28a5", + "0x2ae", + "0x2af", + "0x28af", + "0x2b0", + "0x2b1", + "0x2b2", + "0x2b3", + "0x2b4", + "0x2b5", + "0x28c8", + "0x28d6", + "0x28e4", + "0x28f2", + "0x290b", + "0x2919", + "0x2932", + "0x294b", + "0x2959", + "0x2967", + "0x2b6", + "0x2974", + "0x2b8", + "0x2b9", + "0x2ba", + "0x2bb", + "0x2bc", + "0x2bd", + "0x2be", + "0x2905", + "0x2c0", + "0x2c1", + "0x2c2", + "0x2c3", + "0x2c4", + "0x2c5", + "0x292c", + "0x2c6", + "0x2c7", + "0x2945", + "0x2c8", + "0x2c9", + "0x2ca", + "0x2cb", + "0x2cc", + "0x2cd", + "0x2ce", + "0x2d0", + "0x2d1", + "0x2d2", + "0x2995", + "0x2d3", + "0x2d4", + "0x2d5", + "0x2a18", + "0x2d6", + "0x29df", + "0x29e4", + "0x2a10", + "0x2a09", + "0x29fb", + "0x2d7", + "0x2d8", + "0x2d9", + "0x2a35", + "0x2a3a", + "0x2da", + "0x2a41", + "0x2db", + "0x2dc", + "0x2a50", + "0x2dd", + "0x2de", + "0x2df", + "0x2a62", + "0x2a6f", + "0x2b32", + "0x2e1", + "0x2a87", + "0x2a8c", + "0x2b09", + "0x2a9a", + "0x2a9f", + "0x2adf", + "0x2e2", + "0x2e3", + "0x2acc", + "0x2ac5", + "0x2e4", + "0x2e5", + "0x2e6", + "0x2e7", + "0x2e8", + "0x2e9", + "0x2ea", + "0x2af7", + "0x2b01", + "0x2b20", + "0x2b2a", + "0x2eb", + "0x2ec", + "0x2b8b", + "0x2ed", + "0x2ee", + "0x2ef", + "0x2b7f", + "0x2f1", + "0x2f2", + "0x2b76", + "0x2f3", + "0x2f4", + "0x2f5", + "0x2f6", + "0x2f7", + "0x2c76", + "0x2bc4", + "0x2f8", + "0x2f9", + "0x2c67", + "0x2fa", + "0x2c59", + "0x2fb", + "0x2c4c", + "0x2c40", + "0x2fc", + "0x2c35", + "0x2c2d", + "0x2fd", + "0x2cd6", + "0x2fe", + "0x2ccc", + "0x2ff", + "0x300", + "0x2cc3", + "0x301", + "0x302", + "0x303", + "0x304", + "0x2cff", + "0x305", + "0x306", + "0x307", + "0x308", + "0x309", + "0x30a", + "0x30b", + "0x2d54", + "0x30c", + "0x2d18", + "0x30d", + "0x30e", + "0x30f", + "0x2d1d", + "0x310", + "0x311", + "0x312", + "0x2d46", + "0x313", + "0x2d3f", + "0x314", + "0x2d39", + "0x2d4d", + "0x315", + "0x316", + "0x317", + "0x2d99", + "0x318", + "0x2d91", + "0x319", + "0x31a", + "0x31b", + "0x31c", + "0x2e09", + "0x2dfe", + "0x2df3", + "0x31d", + "0x2deb", + "0x2e2f", + "0x2e42", + "0x31e", + "0x2e3a", + "0x2e6e", + "0x31f", + "0x2e60", + "0x320", + "0x321", + "0x322", + "0x323", + "0x324", + "0x325", + "0x326", + "0x2e7d", + "0x2e8e", + "0x328", + "0x2e9e", + "0x329", + "0x32a", + "0x32b", + "0x2eb3", + "0x32c", + "0x32d", + "0x32e", + "0x32f", + "0x330", + "0x331", + "0x332", + "0x333", + "0x334", + "0x2f19", + "0x335", + "0x336", + "0x337", + "0x338", + "0x2f76", + "0x339", + "0x33a", + "0x2f6f", + "0x33b", + "0x33c", + "0x33d", + "0x2f98", + "0x33e", + "0x33f", + "0x340", + "0x341", + "0x342", + "0x343", + "0x3006", + "0x344", + "0x345", + "0x346", + "0x347", + "0x348", + "0x3020", + "0x349", + "0x34a", + "0x34b", + "0x3084", + "0x34c", + "0x3035", + "0x303a", + "0x3077", + "0x34d", + "0x34e", + "0x3046", + "0x304a", + "0x34f", + "0x350", + "0x351", + "0x306c", + "0x3065", + "0x353", + "0x354", + "0x355", + "0x356", + "0x30c8", + "0x30b9", + "0x30be", + "0x357", + "0x3109", + "0x30ee", + "0x30f3", + "0x3100", + "0x358", + "0x313d", + "0x312f", + "0x3133", + "0x359", + "0x31c0", + "0x31b4", + "0x316e", + "0x3173", + "0x31a7", + "0x319c", + "0x3195", + "0x35b", + "0x35c", + "0x35d", + "0x31ea", + "0x35e", + "0x326a", + "0x3201", + "0x3206", + "0x3259", + "0x324b", + "0x35f", + "0x3242", + "0x360", + "0x361", + "0x362", + "0x363", + "0x364", + "0x365", + "0x32e6", + "0x32a3", + "0x366", + "0x32d8", + "0x32d0", + "0x3350", + "0x3313", + "0x3343", + "0x333b", + "0x33ba", + "0x337b", + "0x33ad", + "0x33a5", + "0x33d3", + "0x33d8", + "0x367", + "0x3459", + "0x33ea", + "0x33ef", + "0x344d", + "0x368", + "0x33fc", + "0x369", + "0x36b", + "0x3401", + "0x36c", + "0x36d", + "0x36e", + "0x3438", + "0x36f", + "0x370", + "0x371", + "0x342f", + "0x372", + "0x3428", + "0x373", + "0x374", + "0x375", + "0x376", + "0x377", + "0x378", + "0x379", + "0x37a", + "0x3473", + "0x37c", + "0x3477", + "0x37d", + "0x37e", + "0x37f", + "0x3482", + "0x380", + "0x381", + "0x382", + "0x383", + "0x384", + "0x34e9", + "0x3497", + "0x349c", + "0x385", + "0x34de", + "0x386", + "0x387", + "0x34d5", + "0x388", + "0x34cb", + "0x34c4", + "0x389", + "0x38a", + "0x38c", + "0x38d", + "0x38e", + "0x38f", + "0x390", + "0x357c", + "0x391", + "0x392", + "0x356e", + "0x393", + "0x394", + "0x395", + "0x396", + "0x397", + "0x3563", + "0x398", + "0x399", + "0x39a", + "0x39b", + "0x39c", + "0x3552", + "0x3549", + "0x39d", + "0x39e", + "0x39f", + "0x3a0", + "0x3a1", + "0x3a2", + "0x3a3", + "0x3590", + "0x3a4", + "0x36ab", + "0x3625", + "0x3a5", + "0x3a6", + "0x3618", + "0x3a7", + "0x360b", + "0x3a8", + "0x3a9", + "0x35ff", + "0x3aa", + "0x35f4", + "0x3ab", + "0x3ac", + "0x3ad", + "0x3ae", + "0x3af", + "0x3b0", + "0x3632", + "0x3637", + "0x369c", + "0x3b1", + "0x3b2", + "0x368e", + "0x3683", + "0x3678", + "0x36c1", + "0x36c5", + "0x3b3", + "0x36d0", + "0x3b4", + "0x36de", + "0x36e2", + "0x3b5", + "0x3b6", + "0x3702", + "0x3b7", + "0x36fc", + "0x3b8", + "0x3b9", + "0x3ba", + "0x3bb", + "0x3bc", + "0x3bd", + "0x3be", + "0x373d", + "0x3bf", + "0x3c0", + "0x3c1", + "0x371b", + "0x3733", + "0x3731", + "0x3c3", + "0x3c4", + "0x3c5", + "0x3c6", + "0x3752", + "0x3c7", + "0x377d", + "0x3c8", + "0x3777", + "0x3815", + "0x3809", + "0x3801", + "0x3c9", + "0x37f9", + "0x3ca", + "0x3cb", + "0x37f0", + "0x37e8", + "0x3cc", + "0x37e0", + "0x37cc", + "0x37da", + "0x3cd", + "0x382e", + "0x3ce", + "0x3cf", + "0x3d0", + "0x3845", + "0x3d1", + "0x3d2", + "0x384b", + "0x3d3", + "0x3d4", + "0x3d5", + "0x386e", + "0x3d6", + "0x3d7", + "0x3861", + "0x3d8", + "0x3d9", + "0x3da", + "0x3db", + "0x3dc", + "0x3dd", + "0x3de", + "0x3df", + "0x388f", + "0x3e0", + "0x3e1", + "0x3882", + "0x3e2", + "0x38b0", + "0x38a3", + "0x3e3", + "0x38c1", + "0x38c7", + "0x38d4", + "0x3e4", + "0x38da", + "0x3e6", + "0x38e2", + "0x3e7", + "0x3e8", + "0x38f6", + "0x38ec", + "0x38f4", + "0x3e9", + "0x3ea", + "0x3eb", + "0x3901", + "0x3ec", + "0x3ee", + "0x3ef", + "0x3f0", + "0x3f1", + "0x3f2", + "0x3f3", + "0x3f4", + "0x3913", + "0x3f5", + "0x3f6", + "0x3f7", + "0x3f8", + "0x3f9", + "0x3fa", + "0x3fb", + "0x3fc", + "0x3fe", + "0x3999", + "0x394e", + "0x3991", + "0x3962", + "0x3966", + "0x398d", + "0x3976", + "0x398a", + "0x3982", + "0x3988", + "0x3995", + "0x39a3", + "0x39aa", + "0x39b1", + "0x3ff", + "0x39bf", + "0x400", + "0x401", + "0x402", + "0x403", + "0x404", + "0x405", + "0x39d2", + "0x406", + "0x407", + "0x408", + "0x409", + "0x40a", + "0x40b", + "0x39e3", + "0x40c", + "0x40d", + "0x39e6", + "0x39ed", + "0x40f", + "0x410", + "0x39f0", + "0x42d", + "0x4c0", + "0x53a", + "0x5bc", + "0x656", + "0x6f0", + "0x753", + "0x7fd", + "0x962", + "0xa4b", + "0xbee", + "0xd70", + "0xe0c", + "0xe86", + "0xeeb", + "0xf50", + "0xfca", + "0x105d", + "0x107a", + "0x10bd", + "0x10dd", + "0x111e", + "0x11de", + "0x11f6", + "0x1217", + "0x1229", + "0x12db", + "0x138d", + "0x13ae", + "0x1460", + "0x1544", + "0x155c", + "0x1684", + "0x16a4", + "0x16ae", + "0x177a", + "0x1784", + "0x17e6", + "0x1833", + "0x1866", + "0x189d", + "0x18a9", + "0x18ea", + "0x1987", + "0x1aa2", + "0x1aae", + "0x1ae5", + "0x1b1d", + "0x1b5f", + "0x1b85", + "0x1ba3", + "0x1c33", + "0x1c50", + "0x1c6c", + "0x1d27", + "0x1dd0", + "0x1df7", + "0x1e5e", + "0x1ea9", + "0x1ef1", + "0x1f09", + "0x1f33", + "0x1f77", + "0x1fe0", + "0x2025", + "0x202a", + "0x2055", + "0x2099", + "0x20de", + "0x2109", + "0x214d", + "0x217f", + "0x2191", + "0x21d0", + "0x21fb", + "0x223f", + "0x227a", + "0x2286", + "0x22b1", + "0x22f5", + "0x23a3", + "0x23e7", + "0x2422", + "0x243c", + "0x2462", + "0x246e", + "0x24d5", + "0x24f4", + "0x2520", + "0x2564", + "0x25b6", + "0x25d4", + "0x2618", + "0x2643", + "0x2648", + "0x2686", + "0x26a6", + "0x270d", + "0x2733", + "0x274e", + "0x2792", + "0x27aa", + "0x27b9", + "0x27fd", + "0x2823", + "0x283b", + "0x287f", + "0x288d", + "0x2899", + "0x28b5", + "0x28b8", + "0x297b", + "0x298f", + "0x299b", + "0x299e", + "0x29b2", + "0x29b5", + "0x2a21", + "0x2a2f", + "0x2a3b", + "0x2a47", + "0x2a4a", + "0x2a56", + "0x2a59", + "0x2a5c", + "0x2a68", + "0x2a78", + "0x2b42", + "0x2b9a", + "0x2b9d", + "0x2c85", + "0x2c88", + "0x2ce4", + "0x2d08", + "0x2d63", + "0x2da5", + "0x2e4d", + "0x2e77", + "0x2e83", + "0x2e94", + "0x2e97", + "0x2ea7", + "0x2eaa", + "0x2ead", + "0x2eb9", + "0x2eca", + "0x2ee5", + "0x2ef6", + "0x2eff", + "0x2f20", + "0x2f3b", + "0x2f7e", + "0x2f9f", + "0x2fba", + "0x2fd5", + "0x2fe6", + "0x3027", + "0x3095", + "0x30d0", + "0x30da", + "0x3112", + "0x311d", + "0x3147", + "0x3152", + "0x31d2", + "0x31f1", + "0x327f", + "0x328a", + "0x32fa", + "0x3363", + "0x33cd", + "0x33d9", + "0x346d", + "0x3487", + "0x34fc", + "0x3508", + "0x3589", + "0x3599", + "0x36bb", + "0x36d5", + "0x36d7", + "0x36e3", + "0x3709", + "0x3747", + "0x375e", + "0x3784", + "0x3823", + "0x383a", + "0x384e", + "0x3874", + "0x3895", + "0x38b6", + "0x38ca", + "0x38f7", + "0x3905", + "0x3909", + "0x3917", + "0x39b7", + "0x39ca", + "0x39dd", + "0x39e7", + "0x1ee63", + "0xe00800d00c00500c00500b00600a009008007006005004003002001000", + "0x601800901700501601501400601300901200500b00601100901000500f", + "0x500c00501f00600a00901e00501d00501c00601801b01a00501900500b", + "0x901e00502300502200601801b02100500b00601100902000500f00e00c", + "0x1b02600500c00500b00600a00902500502500502400600a01b00b006013", + "0x502a00502900601801b02800500b00601100902500501200502700600a", + "0x902500502100502c00600a01b00202b02000502000500b00600a00901e", + "0x502000500b00600a00901e00502f00502e00601801b02d00500b006011", + "0x1b03100500400302000500b00601100902500502000503000600a01b026", + "0x503400601100901a00500f03302000500400301e005031005032006018", + "0x501700503900500b00603800902500501700503700600a01b008036035", + "0x903d00500f03301000501601501e00503c00503b00601801b03a005010", + "0x604200901000501000504100600a01b04000500400303f00503e006011", + "0x500f04501e00504400504300601801b02500501a00501000501700500b", + "0x504000500b00604800903f00500400302500504700504600600a01b010", + "0x601100901e00504a00504900601801b02500501a005010005017005039", + "0x504000503900500b00604800901e00504c00504b00601801b01000500b", + "0x1b03900500f04501e00504e00504d00601801b02500501a005010005017", + "0x905200500400305100500f03303900501601502500505000504f00600a", + "0x505600601801b05500505100503900500b006054009052005053006011", + "0x505900505800601801b02500501000501a00500b00605400901e005057", + "0x505b00505a00601801b02500504000503900501a00500b00604200901e", + "0x4502600501700501700501700505e00603800905d00500400300805c01e", + "0x900806301700506200601100901a00506100506000601801b05f00500f", + "0x1b06900500b00606800901a00506700506600601801b065005064006011", + "0x506d00506c00601801b01a00500b00606800901e00506b00506a006018", + "0x506f00601801b05500500b00601100901700501700506e00600a00901e", + "0x901e00507200507100601801b01700503900500b00600a00901e005070", + "0x1b07600507600507500600a01b00807401700501700501700500b006073", + "0x601801b00807901a00503900507800601801b01a005076005077006018", + "0x501a00500b00605400901a00502600507c00601801b01a00507b00507a", + "0x906500506500507f00600a00901e00507e00507d00601801b02500501a", + "0x601100906500507b00508100600a00906500507b005017005080006073", + "0x507b00501700508400607300903900501700508300600a00907b005082", + "0x501700508600600a00903900501000503900501700508500603800907b", + "0x5017005065005088006073009026005065005017005087006073009039", + "0x508e00508d00508c00508b00608a01b06500506500508900600a009026", + "0x4509700500f04509600509500509400509300509200509100509000508f", + "0x900809d01700506500506500509c00509b00509a00609900909800500f", + "0x50a000601801b06100500b00601100906500509f00509f00509e006073", + "0x60a50090a40060130090080a301a0050170050a200601801b01e0050a1", + "0x500f0330a900501601501e0050a80050a700601801b0250050a600500b", + "0x60ae00900c00509f0050170050ad0060730090ac0050ab0060110090aa", + "0x500c0050b000501700501700501700503900500c0050650050170050af", + "0x50b20050b100601801b09c00500b006011009039005076005076005039", + "0x50b60050b500601801b0250050b400500b0060a50090b300601300901e", + "0x50b900600a01b01e0050b80050b700601801b06700500b00601100901e", + "0x507600501a00500b0060540090250050250050bb00600a01b0250050ba", + "0x503d0050be00601801b0bd00500400301e0050bd0050bc00601801b025", + "0x601801b01e0050c10050c000601801b0bf00503900500b006018009025", + "0x601801b0250050c400500b0060a50090c300601300901a0050250050c2", + "0x901e0050c80050c700601801b07600500b00601100901e0050c60050c5", + "0x1b0ca00500b00601100903900506500500b00600a0090650050c9006011", + "0x906500500400301a0050ca0050cd00601801b01e0050cc0050cb006018", + "0xe01e0050d10050d000601801b0250050cf00500b0060a50090ce006013", + "0x50d40050d300601801b0d200500b00601100901700500f04501700500f", + "0x500b0060a50090d60060130090d500500400306500500b00601100901e", + "0x500b0060a50090da00601300901e0050d90050d800601801b0250050d7", + "0x906500501700500b00600a00901e0050dd0050dc00601801b0250050db", + "0x50e000601801b0250050170050df00503900500b0060380090de006013", + "0x901e0050e30050e200601801b0250050df00500b0060a500901e0050e1", + "0x601100901e0050e50050e400601801b02500501700501a00500b006054", + "0x901e0050d50050e800601801b01e0050e70050e600601801b01700500b", + "0x50eb0050ea00601801b0e900500b00601100905500503900500b00600a", + "0x50760050ed00600a01b03a00500400302500503a0050ec00600a01b01e", + "0x600a01b0f10050040030020f00ef0050040030020ee076005004003025", + "0x50f50050f400601801b0f300503900500b00600a0090250050400050f2", + "0x50040030250050d20050f700600a01b0250050100050f600600a01b01e", + "0x1b01e0050fa0050f900601801b02500500b0060f8009039005004003010", + "0x50fd00601801b0fc00503900500b00601800902500501a0050fb006018", + "0x50df0050c40050a60050b40051000060ff00901a00500400301e0050fe", + "0x510300510200601801b07600510100500b00600a0090d70050db0050cf", + "0x600a00901e00510500510400601801b07b00510100500b00600a00901e", + "0x1b07b00500b00601100901e00510700510600601801b06500510100500b", + "0x500b00601100902500507b00510a00600a01b01e005109005108006018", + "0x60a500902500506500510d00600a01b01e00510c00510b00601801b026", + "0x503900511000600a01b01e00510f00510e00601801b02500510100500b", + "0x500400301e00511300511200601801b11100503900500b00600a009025", + "0x601100901e00511500511400601801b02500501a00500b006018009017", + "0x300211b00211a01e00511900511800601801b00211700811603900500b", + "0x612200612100612000611f11c00500511e00600500511e11d11c005004", + "0x3900500512803a00500512712600500512302f125005124039005005123", + "0x7600500512d00600c00512c07600500512b07600500512a017005005129", + "0x513001700500512b12f00500512b00500500512b00612e076005005123", + "0x513401900500513401700500513301700500512313200c005131017005", + "0x11c00500512313700500512300600500512300500c13600500c13501e005", + "0xa60050051340b400500513400613a139005005123006138136005005123", + "0xd70050051340db0050051340cf0050051340df0050051340c4005005134", + "0x600500513c13b12500512410100500512b10100500512a101005005134", + "0x3900500512b03900500512a11900500512813600500512711c00500513c", + "0x2500500512b11500500512813e00500512713d12500512401a005005123", + "0x13600500c13511900500513403900500513401a00500512b01a00500512a", + "0x512401700500513c01700500511e14000c00513113f00c00513100600c", + "0x5127031125005124111005005127113005005128142005005127141125", + "0x512714612500512414500500512b14400c00513110f00500512b143005", + "0x512814900500512714812500512406500500512306500500512b147005", + "0x512414a12500512402600500512302600500512b02600500512a10c005", + "0x512403c12500512403a125005124017125005124039125005124035125", + "0x512403d12500512407b00500512307b00500512b14c00500512714b125", + "0x512404012500512407b00500512a10900500512814d00500512703f125", + "0x512415012500512406500500512a10700500512814f00500512714e125", + "0x5128153005005127152125005124105005005128151005005127044125", + "0xfe00500512815500500512704712500512401a00500511e006154103005", + "0xfa00500512b15700500512715612500512401a00500513c0fc005005127", + "0x515a03900500513c00615901000500511e03900500511e15800500512b", + "0x513400615c15b00500512303500500512300600c15b00500c135017005", + "0x1700500512d01700500515d15b00500512700500c15b00500c135025005", + "0x512704a12500512401000500513c00616015f00500512715e125005124", + "0x512301000500512b04000500512b0f30050051270f5005005128161005", + "0x51311621250051240400050051230100050051230f10050051230ef005", + "0x513116600500512b03500500512b16500c00513116400500512b16300c", + "0x512407600500511e0ef00500511e0f100500511e04c12500512416700c", + "0x512416b00500512b16a00500512b07600500513c169005005127168125", + "0x512403a00500511e16c00500512b0f100500513c0ef00500513c04e125", + "0x512403a00500512303a00500512b03a00500513c16e00500512716d125", + "0x51230e900500512b0e900500512a0eb00500512816f005005127050125", + "0x512405212500512405112500512417100500512b1701250051240e9005", + "0x51240571250051240551250051240d5005005128173005005127172125", + "0x512810100500517500500c03a00500c13500600c03a00500c135174125", + "0x512b0cf00500512b0c400500512b0a600500512b0b400500512b101005", + "0x51281760050051270591250051240170050051750d700500512b0db005", + "0xe500500512817900500512717812500512400617700500c0051310e7005", + "0x13e00500c13511500500513405b12500512403900500512d039005005175", + "0x11100500c13517a12500512400500c13e00500c13513e00500512300600c", + "0x11100500c13514200500512300600c14200500c13511300500513400600c", + "0x17b00c00513102600500512705d12500512400500c14200500c13500500c", + "0x617d07600500517517c00c00512c14300500512300500c14300500c135", + "0x900050051340e300500512818000500512717f12500512417e00c005131", + "0x18200500512706112500512410f005005128181125005124090005005123", + "0x14700500c13500618300600c14300500c13510f0050051340e1005005128", + "0x1840050051340df00500512b00500c14700500c13514700500512300600c", + "0x512300600c14900500c13510c005005134185125005124184005005123", + "0x1700500512a00600c00513102600500512d00500c14900500c135149005", + "0x512400500c02600500c13510100500512d065005005175186125005124", + "0x51240950050051230950050051340dd005005128187005005127065125", + "0x6b12500512418800c00513106912500512400600c02600500c135067125", + "0x18a1250051240940050051230940050051340d9005005128189005005127", + "0x511e00500c14c00500c13514c00500512300600c14c00500c13500618b", + "0x512d06d1250051240d500500513c07b00500517518c00c0051310d5005", + "0x512a00600c00518f0d400500512818e00500512718d125005124035005", + "0x19300500512b00619200619100619007b00500512d0ba1250051240cf005", + "0x910050051340d100500512819500500512707012500512419400c005131", + "0x10900500513419700500512b0d500500512b196125005124091005005123", + "0x6500500511e00500c14d00500c13514d00500512300600c14d00500c135", + "0x600c19900500c1350ca0050051340061980721250051240a600500512a", + "0x512819b00500512719a12500512400500c19900500c135199005005123", + "0x512419c00500512319c00500513406500500513c0ca0050051280cc005", + "0x10700500513407612500512408d00500512308d00500513400619e19d125", + "0x19f00500512b00500c14f00500c13514f00500512300600c14f00500c135", + "0x1a112500512408e00500512308e0050051341a012500512406500500512d", + "0x500c15100500c13515100500512300600c15100500c135105005005134", + "0x500c00512c0c80050051281a30050051271a21250051240c400500512a", + "0x1030050051340c60050051281a50050051271a412500512407b125005124", + "0xfe00500513400500c15300500c13515300500512300600c15300500c135", + "0xfc00500c13500500c15500500c13515500500512300600c15500500c135", + "0x500c1a700500c1351a700500512300600c1a700500c1350061a600500c", + "0xc13515700500512300600c15700500c1350fa0050051341a8125005124", + "0x15f00500c13515f00500512300600c15f00500c1350061a900500c157005", + "0x51281aa00500512707e12500512403d00500512301000500513000500c", + "0xc13504000500513403d00500512b03d00500512a0bf0050051270c1005", + "0xc13516100500512300600c16100500c1350f500500513400600c0f3005", + "0x51240100050051751ab12500512400500c16100500c13500500c0f3005", + "0x512b0bd00500511e08d12500512409200500512309200500513408c125", + "0x51280bd00500513c1ac00500512708e125005124040005005175109005", + "0x512409300500512309300500513408f12500512400600c0051ad0bd005", + "0x512300600c16900500c1350061af1ae00500512b0bd00500512b090125", + "0x512300500c16e00500c13509112500512400500c16900500c135169005", + "0x1b100c00513100600c16e00500c1351b000500512709212500512416e005", + "0x1b200500512300500c1b200500c13516f00500512300500c16f00500c135", + "0x51230e900500512800600c16f00500c1350eb005005134093125005124", + "0x512a1b300c00513109512500512405500500512b094125005124055005", + "0x51240670050051230670050051341b40050051270961250051240b4005", + "0x51340b60050051280670050051280b80050051281b60050051271b5125", + "0xc1350d50050051340b800500512b09b125005124096005005123096005", + "0x1b800c0051310061b700500c17300500c13517300500512300600c173005", + "0x9800500512809800500515d0b20050051281b900500512709c125005124", + "0x513405f1250051240061bb1ba00c0051310b000500512b00c00500512b", + "0x512709712500512409800500512309f12500512408f00500512308f005", + "0x512408c00500512308c0050051340a80050051280a11250051241bc005", + "0x512409800500512b0dd00500512b0b600500512b0a800500512b1bd125", + "0x1be00500c1351be00500512300600c1be00500c1350061c00061bf1be125", + "0x17600500512300600c17600500c1350e70050051341c112500512400500c", + "0x17900500512300600c17900500c1350e500500513400500c17600500c135", + "0x1bd0050051270a612500512400600c0fc00500c13500500c17900500c135", + "0x9c00500512b09b00500512b05f00500512805f00500515d0a1005005128", + "0x600c18000500c1350e30050051340fa0050051280061c20df00500512a", + "0x512b1b500500512a0a812500512400500c18000500c135180005005123", + "0x513407e0050051281ab0050051271bc1250051241b50050051231b5005", + "0x512400500c18200500c13518200500512300600c18200500c1350e1005", + "0x512400500c1a800500c1351a800500512300600c1a800500c1350aa125", + "0x512300600c18700500c1350dd0050051340061c30db00500512a0ac125", + "0xd700500512a0a91250051240b012500512400500c18700500c135187005", + "0x500c18900500c13518900500512300600c18900500c1350d9005005134", + "0x18e00500c1350d40050051340170050051c40b2125005124098125005124", + "0x1b912500512400500c18e00500c1351c500c00513118e00500512300600c", + "0xc1351c600c0051311a400500512300600c1a400500c1350b4125005124", + "0x512300600c19500500c1350d10050051340b612500512400500c1a4005", + "0x1c10050051231c800c0051c71b612500512400500c19500500c135195005", + "0xc13519b00500512300600c19b00500c1350cc005005134199005005127", + "0x600c1a200500c1350061ca1c900c00513119c00500512800500c19b005", + "0x512411900500512b0b812500512400500c1a200500c1351a2005005123", + "0x512d00600500512d13700500512d12600500512d1cb00c0051311b4125", + "0x1a100500512300600c1a100500c1351cc00c0051c71b212500512411c005", + "0x500c1a100500c1351a300500512300500c1a300500c1351cd00c005131", + "0x1a000500c1350061ce00600c1a300500c1350c80050051341b0125005124", + "0xbd1250051241cf00c00513100500c1a000500c1351a000500512300600c", + "0x500c1a500500c1351a500500512300600c1a500500c1350c6005005134", + "0x600c1aa00500c1350c100500513400600c0bf00500c1351a7005005127", + "0xc13502500500512d00500c1aa00500c1350100050051331aa005005123", + "0x19a0050051271ac12500512419d00500512319d00500513400500c0bf005", + "0x400050051280bf1250051241ae1250051241d000c005131072005005128", + "0xc1351ac00500512300600c1ac00500c1350bd005005134010005005129", + "0x1b000500c1351a71250051241aa1250051240c112500512400500c1ac005", + "0x51340700050051281960050051270c41250051241b000500512300600c", + "0x512403900500512905500500512805500500512d0550050051750e9005", + "0x512818d0050051271a51250051240ba0050051281b20050051270c6125", + "0x51271a312500512405d0050051231d100c0051c70c812500512406d005", + "0xc1350b800500513419c12500512406900500512306b00500512818a005", + "0x51340ca12500512400500c1b400500c1351b400500512300600c1b4005", + "0x512400500c1b600500c1351b600500512300600c1b600500c1350b6005", + "0x1b900500c1351b900500512300600c1b900500c1350b20050051340cc125", + "0xc1350a800500513419912500512419b1250051241d200c00513100500c", + "0x513119f12500512400500c1bc00500c1351bc00500512300600c1bc005", + "0x61d61be0050051270061d50061d41860050051281860050051341d300c", + "0xcf12500512400500c18500500c13518500500512300600c18500500c135", + "0x500c1bd00500c1351bd00500512300600c1bd00500c1350a1005005134", + "0x51310d11250051241d700c0051311b500500512701000c1b500500c135", + "0x51241da00c0051311931250051241d900c0051311951250051241d800c", + "0x1ab00500512300500c1ab00500c1350d41250051241db00c0051310d2125", + "0x1de00c0051310d51250051241dd00c00513118e1250051241dc00c005131", + "0xd91250051241e000c0051310d71250051241df00c005131197125005124", + "0x512800600c1ab00500c13507e0050051341891250051241e100c005131", + "0x1e300c00513101e00c1b500500c1351a80050051271e200c005131184005", + "0x513106700500512b1e500c0051311e400c00513101a00c1b500500c135", + "0x1b500500c1351a200500512701200c1b500500c1351a40050051271e600c", + "0x19d0050051281a00050051271a100500512700c00c1b500500c13500500c", + "0x19a00500512300600c19a00500c1350720050051341390050051750061e7", + "0x512b18100500512818100500513413900500512b00500c19a00500c135", + "0x512817a0050051270db12500512405d00500513c05d00500511e19d005", + "0x512b05d00500512b05900500512b1780050051270dd12500512405b005", + "0xdf12500512418412500512418712500512401d00c1b500500c13517f005", + "0x512401900c1b500500c1350e31250051241821250051240e1125005124", + "0x51240510050051230390050051300e5125005124059005005128180125", + "0xc13507000500513405100500512b057005005128174005005127179125", + "0x515a05200500511e00500c19600500c13519600500512300600c196005", + "0x17000500c13517000500512305200500512300600c17000500c135039005", + "0x512b05500500513403900500515d17000500512705200500513c00500c", + "0xc13506d0050051341761250051240e712500512417200500512b052005", + "0x512417312500512400500c18d00500c13518d00500512300600c18d005", + "0x18a00500c13506b00500513400600c06900500c1350eb1250051240e9125", + "0x6900500c13500500c18a00500c1351e800c00513118a00500512300600c", + "0xc13512500c1b500500c1351e900c1b500500c13506900500512700500c", + "0x8d00500517508c00500512808c00500517518500500512700600c1b5005", + "0x9000500517508f00500512808e00500512808e00500517508d005005128", + "0x92005005128092005005175091005005128091005005175090005005128", + "0x517509300500512809300500517509200500512b0061ea01000500512d", + "0x5128096005005175095005005128095005005175094005005128094005", + "0x16f12500512417a00500512300500c17a00500c1351eb00c005131096005", + "0x51ec00600c17a00500c13505b00500513404e00500512816d005005127", + "0x16800500512716e12500512400500c0051ad0061ed05d005005175017005", + "0xc13517800500512300600c17800500c13505900500513404c005005128", + "0x1000500c1f11f000c0051311ef00c0051311ee00c00513100500c178005", + "0x513304a0050051281620050051271711250051241f200c0051ad076005", + "0x17400500c13517400500512300600c17400500c135057005005134039005", + "0x515a03f00500511e1691250051241f300c00513105100500512a00500c", + "0x15600500c13515600500512303f00500512300600c15600500c135010005", + "0x512716c12500512401000500515d15600500512703f00500513c00500c", + "0x16d00500512300600c16d00500c13504e005005134044005005128152005", + "0x61f515e00500512b1f400c00513103f00500512b00500c16d00500c135", + "0x1f600c00513100500c15000500c13515000500512300600c15000500c135", + "0xc13516800500512300600c16800500c13504c0050051340ef125005124", + "0x14b00500512716a12500512404000500513c04000500511e00500c168005", + "0xc13516200500512300600c16200500c13504a00500513403c005005128", + "0xf112500512402000500511e1f700c00513114e00500512b00500c162005", + "0x512402000500513c0200050051230f31250051240061f816b125005124", + "0x200050051340061f90310050051280200050051281480050051270f5125", + "0xc13515200500512300600c15200500c135044005005134161125005124", + "0x3100500511e15000500512714a00500512b02000500512b00500c152005", + "0x15b12500512403100500513c15f12500512400600c0051fa00500c0051fa", + "0xc13514b00500512300600c14b00500c13503c00500513400c005005123", + "0x51310061fb01000500512a14600500512b03100500512b00500c14b005", + "0x3100500513416412500512416612500512400c00c0051fa0061fd1fc00c", + "0x1fe00c0051fa00500c14800500c13514800500512300600c14800500c135", + "0x513100620100620000c00500512d00c00500512a0061ff00c005005175", + "0x15712500512420400c0051311410050051270fa12500512400620320200c", + "0x1551250051240fe1250051240fc12500512400c00c0051ad020005005175", + "0x512300600c14100500c13513d00500512815812500512420500c005131", + "0x2f00500512813b00500512710112500512400500c14100500c135141005", + "0x512820800500513410312500512420700500512300620602d005005127", + "0x512702a00500512820a00500512715312500512420900c005131208005", + "0x20c00500512820c00500512320c00500513410512500512400620b028005", + "0x20d00500512715112500512413d00500512d13d00500512313d005005134", + "0x600c13b00500c13502f00500513400600c02d00500c135023005005128", + "0x1e900500512710712500512400620e00500c13b00500c13513b005005123", + "0x600c20a00500c13502a00500513400600c02800500c13501d005005128", + "0x12500500512812500500513400620f00500c20a00500c13520a005005123", + "0x20d00500512300600c20d00500c13502300500513414f125005124006210", + "0xc13501d00500513410912500512400500c20d00500c13521100c005131", + "0x621300500c1e900500c13521200c0051311e900500512300600c1e9005", + "0x512300500c02800500c13500621402d00500512300500c02d00500c135", + "0x600c00601a00521600500600500601d005216005006006006215028005", + "0xc41e901e00c21600c00c00500c010006006216005006125006006216005", + "0x501900601000521600501000501d00600621600500601200602102000c", + "0x21600c20d00501e00601e00521600501e00501a00620d02300c216005010", + "0x620c0052160050230051e90060062160050060120060260050a9025005", + "0x2a00502300620a02a00c21600502800502100602800521600520c005020", + "0x602d20700c21600520800502100620800521600500620d006006216005", + "0x21600502d00502500602f00521600520a005025006006216005207005023", + "0x603f00621600c13b02f00c20c00602f00521600502f00502600613b005", + "0x621600501a00502a00600621600501d005028006006216005006012006", + "0x521600500620700613d00521600500620800600621600502500520a006", + "0x13b00603100521600514113d00c02f00614100521600514100502d006141", + "0x21600514800514100614800521600503114600c13d006146005216005006", + "0x14600601e00521600501e00501a00600600521600500600503100614a005", + "0x21600514a00514a0061250052160051250051480061e90052160051e9005", + "0x21600500603500600621600500601200614a1251e901e00601200514a005", + "0x3900c21600c0351e901e125017006035005216005035005039006035005", + "0x3c00614b00521600500603a00600621600500601200603c03a00c096017", + "0x604000521600500603d00603f00521600500614b00603d005216005006", + "0x4400521600500614e00615000521600500604000614e00521600500603f", + "0x21600515200504400615200521600504415014e04003f03d14b019150006", + "0x14600603900521600503900501a00600621600504700515200615604700c", + "0x216005125005148006006005216005006005031006017005216005017005", + "0x502515612500601703901d04700602500521600502500502d006125005", + "0x1a00c15e00601200521600501201d00c15600616201901204a15e012216", + "0x500601200616800508e04c00521600c16200504a006019005216005019", + "0x504c00616d00521600504c00516200604e005216005006208006006216", + "0x521600515e00501a00600621600505000516800617005000c21600516d", + "0x504e00617000521600517000501d00604a00521600504a00514600615e", + "0x5000617205205112521600504e17004a15e01016d00604e00521600504e", + "0x50550051700060062160050060120060570051a205500521600c172005", + "0x5b17800c21600517400505200600621600505900505100605917400c216", + "0x517a00505700617a00521600505b005055006006216005178005172006", + "0x601200521600501200503100617f00521600505d00517400605d005216", + "0x501900514800605200521600505200514600605100521600505100501a", + "0x1200617f01905205101201200517f00521600517f00514a006019005216", + "0x12005216005012005031006181005216005057005141006006216005006", + "0x1900514800605200521600505200514600605100521600505100501a006", + "0x618101905205101201200518100521600518100514a006019005216005", + "0x5216005012005031006061005216005168005141006006216005006012", + "0x514800604a00521600504a00514600615e00521600515e00501a006012", + "0x6101904a15e01201200506100521600506100514a006019005216005019", + "0x621600501a00502a00600621600501d005028006006216005006012006", + "0x521600500605900618500521600500620800600621600502500520a006", + "0x13b00606500521600518618500c02f00618600521600518600502d006186", + "0x21600506900514100606900521600506506700c13d006067005216005006", + "0x14600603a00521600503a00501a00600600521600500600503100606b005", + "0x21600506b00514a00612500521600512500514800603c00521600503c005", + "0x502600505100600621600500601200606b12503c03a00601200506b005", + "0x2300516800600621600501a00502a00600621600501d005028006006216", + "0x502d00606d00521600500617800618a005216005006208006006216005", + "0x521600500613b00618d00521600506d18a00c02f00606d00521600506d", + "0x3100619600521600507000514100607000521600518d0ba00c13d0060ba", + "0x2160051e900514600601e00521600501e00501a006006005216005006005", + "0x1200519600521600519600514a0061250052160051250051480061e9005", + "0x16800600621600501a00502a0060062160050060120061961251e901e006", + "0x607200521600500620800600621600501d005028006006216005010005", + "0x519a07200c02f00619a00521600519a00502d00619a005216005006059", + "0x61a000521600519d07600c13d00607600521600500613b00619d005216", + "0x502000501a0060060052160050060050310061a10052160051a0005141", + "0x6125005216005125005148006021005216005021005146006020005216", + "0x521600500605b0061a11250210200060120051a10052160051a100514a", + "0x21600c00c00500c01000600621600500612500600621600500600c00601d", + "0x521600501000501d0060062160050060120061e901e00c21701a01900c", + "0x1e00601900521600501900501a00602102000c216005010005019006010", + "0x501900501a00600621600500601200602300521801200521600c021005", + "0x602000521600502000501d00601a00521600501a005146006019005216", + "0x2602520d12521600502001a01912505d00601200521600501201d00c17a", + "0x518100600621600500601200602800521920c00521600c02600517f006", + "0x601200620700521a20800521600c20a00506100620a02a00c21600520c", + "0x602f00521600502d00502000602d00521600502a0051e9006006216005", + "0x21600500620d00600621600513b00502300613d13b00c21600502f005021", + "0x2500600621600503100502300614603100c216005141005021006141005", + "0x21600514800502600614a00521600514600502500614800521600513d005", + "0x16800600621600500601200600610500621600c14a14800c20c006148005", + "0x603500521600500620800600621600501200520a006006216005208005", + "0x503903500c02f00603900521600503900502d006039005216005006207", + "0x603c00521600501703a00c13d00603a00521600500613b006017005216", + "0x520d00501a00600600521600500600503100614b00521600503c005141", + "0x612500521600512500514800602500521600502500514600620d005216", + "0x621600500601200614b12502520d00601200514b00521600514b00514a", + "0x2520d12501700603d00521600503d00503900603d005216005006035006", + "0x500603a00600621600500601200615014e00c21b04003f00c21600c03d", + "0x603d00604700521600500614b00615200521600500603c006044005216", + "0x14e00604a00521600500604000615e00521600500603f006156005216005", + "0x604c00521600516204a15e156047152044019150006162005216005006", + "0x500600503100604000521600504000514600603f00521600503f00501a", + "0x601200521600501200502d006125005216005125005148006006005216", + "0x1221600520801204c12500604003f01918500620800521600520800501d", + "0x500601200605200521c05100521600c17000518600617005016d04e168", + "0x172005052006172005216005006208006006216005051005065006006216", + "0x17400521600505700505500600621600505500517200605705500c216005", + "0x16d005031006178005216005059005174006059005216005174005057006", + "0x4e00521600504e00514600616800521600516800501a00616d005216005", + "0x16816d01200517800521600517800514a006050005216005050005148006", + "0x503100605b00521600505200514100600621600500601200617805004e", + "0x521600504e00514600616800521600516800501a00616d00521600516d", + "0x16d01200505b00521600505b00514a00605000521600505000514800604e", + "0x520a00600621600520800516800600621600500601200605b05004e168", + "0x2d00605d00521600500605900617a005216005006208006006216005012", + "0x21600500613b00617f00521600505d17a00c02f00605d00521600505d005", + "0x618500521600506100514100606100521600517f18100c13d006181005", + "0x515000514600614e00521600514e00501a006006005216005006005031", + "0x518500521600518500514a006125005216005125005148006150005216", + "0x600621600520700505100600621600500601200618512515014e006012", + "0x18600521600500620800600621600501200520a00600621600502a005168", + "0x6518600c02f00606500521600506500502d006065005216005006067006", + "0x6b00521600506706900c13d00606900521600500613b006067005216005", + "0x20d00501a00600600521600500600503100618a00521600506b005141006", + "0x12500521600512500514800602500521600502500514600620d005216005", + "0x21600500601200618a12502520d00601200518a00521600518a00514a006", + "0x600503100606d00521600502800514100600621600501200520a006006", + "0x2500521600502500514600620d00521600520d00501a006006005216005", + "0x20d00601200506d00521600506d00514a006125005216005125005148006", + "0x2000516800600621600502300505100600621600500601200606d125025", + "0x617800618d00521600500620800600621600501d005069006006216005", + "0x52160050ba18d00c02f0060ba0052160050ba00502d0060ba005216005", + "0x514100607200521600507019600c13d00619600521600500613b006070", + "0x521600501900501a00600600521600500600503100619a005216005072", + "0x514a00612500521600512500514800601a00521600501a005146006019", + "0x16800600621600500601200619a12501a01900601200519a00521600519a", + "0x619d00521600500620800600621600501d005069006006216005010005", + "0x507619d00c02f00607600521600507600502d006076005216005006059", + "0x61a20052160051a01a100c13d0061a100521600500613b0061a0005216", + "0x501e00501a00600600521600500600503100607b0052160051a2005141", + "0x61250052160051250051480061e90052160051e900514600601e005216", + "0x621600500612500607b1251e901e00601200507b00521600507b00514a", + "0x621600500601200601a01900c21d01d01200c21600c00c00500c010006", + "0x1200c06b00601000521600501000501d00601200521600501200501a006", + "0x1200602300521e02100521600c02000518a0060201e901e125216005010", + "0x20d00c2160051e90050190061e90052160051e900501d006006216005006", + "0x1e900600621600500601200620c00521f02600521600c02500501e006025", + "0x21600502a00502100602a00521600502800502000602800521600520d005", + "0x502100620700521600500620d00600621600520a00502300620820a00c", + "0x521600520800502500600621600502d00502300602f02d00c216005207", + "0xc20c00613b00521600513b00502600613d00521600502f00502500613b", + "0x621600502600520a00600621600500601200600622000621600c13d13b", + "0x521600500620700614100521600500620800600621600502100506d006", + "0x13b00614600521600503114100c02f00603100521600503100502d006031", + "0x21600514a00514100614a00521600514614800c13d006148005216005006", + "0x14600601e00521600501e00501a006006005216005006005031006035005", + "0x21600503500514a00612500521600512500514800601d00521600501d005", + "0x21600500603500600621600500601200603512501d01e006012005035005", + "0x1700c21600c03901d01e125017006039005216005039005039006039005", + "0x3c00603d00521600500603a00600621600500601200614b03c00c22103a", + "0x614e00521600500603d00604000521600500614b00603f005216005006", + "0x15200521600500614e00604400521600500604000615000521600500603f", + "0x21600504700504400604700521600515204415014e04003f03d019150006", + "0x14600601700521600501700501a00600621600515600515200615e15600c", + "0x21600512500514800600600521600500600503100603a00521600503a005", + "0xba00602600521600502600502d00602100521600502100518d006125005", + "0x4e00507000604e16804c16204a01221600502602115e12500603a017019", + "0x17000521600500620800600621600500601200605000522216d00521600c", + "0x519a00617205200c21600505100507200605100521600516d005196006", + "0x17000521600517000504e00617200521600517200519d006006216005052", + "0x505200600621600505700505100605705500c21600517017200c076006", + "0x521600505900505500600621600517400517200605917400c216005055", + "0x503100617a00521600505b00517400605b005216005178005057006178", + "0x521600516200514600604a00521600504a00501a00604c00521600504c", + "0x4c01200517a00521600517a00514a006168005216005168005148006162", + "0x3100605d00521600505000514100600621600500601200617a16816204a", + "0x21600516200514600604a00521600504a00501a00604c00521600504c005", + "0x1200505d00521600505d00514a006168005216005168005148006162005", + "0x6d00600621600502600520a00600621600500601200605d16816204a04c", + "0x618100521600500605900617f005216005006208006006216005021005", + "0x500613b00606100521600518117f00c02f00618100521600518100502d", + "0x6500521600518600514100618600521600506118500c13d006185005216", + "0x14b00514600603c00521600503c00501a006006005216005006005031006", + "0x6500521600506500514a00612500521600512500514800614b005216005", + "0x621600520c00505100600621600500601200606512514b03c006012005", + "0x521600500620800600621600502100506d00600621600520d005168006", + "0x6700c02f00606900521600506900502d006069005216005006067006067", + "0x521600506b18a00c13d00618a00521600500613b00606b005216005069", + "0x501a00600600521600500600503100618d00521600506d00514100606d", + "0x521600512500514800601d00521600501d00514600601e00521600501e", + "0x500601200618d12501d01e00601200518d00521600518d00514a006125", + "0x50062080060062160051e9005168006006216005023005051006006216", + "0x2f00607000521600507000502d0060700052160050061780060ba005216", + "0x519607200c13d00607200521600500613b0061960052160050700ba00c", + "0x600600521600500600503100619d00521600519a00514100619a005216", + "0x512500514800601d00521600501d00514600601e00521600501e00501a", + "0x1200619d12501d01e00601200519d00521600519d00514a006125005216", + "0x59006076005216005006208006006216005010005168006006216005006", + "0x2160051a007600c02f0061a00052160051a000502d0061a0005216005006", + "0x14100607b0052160051a11a200c13d0061a200521600500613b0061a1005", + "0x21600501900501a0060060052160050060050310061a400521600507b005", + "0x14a00612500521600512500514800601a00521600501a005146006019005", + "0x60062160050061250061a412501a0190060120051a40052160051a4005", + "0x600621600500601200601a01900c22301d01200c21600c00c00500c010", + "0x1001200c06b00601000521600501000501d00601200521600501200501a", + "0x601200602300522402100521600c02000518a0060201e901e125216005", + "0x2520d00c2160051e90050190061e90052160051e900501d006006216005", + "0x51e900600621600500601200620c00522502600521600c02500501e006", + "0xc21600502a00502100602a00521600502800502000602800521600520d", + "0x20700502100620700521600500620d00600621600520a00502300620820a", + "0x13b00521600520800502500600621600502d00502300602f02d00c216005", + "0x13b00c20c00613b00521600513b00502600613d00521600502f005025006", + "0x600621600502600520a00600621600500601200600622600621600c13d", + "0x3100521600500620700614100521600500620800600621600502100506d", + "0x613b00614600521600503114100c02f00603100521600503100502d006", + "0x521600514a00514100614a00521600514614800c13d006148005216005", + "0x514600601e00521600501e00501a006006005216005006005031006035", + "0x521600503500514a00612500521600512500514800601d00521600501d", + "0x521600500603500600621600500601200603512501d01e006012005035", + "0x3a01700c21600c03901d01e125017006039005216005039005039006039", + "0x603c00603d00521600500603a00600621600500601200614b03c00c227", + "0x3f00614e00521600500603d00604000521600500614b00603f005216005", + "0x615200521600500614e006044005216005006040006150005216005006", + "0x521600501700501a00604700521600515204415014e04003f03d019150", + "0x514800600600521600500600503100603a00521600503a005146006017", + "0x521600502600502d00602100521600502100518d006125005216005125", + "0x604c16204a15e15601221600502602104712500603a0170191a0006026", + "0x16800506500600621600500601200604e00522816800521600c04c005186", + "0x617005000c21600516d00505200616d005216005006208006006216005", + "0x216005051005057006051005216005170005055006006216005050005172", + "0x1a00604a00521600504a005031006172005216005052005174006052005", + "0x21600516200514800615e00521600515e005146006156005216005156005", + "0x601200617216215e15604a01200517200521600517200514a006162005", + "0x604a00521600504a00503100605500521600504e005141006006216005", + "0x516200514800615e00521600515e00514600615600521600515600501a", + "0x1200605516215e15604a01200505500521600505500514a006162005216", + "0x20800600621600502100506d00600621600502600520a006006216005006", + "0x17400521600517400502d006174005216005006059006057005216005006", + "0x17800c13d00617800521600500613b00605900521600517405700c02f006", + "0x521600500600503100617a00521600505b00514100605b005216005059", + "0x514800614b00521600514b00514600603c00521600503c00501a006006", + "0x17a12514b03c00601200517a00521600517a00514a006125005216005125", + "0x621600520d00516800600621600520c005051006006216005006012006", + "0x521600500606700605d00521600500620800600621600502100506d006", + "0x13b00618100521600517f05d00c02f00617f00521600517f00502d00617f", + "0x21600518500514100618500521600518106100c13d006061005216005006", + "0x14600601e00521600501e00501a006006005216005006005031006186005", + "0x21600518600514a00612500521600512500514800601d00521600501d005", + "0x502300505100600621600500601200618612501d01e006012005186005", + "0x50061780060650052160050062080060062160051e9005168006006216", + "0x6900521600506706500c02f00606700521600506700502d006067005216", + "0x18a00514100618a00521600506906b00c13d00606b00521600500613b006", + "0x1e00521600501e00501a00600600521600500600503100606d005216005", + "0x6d00514a00612500521600512500514800601d00521600501d005146006", + "0x516800600621600500601200606d12501d01e00601200506d005216005", + "0x2d0060ba00521600500605900618d005216005006208006006216005010", + "0x21600500613b0060700052160050ba18d00c02f0060ba0052160050ba005", + "0x619a00521600507200514100607200521600507019600c13d006196005", + "0x501a00514600601900521600501900501a006006005216005006005031", + "0x519a00521600519a00514a00612500521600512500514800601a005216", + "0xc21600c00c00500c01000600621600500612500619a12501a019006012", + "0x1200521600501200501a00600621600500601200601a01900c22901d012", + "0x60201e901e12521600501001200c06b00601000521600501000501d006", + "0x1e900501d00600621600500601200602300522a02100521600c02000518a", + "0x521600c02500501e00602520d00c2160051e90050190061e9005216005", + "0x2000602800521600520d0051e900600621600500601200620c00522b026", + "0x520a00502300620820a00c21600502a00502100602a005216005028005", + "0x2300602f02d00c21600520700502100620700521600500620d006006216", + "0x521600502f00502500613b00521600520800502500600621600502d005", + "0x600622c00621600c13d13b00c20c00613b00521600513b00502600613d", + "0x600621600502100506d00600621600502600520a006006216005006012", + "0x521600503100502d006031005216005006207006141005216005006208", + "0xc13d00614800521600500613b00614600521600503114100c02f006031", + "0x21600500600503100603500521600514a00514100614a005216005146148", + "0x14800601d00521600501d00514600601e00521600501e00501a006006005", + "0x12501d01e00601200503500521600503500514a006125005216005125005", + "0x216005039005039006039005216005006035006006216005006012006035", + "0x601200614b03c00c22d03a01700c21600c03901d01e125017006039005", + "0x614b00603f00521600500603c00603d00521600500603a006006216005", + "0x4000615000521600500603f00614e00521600500603d006040005216005", + "0x15014e04003f03d01915000615200521600500614e006044005216005006", + "0x21600503a00514600601700521600501700501a006047005216005152044", + "0x18d00612500521600512500514800600600521600500600503100603a005", + "0x603a0170191a100602600521600502600502d006021005216005021005", + "0x16800521600c04c00518600604c16204a15e156012216005026021047125", + "0x500620800600621600516800506500600621600500601200604e00522e", + "0x600621600505000517200617005000c21600516d00505200616d005216", + "0x5052005174006052005216005051005057006051005216005170005055", + "0x615600521600515600501a00604a00521600504a005031006172005216", + "0x517200514a00616200521600516200514800615e00521600515e005146", + "0x4e00514100600621600500601200617216215e15604a012005172005216", + "0x15600521600515600501a00604a00521600504a005031006055005216005", + "0x5500514a00616200521600516200514800615e00521600515e005146006", + "0x520a00600621600500601200605516215e15604a012005055005216005", + "0x5900605700521600500620800600621600502100506d006006216005026", + "0x21600517405700c02f00617400521600517400502d006174005216005006", + "0x14100605b00521600505917800c13d00617800521600500613b006059005", + "0x21600503c00501a00600600521600500600503100617a00521600505b005", + "0x14a00612500521600512500514800614b00521600514b00514600603c005", + "0x600621600500601200617a12514b03c00601200517a00521600517a005", + "0x621600502100506d00600621600520d00516800600621600520c005051", + "0x21600517f00502d00617f00521600500606700605d005216005006208006", + "0x13d00606100521600500613b00618100521600517f05d00c02f00617f005", + "0x500600503100618600521600518500514100618500521600518106100c", + "0x601d00521600501d00514600601e00521600501e00501a006006005216", + "0x1d01e00601200518600521600518600514a006125005216005125005148", + "0x51e9005168006006216005023005051006006216005006012006186125", + "0x6700502d006067005216005006178006065005216005006208006006216", + "0x6b00521600500613b00606900521600506706500c02f006067005216005", + "0x503100606d00521600518a00514100618a00521600506906b00c13d006", + "0x521600501d00514600601e00521600501e00501a006006005216005006", + "0x601200506d00521600506d00514a00612500521600512500514800601d", + "0x620800600621600501000516800600621600500601200606d12501d01e", + "0x60ba0052160050ba00502d0060ba00521600500605900618d005216005", + "0x7019600c13d00619600521600500613b0060700052160050ba18d00c02f", + "0x600521600500600503100619a005216005072005141006072005216005", + "0x12500514800601a00521600501a00514600601900521600501900501a006", + "0x619a12501a01900601200519a00521600519a00514a006125005216005", + "0x601a01900c22f01d01200c21600c00c00500c010006006216005006125", + "0xc21600501000501900601000521600501000501d006006216005006012", + "0x523002000521600c1e900501e00601200521600501200501a0061e901e", + "0x501e00501d00601200521600501200501a006006216005006012006021", + "0x21600c02500518a00602520d02312521600501e01200c06b00601e005216", + "0x602800521600520d0051e900600621600500601200620c005231026005", + "0x20a00502300620820a00c21600502a00502100602a005216005028005020", + "0x602f02d00c21600520700502100620700521600500620d006006216005", + "0x21600502f00502500613b00521600520800502500600621600502d005023", + "0x623200621600c13d13b00c20c00613b00521600513b00502600613d005", + "0x621600502000520a00600621600502600506d006006216005006012006", + "0x21600503100502d006031005216005006207006141005216005006208006", + "0x13d00614800521600500613b00614600521600503114100c02f006031005", + "0x500600503100603500521600514a00514100614a00521600514614800c", + "0x601d00521600501d00514600602300521600502300501a006006005216", + "0x1d02300601200503500521600503500514a006125005216005125005148", + "0x5039005039006039005216005006035006006216005006012006035125", + "0x1200614b03c00c23303a01700c21600c03901d023125017006039005216", + "0x14b00603f00521600500603c00603d00521600500603a006006216005006", + "0x615000521600500603f00614e00521600500603d006040005216005006", + "0x14e04003f03d01915000615200521600500614e006044005216005006040", + "0x15600515200615e15600c216005047005044006047005216005152044150", + "0x603a00521600503a00514600601700521600501700501a006006216005", + "0x502000502d006125005216005125005148006006005216005006005031", + "0x2015e12500603a0170191a200602600521600502600518d006020005216", + "0x5000523416d00521600c04e00507000604e16804c16204a012216005026", + "0x521600516d005196006170005216005006208006006216005006012006", + "0x519d00600621600505200519a00617205200c216005051005072006051", + "0x21600517017200c07600617000521600517000504e006172005216005172", + "0x605917400c21600505500505200600621600505700505100605705500c", + "0x216005178005057006178005216005059005055006006216005174005172", + "0x1a00604c00521600504c00503100617a00521600505b00517400605b005", + "0x21600516800514800616200521600516200514600604a00521600504a005", + "0x601200617a16816204a04c01200517a00521600517a00514a006168005", + "0x604c00521600504c00503100605d005216005050005141006006216005", + "0x516800514800616200521600516200514600604a00521600504a00501a", + "0x1200605d16816204a04c01200505d00521600505d00514a006168005216", + "0x20800600621600502000520a00600621600502600506d006006216005006", + "0x18100521600518100502d00618100521600500605900617f005216005006", + "0x18500c13d00618500521600500613b00606100521600518117f00c02f006", + "0x5216005006005031006065005216005186005141006186005216005061", + "0x514800614b00521600514b00514600603c00521600503c00501a006006", + "0x6512514b03c00601200506500521600506500514a006125005216005125", + "0x621600520d00516800600621600520c005051006006216005006012006", + "0x521600500606700606700521600500620800600621600502000520a006", + "0x13b00606b00521600506906700c02f00606900521600506900502d006069", + "0x21600506d00514100606d00521600506b18a00c13d00618a005216005006", + "0x14600602300521600502300501a00600600521600500600503100618d005", + "0x21600518d00514a00612500521600512500514800601d00521600501d005", + "0x502100505100600621600500601200618d12501d02300601200518d005", + "0x50061780060ba00521600500620800600621600501e005168006006216", + "0x1960052160050700ba00c02f00607000521600507000502d006070005216", + "0x19a00514100619a00521600519607200c13d00607200521600500613b006", + "0x1200521600501200501a00600600521600500600503100619d005216005", + "0x19d00514a00612500521600512500514800601d00521600501d005146006", + "0x516800600621600500601200619d12501d01200601200519d005216005", + "0x2d0061a0005216005006059006076005216005006208006006216005010", + "0x21600500613b0061a10052160051a007600c02f0061a00052160051a0005", + "0x61a400521600507b00514100607b0052160051a11a200c13d0061a2005", + "0x501a00514600601900521600501900501a006006005216005006005031", + "0x51a40052160051a400514a00612500521600512500514800601a005216", + "0xc21600c00c00500c0100060062160050061250061a412501a019006012", + "0x1000521600501000501d00600621600500601200601a01900c23501d012", + "0x501e00601200521600501200501a0061e901e00c216005010005019006", + "0x21600501200501a00600621600500601200602100523602000521600c1e9", + "0x20d02312521600501e01200c06b00601e00521600501e00501d006012005", + "0x1e900600621600500601200620c00523702600521600c02500518a006025", + "0x21600502a00502100602a00521600502800502000602800521600520d005", + "0x502100620700521600500620d00600621600520a00502300620820a00c", + "0x521600520800502500600621600502d00502300602f02d00c216005207", + "0xc20c00613b00521600513b00502600613d00521600502f00502500613b", + "0x621600502600506d00600621600500601200600623800621600c13d13b", + "0x521600500620700614100521600500620800600621600502000520a006", + "0x13b00614600521600503114100c02f00603100521600503100502d006031", + "0x21600514a00514100614a00521600514614800c13d006148005216005006", + "0x14600602300521600502300501a006006005216005006005031006035005", + "0x21600503500514a00612500521600512500514800601d00521600501d005", + "0x21600500603500600621600500601200603512501d023006012005035005", + "0x1700c21600c03901d023125017006039005216005039005039006039005", + "0x3c00603d00521600500603a00600621600500601200614b03c00c23903a", + "0x614e00521600500603d00604000521600500614b00603f005216005006", + "0x15200521600500614e00604400521600500604000615000521600500603f", + "0x21600501700501a00604700521600515204415014e04003f03d019150006", + "0x14800600600521600500600503100603a00521600503a005146006017005", + "0x21600502600518d00602000521600502000502d006125005216005125005", + "0x4c16204a15e15601221600502602004712500603a01701907b006026005", + "0x506500600621600500601200604e00523a16800521600c04c005186006", + "0x17005000c21600516d00505200616d005216005006208006006216005168", + "0x5051005057006051005216005170005055006006216005050005172006", + "0x604a00521600504a005031006172005216005052005174006052005216", + "0x516200514800615e00521600515e00514600615600521600515600501a", + "0x1200617216215e15604a01200517200521600517200514a006162005216", + "0x4a00521600504a00503100605500521600504e005141006006216005006", + "0x16200514800615e00521600515e00514600615600521600515600501a006", + "0x605516215e15604a01200505500521600505500514a006162005216005", + "0x600621600502000520a00600621600502600506d006006216005006012", + "0x521600517400502d006174005216005006059006057005216005006208", + "0xc13d00617800521600500613b00605900521600517405700c02f006174", + "0x21600500600503100617a00521600505b00514100605b005216005059178", + "0x14800614b00521600514b00514600603c00521600503c00501a006006005", + "0x12514b03c00601200517a00521600517a00514a006125005216005125005", + "0x21600520d00516800600621600520c00505100600621600500601200617a", + "0x21600500606700605d00521600500620800600621600502000520a006006", + "0x618100521600517f05d00c02f00617f00521600517f00502d00617f005", + "0x518500514100618500521600518106100c13d00606100521600500613b", + "0x602300521600502300501a006006005216005006005031006186005216", + "0x518600514a00612500521600512500514800601d00521600501d005146", + "0x2100505100600621600500601200618612501d023006012005186005216", + "0x617800606500521600500620800600621600501e005168006006216005", + "0x521600506706500c02f00606700521600506700502d006067005216005", + "0x514100618a00521600506906b00c13d00606b00521600500613b006069", + "0x521600501200501a00600600521600500600503100606d00521600518a", + "0x514a00612500521600512500514800601d00521600501d005146006012", + "0x16800600621600500601200606d12501d01200601200506d00521600506d", + "0x60ba00521600500605900618d005216005006208006006216005010005", + "0x500613b0060700052160050ba18d00c02f0060ba0052160050ba00502d", + "0x19a00521600507200514100607200521600507019600c13d006196005216", + "0x1a00514600601900521600501900501a006006005216005006005031006", + "0x19a00521600519a00514a00612500521600512500514800601a005216005", + "0x21600c00c00500c01000600621600500612500619a12501a019006012005", + "0x521600501000501d00600621600500601200601a01900c23b01d01200c", + "0x1e00601200521600501200501a0061e901e00c216005010005019006010", + "0x501200501a00600621600500601200602100523c02000521600c1e9005", + "0x2312521600501e01200c06b00601e00521600501e00501d006012005216", + "0x600621600500601200620c00523d02600521600c02500518a00602520d", + "0x502a00502100602a00521600502800502000602800521600520d0051e9", + "0x2100620700521600500620d00600621600520a00502300620820a00c216", + "0x21600520800502500600621600502d00502300602f02d00c216005207005", + "0x20c00613b00521600513b00502600613d00521600502f00502500613b005", + "0x21600502600506d00600621600500601200600623e00621600c13d13b00c", + "0x21600500620700614100521600500620800600621600502000520a006006", + "0x614600521600503114100c02f00603100521600503100502d006031005", + "0x514a00514100614a00521600514614800c13d00614800521600500613b", + "0x602300521600502300501a006006005216005006005031006035005216", + "0x503500514a00612500521600512500514800601d00521600501d005146", + "0x500603500600621600500601200603512501d023006012005035005216", + "0xc21600c03901d023125017006039005216005039005039006039005216", + "0x603d00521600500603a00600621600500601200614b03c00c23f03a017", + "0x14e00521600500603d00604000521600500614b00603f00521600500603c", + "0x521600500614e00604400521600500604000615000521600500603f006", + "0x501700501a00604700521600515204415014e04003f03d019150006152", + "0x600600521600500600503100603a00521600503a005146006017005216", + "0x502600518d00602000521600502000502d006125005216005125005148", + "0x16204a15e15601221600502602004712500603a0170191a4006026005216", + "0x6500600621600500601200604e00524016800521600c04c00518600604c", + "0x5000c21600516d00505200616d005216005006208006006216005168005", + "0x51005057006051005216005170005055006006216005050005172006170", + "0x4a00521600504a005031006172005216005052005174006052005216005", + "0x16200514800615e00521600515e00514600615600521600515600501a006", + "0x617216215e15604a01200517200521600517200514a006162005216005", + "0x521600504a00503100605500521600504e005141006006216005006012", + "0x514800615e00521600515e00514600615600521600515600501a00604a", + "0x5516215e15604a01200505500521600505500514a006162005216005162", + "0x621600502000520a00600621600502600506d006006216005006012006", + "0x21600517400502d006174005216005006059006057005216005006208006", + "0x13d00617800521600500613b00605900521600517405700c02f006174005", + "0x500600503100617a00521600505b00514100605b00521600505917800c", + "0x614b00521600514b00514600603c00521600503c00501a006006005216", + "0x14b03c00601200517a00521600517a00514a006125005216005125005148", + "0x520d00516800600621600520c00505100600621600500601200617a125", + "0x500606700605d00521600500620800600621600502000520a006006216", + "0x18100521600517f05d00c02f00617f00521600517f00502d00617f005216", + "0x18500514100618500521600518106100c13d00606100521600500613b006", + "0x2300521600502300501a006006005216005006005031006186005216005", + "0x18600514a00612500521600512500514800601d00521600501d005146006", + "0x505100600621600500601200618612501d023006012005186005216005", + "0x17800606500521600500620800600621600501e005168006006216005021", + "0x21600506706500c02f00606700521600506700502d006067005216005006", + "0x14100618a00521600506906b00c13d00606b00521600500613b006069005", + "0x21600501200501a00600600521600500600503100606d00521600518a005", + "0x14a00612500521600512500514800601d00521600501d005146006012005", + "0x600621600500601200606d12501d01200601200506d00521600506d005", + "0xba00521600500605900618d005216005006208006006216005010005168", + "0x613b0060700052160050ba18d00c02f0060ba0052160050ba00502d006", + "0x521600507200514100607200521600507019600c13d006196005216005", + "0x514600601900521600501900501a00600600521600500600503100619a", + "0x521600519a00514a00612500521600512500514800601a00521600501a", + "0xc00c00500c01000600621600500612500619a12501a01900601200519a", + "0x21600501200501a00600621600500601200601a01900c24101d01200c216", + "0x1e901e12521600501001200c1a800601000521600501000501d006012005", + "0x1e900600621600500601200602300524202100521600c02000507e006020", + "0x21600502500502100602500521600520d00502000620d0052160051e9005", + "0x502100602800521600500620d00600621600502600502300620c02600c", + "0x521600520c00502500600621600502a00502300620a02a00c216005028", + "0xc20c00620800521600520800502600620700521600520a005025006208", + "0x62160050210051ab00600621600500601200600624300621600c207208", + "0x21600502f00502d00602f00521600500620700602d005216005006208006", + "0x13d00613d00521600500613b00613b00521600502f02d00c02f00602f005", + "0x500600503100603100521600514100514100614100521600513b13d00c", + "0x601d00521600501d00514600601e00521600501e00501a006006005216", + "0x1d01e00601200503100521600503100514a006125005216005125005148", + "0x5146005039006146005216005006035006006216005006012006031125", + "0x1200603903500c24414a14800c21600c14601d01e125017006146005216", + "0x14b00603a00521600500603c00601700521600500603a006006216005006", + "0x603d00521600500603f00614b00521600500603d00603c005216005006", + "0x14b03c03a01701915000604000521600500614e00603f005216005006040", + "0x514a00514600614800521600514800501a00614e00521600504003f03d", + "0x612500521600512500514800600600521600500600503100614a005216", + "0x15001221600502114e12500614a14801d08d00602100521600502100508c", + "0x21600500601200604a00524515e00521600c156005186006156047152044", + "0x516200505200616200521600500620800600621600515e005065006006", + "0x604e00521600516800505500600621600504c00517200616804c00c216", + "0x515200503100605000521600516d00517400616d00521600504e005057", + "0x604400521600504400514600615000521600515000501a006152005216", + "0x4415015201200505000521600505000514a006047005216005047005148", + "0x15200503100617000521600504a005141006006216005006012006050047", + "0x4400521600504400514600615000521600515000501a006152005216005", + "0x15015201200517000521600517000514a006047005216005047005148006", + "0x50062080060062160050210051ab006006216005006012006170047044", + "0x2f00605200521600505200502d006052005216005006059006051005216", + "0x517205500c13d00605500521600500613b00617200521600505205100c", + "0x6006005216005006005031006174005216005057005141006057005216", + "0x512500514800603900521600503900514600603500521600503500501a", + "0x1200617412503903500601200517400521600517400514a006125005216", + "0x2080060062160051e9005168006006216005023005051006006216005006", + "0x17800521600517800502d006178005216005006178006059005216005006", + "0x17a00c13d00617a00521600500613b00605b00521600517805900c02f006", + "0x521600500600503100617f00521600505d00514100605d00521600505b", + "0x514800601d00521600501d00514600601e00521600501e00501a006006", + "0x17f12501d01e00601200517f00521600517f00514a006125005216005125", + "0x181005216005006208006006216005010005168006006216005006012006", + "0x6118100c02f00606100521600506100502d006061005216005006059006", + "0x6500521600518518600c13d00618600521600500613b006185005216005", + "0x1900501a006006005216005006005031006067005216005065005141006", + "0x12500521600512500514800601a00521600501a005146006019005216005", + "0x21600500612500606712501a01900601200506700521600506700514a006", + "0x21600500601200601a01900c24601d01200c21600c00c00500c010006006", + "0x1a0061e901e00c21600501000501900601000521600501000501d006006", + "0x601200602100524702000521600c1e900501e006012005216005012005", + "0x620d00521600502300502000602300521600501e0051e9006006216005", + "0x21600500620d00600621600502500502300602602500c21600520d005021", + "0x2500600621600502800502300602a02800c21600520c00502100620c005", + "0x21600520a00502600620800521600502a00502500620a005216005026005", + "0x20a00600621600500601200600624800621600c20820a00c20c00620a005", + "0x602d005216005006207006207005216005006208006006216005020005", + "0x500613b00602f00521600502d20700c02f00602d00521600502d00502d", + "0x14100521600513d00514100613d00521600502f13b00c13d00613b005216", + "0x1d00514600601200521600501200501a006006005216005006005031006", + "0x14100521600514100514a00612500521600512500514800601d005216005", + "0x3100521600500603500600621600500601200614112501d012006012005", + "0x24914814600c21600c03101d012125017006031005216005031005039006", + "0x500603c00603900521600500603a00600621600500601200603514a00c", + "0x603f00603c00521600500603d00603a00521600500614b006017005216", + "0x15000603f00521600500614e00603d00521600500604000614b005216005", + "0x14e00c21600504000504400604000521600503f03d14b03c03a017039019", + "0x14800514600614600521600514600501a00600621600514e005152006150", + "0x125005216005125005148006006005216005006005031006148005216005", + "0x1221600502015012500614814601d08e00602000521600502000502d006", + "0x500601200616200524a04a00521600c15e00508f00615e156047152044", + "0x509100616800521600504a00509000604c005216005006208006006216", + "0x521600516d00508c00600621600504e0051ab00616d04e00c216005168", + "0x617005000c21600504c16d00c09200604c00521600504c00504e00616d", + "0x505100517200605205100c216005050005052006006216005170005051", + "0x174006055005216005172005057006172005216005052005055006006216", + "0x21600504400501a006047005216005047005031006057005216005055005", + "0x14a006156005216005156005148006152005216005152005146006044005", + "0x6006216005006012006057156152044047012005057005216005057005", + "0x504400501a006047005216005047005031006174005216005162005141", + "0x6156005216005156005148006152005216005152005146006044005216", + "0x621600500601200617415615204404701200517400521600517400514a", + "0x521600500605900605900521600500620800600621600502000520a006", + "0x13b00605b00521600517805900c02f00617800521600517800502d006178", + "0x21600505d00514100605d00521600505b17a00c13d00617a005216005006", + "0x14600614a00521600514a00501a00600600521600500600503100617f005", + "0x21600517f00514a006125005216005125005148006035005216005035005", + "0x502100505100600621600500601200617f12503514a00601200517f005", + "0x500617800618100521600500620800600621600501e005168006006216", + "0x18500521600506118100c02f00606100521600506100502d006061005216", + "0x6500514100606500521600518518600c13d00618600521600500613b006", + "0x1200521600501200501a006006005216005006005031006067005216005", + "0x6700514a00612500521600512500514800601d00521600501d005146006", + "0x516800600621600500601200606712501d012006012005067005216005", + "0x2d00606b005216005006059006069005216005006208006006216005010", + "0x21600500613b00618a00521600506b06900c02f00606b00521600506b005", + "0x60ba00521600518d00514100618d00521600518a06d00c13d00606d005", + "0x501a00514600601900521600501900501a006006005216005006005031", + "0x50ba0052160050ba00514a00612500521600512500514800601a005216", + "0xc21600c00c00500c0100060062160050061250060ba12501a019006012", + "0x1000521600501000501d00600621600500601200601a01900c24b01d012", + "0x501e00601200521600501200501a0061e901e00c216005010005019006", + "0x21600501200501a00600621600500601200602100524c02000521600c1e9", + "0x20d02312521600501e01200c1a800601e00521600501e00501d006012005", + "0x1e900600621600500601200620c00524d02600521600c02500507e006025", + "0x21600502a00502100602a00521600502800502000602800521600520d005", + "0x502100620700521600500620d00600621600520a00502300620820a00c", + "0x521600520800502500600621600502d00502300602f02d00c216005207", + "0xc20c00613b00521600513b00502600613d00521600502f00502500613b", + "0x62160050260051ab00600621600500601200600624e00621600c13d13b", + "0x521600500620700614100521600500620800600621600502000520a006", + "0x13b00614600521600503114100c02f00603100521600503100502d006031", + "0x21600514a00514100614a00521600514614800c13d006148005216005006", + "0x14600602300521600502300501a006006005216005006005031006035005", + "0x21600503500514a00612500521600512500514800601d00521600501d005", + "0x21600500603500600621600500601200603512501d023006012005035005", + "0x1700c21600c03901d023125017006039005216005039005039006039005", + "0x3c00603d00521600500603a00600621600500601200614b03c00c24f03a", + "0x614e00521600500603d00604000521600500614b00603f005216005006", + "0x15200521600500614e00604400521600500604000615000521600500603f", + "0x21600501700501a00604700521600515204415014e04003f03d019150006", + "0x14800600600521600500600503100603a00521600503a005146006017005", + "0x21600502600508c00602000521600502000502d006125005216005125005", + "0x4c16204a15e15601221600502602004712500603a017019093006026005", + "0x620800600621600500601200604e00525016800521600c04c005094006", + "0x621600505000515200617005000c21600516800509500616d005216005", + "0x5200518d00600621600505100506d00605205100c216005170005096006", + "0xc21600516d05200c1b500616d00521600516d00504e006052005216005", + "0x17200617405700c216005172005052006006216005055005051006055172", + "0x5216005059005057006059005216005174005055006006216005057005", + "0x501a00604a00521600504a00503100605b005216005178005174006178", + "0x521600516200514800615e00521600515e005146006156005216005156", + "0x500601200605b16215e15604a01200505b00521600505b00514a006162", + "0x1a00604a00521600504a00503100617a00521600504e005141006006216", + "0x21600516200514800615e00521600515e005146006156005216005156005", + "0x601200617a16215e15604a01200517a00521600517a00514a006162005", + "0x620800600621600502000520a0060062160050260051ab006006216005", + "0x617f00521600517f00502d00617f00521600500605900605d005216005", + "0x18106100c13d00606100521600500613b00618100521600517f05d00c02f", + "0x6005216005006005031006186005216005185005141006185005216005", + "0x12500514800614b00521600514b00514600603c00521600503c00501a006", + "0x618612514b03c00601200518600521600518600514a006125005216005", + "0x600621600520d00516800600621600520c005051006006216005006012", + "0x6700521600500606700606500521600500620800600621600502000520a", + "0x613b00606900521600506706500c02f00606700521600506700502d006", + "0x521600518a00514100618a00521600506906b00c13d00606b005216005", + "0x514600602300521600502300501a00600600521600500600503100606d", + "0x521600506d00514a00612500521600512500514800601d00521600501d", + "0x21600502100505100600621600500601200606d12501d02300601200506d", + "0x21600500617800618d00521600500620800600621600501e005168006006", + "0x60700052160050ba18d00c02f0060ba0052160050ba00502d0060ba005", + "0x507200514100607200521600507019600c13d00619600521600500613b", + "0x601200521600501200501a00600600521600500600503100619a005216", + "0x519a00514a00612500521600512500514800601d00521600501d005146", + "0x1000516800600621600500601200619a12501d01200601200519a005216", + "0x502d00607600521600500605900619d005216005006208006006216005", + "0x521600500613b0061a000521600507619d00c02f006076005216005076", + "0x3100607b0052160051a20051410061a20052160051a01a100c13d0061a1", + "0x21600501a00514600601900521600501900501a006006005216005006005", + "0x1200507b00521600507b00514a00612500521600512500514800601a005", + "0x1200c21600c00c00500c01000600621600500612500607b12501a019006", + "0x601200521600501200501a00600621600500601200601a01900c25101d", + "0x18a0060201e901e12521600501001200c06b00601000521600501000501d", + "0x501e00501a00600621600500601200602300525202100521600c020005", + "0x20d1252160051e901e00c1a80061e90052160051e900501d00601e005216", + "0x600621600500601200602800525320c00521600c02600507e006026025", + "0x520a00502100620a00521600502a00502000602a0052160050250051e9", + "0x2100602d00521600500620d00600621600520800502300620720800c216", + "0x21600520700502500600621600502f00502300613b02f00c21600502d005", + "0x20c00613d00521600513d00502600614100521600513b00502500613d005", + "0x21600520c0051ab00600621600500601200600625400621600c14113d00c", + "0x21600500620700603100521600500620800600621600502100506d006006", + "0x614800521600514603100c02f00614600521600514600502d006146005", + "0x503500514100603500521600514814a00c13d00614a00521600500613b", + "0x620d00521600520d00501a006006005216005006005031006039005216", + "0x503900514a00612500521600512500514800601d00521600501d005146", + "0x500603500600621600500601200603912501d20d006012005039005216", + "0xc21600c01701d20d125017006017005216005017005039006017005216", + "0x603f00521600500603a00600621600500601200603d14b00c25503c03a", + "0x15000521600500603d00614e00521600500614b00604000521600500603c", + "0x521600500614e00615200521600500604000604400521600500603f006", + "0x503a00501a00615600521600504715204415014e04003f019150006047", + "0x600600521600500600503100603c00521600503c00514600603a005216", + "0x520c00508c00602100521600502100518d006125005216005125005148", + "0x4c16204a15e01221600520c02115612500603c03a01909b00620c005216", + "0x20800600621600500601200616d00525604e00521600c16800509c006168", + "0x21600517000515200605117000c21600504e00505f006050005216005006", + "0x508c0060062160050520051ab00617205200c216005051005091006006", + "0x21600505017200c09200605000521600505000504e006172005216005172", + "0x605917400c21600505500505200600621600505700505100605705500c", + "0x216005178005057006178005216005059005055006006216005174005172", + "0x1a00616200521600516200503100617a00521600505b00517400605b005", + "0x21600504c00514800604a00521600504a00514600615e00521600515e005", + "0x601200617a04c04a15e16201200517a00521600517a00514a00604c005", + "0x616200521600516200503100605d00521600516d005141006006216005", + "0x504c00514800604a00521600504a00514600615e00521600515e00501a", + "0x1200605d04c04a15e16201200505d00521600505d00514a00604c005216", + "0x20800600621600502100506d00600621600520c0051ab006006216005006", + "0x18100521600518100502d00618100521600500605900617f005216005006", + "0x18500c13d00618500521600500613b00606100521600518117f00c02f006", + "0x5216005006005031006065005216005186005141006186005216005061", + "0x514800603d00521600503d00514600614b00521600514b00501a006006", + "0x6512503d14b00601200506500521600506500514a006125005216005125", + "0x6216005025005168006006216005028005051006006216005006012006", + "0x521600500606700606700521600500620800600621600502100506d006", + "0x13b00606b00521600506906700c02f00606900521600506900502d006069", + "0x21600506d00514100606d00521600506b18a00c13d00618a005216005006", + "0x14600620d00521600520d00501a00600600521600500600503100618d005", + "0x21600518d00514a00612500521600512500514800601d00521600501d005", + "0x502300505100600621600500601200618d12501d20d00601200518d005", + "0x50061780060ba0052160050062080060062160051e9005168006006216", + "0x1960052160050700ba00c02f00607000521600507000502d006070005216", + "0x19a00514100619a00521600519607200c13d00607200521600500613b006", + "0x1e00521600501e00501a00600600521600500600503100619d005216005", + "0x19d00514a00612500521600512500514800601d00521600501d005146006", + "0x516800600621600500601200619d12501d01e00601200519d005216005", + "0x2d0061a0005216005006059006076005216005006208006006216005010", + "0x21600500613b0061a10052160051a007600c02f0061a00052160051a0005", + "0x61a400521600507b00514100607b0052160051a11a200c13d0061a2005", + "0x501a00514600601900521600501900501a006006005216005006005031", + "0x51a40052160051a400514a00612500521600512500514800601a005216", + "0xc21600c00500600c0100060062160050061250061a412501a019006012", + "0x1a0052160051250051e900600621600500601200601901d00c257012010", + "0x50230060201e900c21600501e00502100601e00521600501a005020006", + "0x20d02300c21600502100502100602100521600500620d0060062160051e9", + "0x520d005025006025005216005020005025006006216005023005023006", + "0x601000521600501000501a006025005216005025005026006026005216", + "0x21600500620800600621600500601200600625800621600c02602500c20c", + "0xc02f00602800521600502800502d00602800521600500620700620c005", + "0x21600502a20a00c13d00620a00521600500613b00602a00521600502820c", + "0x14600601000521600501000501a006207005216005208005141006208005", + "0x21600520700514a00600c00521600500c005148006012005216005012005", + "0x521600500603500600621600500601200620700c012010010005207005", + "0x13b02f00c21600c02d01201012501700602d00521600502d00503900602d", + "0x603c00603100521600500603a00600621600500601200614113d00c259", + "0x3f00614a00521600500603d00614800521600500614b006146005216005", + "0x601700521600500614e006039005216005006040006035005216005006", + "0x521600502f00501a00603a00521600501703903514a148146031019150", + "0x1009f00600c00521600500c00514800613b00521600513b00514600602f", + "0x25a04000521600c03f00509700603f03d14b03c01021600503a00c13b02f", + "0x50400050a100615000521600500620800600621600500601200614e005", + "0x15604700c21600515200502100600621600504400515200615204400c216", + "0x515e0051bd00615e005216005156005025006006216005047005023006", + "0x4c00c21600516200505200616200521600504a15000c02f00604a005216", + "0x4e00505700604e00521600516800505500600621600504c005172006168", + "0x3c00521600503c00501a00605000521600516d00517400616d005216005", + "0x5000514a00603d00521600503d00514800614b00521600514b005146006", + "0x14e00514100600621600500601200605003d14b03c010005050005216005", + "0x14b00521600514b00514600603c00521600503c00501a006170005216005", + "0x14b03c01000517000521600517000514a00603d00521600503d005148006", + "0x21600500605900605100521600500620800600621600500601200617003d", + "0x617200521600505205100c02f00605200521600505200502d006052005", + "0x505700514100605700521600517205500c13d00605500521600500613b", + "0x614100521600514100514600613d00521600513d00501a006174005216", + "0xc14113d01000517400521600517400514a00600c00521600500c005148", + "0x5216005006208006006216005125005168006006216005006012006174", + "0x5900c02f00617800521600517800502d006178005216005006059006059", + "0x521600505b17a00c13d00617a00521600500613b00605b005216005178", + "0x514600601d00521600501d00501a00617f00521600505d00514100605d", + "0x521600517f00514a00600c00521600500c005148006019005216005019", + "0x621600500600c0060120052160050061be00617f00c01901d01000517f", + "0x1e01a00c25b01901d00c21600c00500600c010006006216005006125006", + "0x21600501900514600601d00521600501d00501a006006216005006012006", + "0x1e912521600512501901d1251c100612500521600512500501d006019005", + "0x600621600500601200620d00525c02300521600c0210050a6006021020", + "0x620c00525d01000521600c0260051bc00602602500c2160050230050a8", + "0x52160050200051460061e90052160051e900501a006006216005006012", + "0x5d00601000521600501001200c0aa00602500521600502500501d006020", + "0x525e20800521600c20a00517f00620a02a0281252160050250201e9125", + "0x2f00506100602f02d00c216005208005181006006216005006012006207", + "0x521600502d0051e900600621600500601200613d00525f13b00521600c", + "0x2300614814600c216005031005021006031005216005141005020006141", + "0x3500c21600514a00502100614a00521600500620d006006216005146005", + "0x39005025006017005216005148005025006006216005035005023006039", + "0x621600c03a01700c20c00601700521600501700502600603a005216005", + "0x501000517200600621600513b005168006006216005006012006006260", + "0x14b00502d00614b00521600500620700603c005216005006208006006216", + "0x3f00521600500613b00603d00521600514b03c00c02f00614b005216005", + "0x501a00614e00521600504000514100604000521600503d03f00c13d006", + "0x521600500c00514800602a00521600502a005146006028005216005028", + "0x21600500601200614e00c02a02801000514e00521600514e00514a00600c", + "0x28125017006150005216005150005039006150005216005006035006006", + "0x603a00600621600500601200615604700c26115204400c21600c15002a", + "0x3d00616200521600500614b00604a00521600500603c00615e005216005", + "0x604e00521600500604000616800521600500603f00604c005216005006", + "0x5000521600516d04e16804c16204a15e01915000616d00521600500614e", + "0x15200514600600621600517000515200605117000c216005050005044006", + "0x1000521600501000504e00600c00521600500c005148006152005216005", + "0x5212521600513b01005100c1520120ac00613b00521600513b00501d006", + "0x526205700521600c0550050b000604400521600504400501a006055172", + "0x52160050062080060062160050570050a9006006216005006012006174", + "0x505500600621600517800517200605b17800c216005059005052006059", + "0x521600505d00517400605d00521600517a00505700617a00521600505b", + "0x514800605200521600505200514600604400521600504400501a00617f", + "0x617f17205204401000517f00521600517f00514a006172005216005172", + "0x521600504400501a006181005216005174005141006006216005006012", + "0x514a006172005216005172005148006052005216005052005146006044", + "0x5168006006216005006012006181172052044010005181005216005181", + "0x5900606100521600500620800600621600501000517200600621600513b", + "0x21600518506100c02f00618500521600518500502d006185005216005006", + "0x14100606700521600518606500c13d00606500521600500613b006186005", + "0x21600515600514600604700521600504700501a006069005216005067005", + "0x1000506900521600506900514a00600c00521600500c005148006156005", + "0x516800600621600513d00505100600621600500601200606900c156047", + "0x6700606b00521600500620800600621600501000517200600621600502d", + "0x21600518a06b00c02f00618a00521600518a00502d00618a005216005006", + "0x1410060ba00521600506d18d00c13d00618d00521600500613b00606d005", + "0x21600502a00514600602800521600502800501a0060700052160050ba005", + "0x1000507000521600507000514a00600c00521600500c00514800602a005", + "0x514100600621600501000517200600621600500601200607000c02a028", + "0x521600502a00514600602800521600502800501a006196005216005207", + "0x2801000519600521600519600514a00600c00521600500c00514800602a", + "0x2500516800600621600520c00505100600621600500601200619600c02a", + "0x6178006072005216005006208006006216005012005098006006216005", + "0x521600519a07200c02f00619a00521600519a00502d00619a005216005", + "0x51410061a000521600519d07600c13d00607600521600500613b00619d", + "0x52160050200051460061e90052160051e900501a0061a10052160051a0", + "0x1e90100051a10052160051a100514a00600c00521600500c005148006020", + "0x20d0051410060062160050120050980060062160050060120061a100c020", + "0x200052160050200051460061e90052160051e900501a0061a2005216005", + "0x201e90100051a20052160051a200514a00600c00521600500c005148006", + "0x51250051680060062160050120050980060062160050060120061a200c", + "0x1a400502d0061a400521600500605900607b005216005006208006006216", + "0x7e00521600500613b0061a80052160051a407b00c02f0061a4005216005", + "0x501a00608c0052160051ab0051410061ab0052160051a807e00c13d006", + "0x521600500c00514800601e00521600501e00514600601a00521600501a", + "0x2160050060b200608c00c01e01a01000508c00521600508c00514a00600c", + "0x50060b200602100521600500605b0061e90052160050061b900601a005", + "0x1000500c01000600621600500612500600621600500600c00620d005216", + "0x501d00501d00600621600500601200602820c00c26302602500c21600c", + "0x2500521600502500501a00620a02a00c21600501d00501900601d005216", + "0x501a00600621600500601200620800526402000521600c20a00501e006", + "0x521600502a00501d006026005216005026005146006025005216005025", + "0x20712521600502a02602512505d00602000521600502002100c17a00602a", + "0x600621600500601200613d00526513b00521600c02f00517f00602f02d", + "0x614600526601900521600c03100506100603114100c21600513b005181", + "0x60062160050060b40061480052160051410051e9006006216005006012", + "0x3900526703514a00c21600c1480051b600601900521600501901a00c0b6", + "0x21600514a0051b40060170052160050350050b8006006216005006012006", + "0x50060120060062680050061b000603c0052160050170051b200603a005", + "0x51b400603d00521600514b0051ac00614b0052160050060bd006006216", + "0x521600c03c0051ae00603c00521600503d0051b200603a005216005039", + "0xc100614e00521600503f0050bf00600621600500601200604000526903f", + "0x21600515000502d00620700521600520700501a00615000521600514e005", + "0x1e00521600c1520051a700615204400c21600515020700c1aa006150005", + "0x503a0050550060062160050060c400600621600500601200604700526a", + "0x602d00521600502d00514600604400521600504400501a006156005216", + "0x4412505d00601e00521600501e1e900c0c600615600521600515600501d", + "0x616800526b04c00521600c16200517f00616204a15e12521600515602d", + "0x21600c16d00506100616d04e00c21600504c005181006006216005006012", + "0x615e00521600515e00501a00600621600500601200605000526c023005", + "0x2320d00c0b600604e00521600504e00501d00604a00521600504a005146", + "0x520050c800605205117012521600504e04a15e1251a5006023005216005", + "0xc2160051720051a300600621600500601200605500526d17200521600c", + "0x600621600500601200617800526e05900521600c17400519c006174057", + "0x517a00502100617a00521600505b00502000605b0052160050570051e9", + "0x2100618100521600500620d00600621600505d00502300617f05d00c216", + "0x21600517f00502500600621600506100502300618506100c216005181005", + "0x20c006186005216005186005026006065005216005185005025006186005", + "0x2160050590050ca00600621600500601200600626f00621600c06518600c", + "0x501900516800600621600501e0050cc006006216005023005168006006", + "0x500620700606700521600500620800600621600502000520a006006216", + "0x6b00521600506906700c02f00606900521600506900502d006069005216", + "0x6d00514100606d00521600506b18a00c13d00618a00521600500613b006", + "0x17000521600517000501a00600600521600500600503100618d005216005", + "0x5100514600612500521600512500519900600c00521600500c00519b006", + "0x18d00521600518d00514a006012005216005012005148006051005216005", + "0x21600500603500600621600500601200618d01205112500c170006019005", + "0x7000c21600c0ba0511701250170060ba0052160050ba0050390060ba005", + "0x3c00619d00521600500603a00600621600500601200619a07200c270196", + "0x61a100521600500603d0061a000521600500614b006076005216005006", + "0x1a400521600500614e00607b0052160050060400061a200521600500603f", + "0x21600507000501a0061a80052160051a407b1a21a11a007619d019150006", + "0x3100600c00521600500c00519b006196005216005196005146006070005", + "0x216005012005148006125005216005125005199006006005216005006005", + "0x19f00601900521600501900501d00602000521600502000502d006012005", + "0x2160050590050cf00602300521600502300501d00601e00521600501e005", + "0x1921600505902301e0190201a801212500600c1960700210d1006059005", + "0x1200609200527109100521600c09000518600609008f08e08d08c1ab07e", + "0x52006093005216005006208006006216005091005065006006216005006", + "0x21600509500505500600621600509400517200609509400c216005093005", + "0x3100609b0052160051b50051740061b5005216005096005057006096005", + "0x21600508c00519b00607e00521600507e00501a00608d00521600508d005", + "0x1480061ab0052160051ab00514600608e00521600508e00519900608c005", + "0x8e08c07e08d01900509b00521600509b00514a00608f00521600508f005", + "0x503100609c00521600509200514100600621600500601200609b08f1ab", + "0x521600508c00519b00607e00521600507e00501a00608d00521600508d", + "0x51480061ab0052160051ab00514600608e00521600508e00519900608c", + "0x1ab08e08c07e08d01900509c00521600509c00514a00608f00521600508f", + "0x50230051680060062160050590050ca00600621600500601200609c08f", + "0x2000520a00600621600501900516800600621600501e0050cc006006216", + "0x502d00609f00521600500605900605f005216005006208006006216005", + "0x521600500613b00609700521600509f05f00c02f00609f00521600509f", + "0x310061be0052160051bd0051410061bd0052160050970a100c13d0060a1", + "0x21600500c00519b00607200521600507200501a006006005216005006005", + "0x14800619a00521600519a00514600612500521600512500519900600c005", + "0x12500c0720060190051be0052160051be00514a006012005216005012005", + "0x570051680060062160051780050510060062160050060120061be01219a", + "0x516800600621600501e0050cc006006216005023005168006006216005", + "0x1950061c100521600500620800600621600502000520a006006216005019", + "0x2160050a61c100c02f0060a60052160050a600502d0060a6005216005006", + "0x1410060aa0052160050a81bc00c13d0061bc00521600500613b0060a8005", + "0x21600517000501a0060060052160050060050310060ac0052160050aa005", + "0x14600612500521600512500519900600c00521600500c00519b006170005", + "0x2160050ac00514a006012005216005012005148006051005216005051005", + "0x520a0060062160050060120060ac01205112500c1700060190050ac005", + "0x16800600621600501e0050cc006006216005023005168006006216005020", + "0x52160050060050310060b0005216005055005141006006216005019005", + "0x519900600c00521600500c00519b00617000521600517000501a006006", + "0x5216005012005148006051005216005051005146006125005216005125", + "0x120060b001205112500c1700060190050b00052160050b000514a006012", + "0xcc006006216005019005168006006216005050005051006006216005006", + "0x600621600504e00516800600621600502000520a00600621600501e005", + "0x980052160050060d20060a900521600500620800600621600520d005193", + "0x613b0060b20052160050980a900c02f00609800521600509800502d006", + "0x52160050b40051410060b40052160050b21b900c13d0061b9005216005", + "0x519b00615e00521600515e00501a0060060052160050060050310060b6", + "0x521600504a00514600612500521600512500519900600c00521600500c", + "0x60190050b60052160050b600514a00601200521600501200514800604a", + "0x60062160050190051680060062160050060120060b601204a12500c15e", + "0x621600520d00519300600621600502000520a00600621600501e0050cc", + "0x15e00501a0060060052160050060050310061b6005216005168005141006", + "0x12500521600512500519900600c00521600500c00519b00615e005216005", + "0x1b600514a00601200521600501200514800604a00521600504a005146006", + "0x60062160050060120061b601204a12500c15e0060190051b6005216005", + "0x621600503a0050d4006006216005019005168006006216005047005051", + "0x2160051e900518e00600621600520d00519300600621600502000520a006", + "0x2160050060120060062720050061b00060b800521600504400501a006006", + "0x503a0050d4006006216005019005168006006216005040005051006006", + "0x1e900518e00600621600520d00519300600621600502000520a006006216", + "0x62080060062160050060c40060b800521600520700501a006006216005", + "0x61b20052160051b200502d0061b20052160050060d50061b4005216005", + "0x1b00bd00c13d0060bd00521600500613b0061b00052160051b21b400c02f", + "0x60052160050060050310061ae0052160051ac0051410061ac005216005", + "0x12500519900600c00521600500c00519b0060b80052160050b800501a006", + "0x1200521600501200514800602d00521600502d005146006125005216005", + "0x60120061ae01202d12500c0b80060190051ae0052160051ae00514a006", + "0x520a006006216005141005168006006216005146005051006006216005", + "0x1930060062160051e900518e00600621600520d005193006006216005020", + "0x60c10052160050060670060bf00521600500620800600621600501a005", + "0x500613b0061aa0052160050c10bf00c02f0060c10052160050c100502d", + "0xc60052160050c40051410060c40052160051aa1a700c13d0061a7005216", + "0xc00519b00620700521600520700501a006006005216005006005031006", + "0x2d00521600502d00514600612500521600512500519900600c005216005", + "0x2070060190050c60052160050c600514a006012005216005012005148006", + "0x20a00600621600501a0051930060062160050060120060c601202d12500c", + "0x60062160051e900518e00600621600520d005193006006216005020005", + "0x520700501a0060060052160050060050310061a500521600513d005141", + "0x612500521600512500519900600c00521600500c00519b006207005216", + "0x51a500514a00601200521600501200514800602d00521600502d005146", + "0x510060062160050060120061a501202d12500c2070060190051a5005216", + "0x60062160051e900518e00600621600501a005193006006216005208005", + "0x621600502100506900600621600502a00516800600621600520d005193", + "0x2160051a300502d0061a30052160050061780060c8005216005006208006", + "0x13d0060ca00521600500613b00619c0052160051a30c800c02f0061a3005", + "0x500600503100619b0052160050cc0051410060cc00521600519c0ca00c", + "0x600c00521600500c00519b00602500521600502500501a006006005216", + "0x5012005148006026005216005026005146006125005216005125005199", + "0x19b01202612500c02500601900519b00521600519b00514a006012005216", + "0x62160051e900518e00600621600501a005193006006216005006012006", + "0x21600502100506900600621600520d00519300600621600501d005168006", + "0x519f00502d00619f005216005006059006199005216005006208006006", + "0x60d100521600500613b0060cf00521600519f19900c02f00619f005216", + "0x60050310061930052160051950051410061950052160050cf0d100c13d", + "0xc00521600500c00519b00620c00521600520c00501a006006005216005", + "0x12005148006028005216005028005146006125005216005125005199006", + "0x1202812500c20c00601900519300521600519300514a006012005216005", + "0x21600500600c0061e900521600500605b00601a0052160050060b2006193", + "0x2300c27302102000c21600c01000500c010006006216005006125006006", + "0x501d00501900601d00521600501d00501d00600621600500601200620d", + "0x1e00521600c02600501e00602000521600502000501a00602602500c216", + "0x514600602000521600502000501a00600621600500601200620c005274", + "0x21600501e1e900c17a00602500521600502500501d006021005216005021", + "0x21600c20a00517f00620a02a02812521600502502102012505d00601e005", + "0x2f02d00c216005208005181006006216005006012006207005275208005", + "0x501a00600621600500601200613b00527601900521600c02f005061006", + "0x521600502d00501d00602a00521600502a005146006028005216005028", + "0x13d12521600502d02a0281251a500601900521600501901a00c0b600602d", + "0x600621600500601200614800527714600521600c0310050c8006031141", + "0x601700527803900521600c03500519c00603514a00c2160051460051a3", + "0x521600503a00502000603a00521600514a0051e9006006216005006012", + "0x620d00600621600514b00502300603d14b00c21600503c00502100603c", + "0x621600504000502300614e04000c21600503f00502100603f005216005", + "0x15000502600604400521600514e00502500615000521600503d005025006", + "0x621600500601200600627900621600c04415000c20c006150005216005", + "0x21600501e00520a0060062160050190051680060062160050390050ca006", + "0x504700502d006047005216005006207006152005216005006208006006", + "0x615e00521600500613b00615600521600504715200c02f006047005216", + "0x600503100616200521600504a00514100604a00521600515615e00c13d", + "0xc00521600500c00519b00613d00521600513d00501a006006005216005", + "0x12005148006141005216005141005146006125005216005125005199006", + "0x1214112500c13d00601900516200521600516200514a006012005216005", + "0x21600504c00503900604c005216005006035006006216005006012006162", + "0x601200605016d00c27a04e16800c21600c04c14113d12501700604c005", + "0x614b00605100521600500603c00617000521600500603a006006216005", + "0x4000605500521600500603f00617200521600500603d006052005216005", + "0x5517205205117001915000617400521600500614e006057005216005006", + "0x21600504e00514600616800521600516800501a006059005216005174057", + "0x19900600600521600500600503100600c00521600500c00519b00604e005", + "0x21600501e00502d006012005216005012005148006125005216005125005", + "0x1970060390052160050390050cf00601900521600501900501d00601e005", + "0x18117f05d17a05b17801921600503901901e05901212500600c04e1681e9", + "0x6500600621600500601200618600527b18500521600c061005186006061", + "0x6700c216005065005052006065005216005006208006006216005185005", + "0x6b00505700606b005216005069005055006006216005067005172006069", + "0x5d00521600505d00503100606d00521600518a00517400618a005216005", + "0x17f00519900617a00521600517a00519b00617800521600517800501a006", + "0x18100521600518100514800605b00521600505b00514600617f005216005", + "0x601200606d18105b17f17a17805d01900506d00521600506d00514a006", + "0x605d00521600505d00503100618d005216005186005141006006216005", + "0x517f00519900617a00521600517a00519b00617800521600517800501a", + "0x618100521600518100514800605b00521600505b00514600617f005216", + "0x500601200618d18105b17f17a17805d01900518d00521600518d00514a", + "0x1e00520a0060062160050190051680060062160050390050ca006006216", + "0x502d0060700052160050060590060ba005216005006208006006216005", + "0x521600500613b0061960052160050700ba00c02f006070005216005070", + "0x3100619d00521600519a00514100619a00521600519607200c13d006072", + "0x21600500c00519b00616d00521600516d00501a006006005216005006005", + "0x14800605000521600505000514600612500521600512500519900600c005", + "0x12500c16d00601900519d00521600519d00514a006012005216005012005", + "0x14a00516800600621600501700505100600621600500601200619d012050", + "0x620800600621600501e00520a006006216005019005168006006216005", + "0x61a00052160051a000502d0061a00052160050060d5006076005216005", + "0x1a11a200c13d0061a200521600500613b0061a10052160051a007600c02f", + "0x60052160050060050310061a400521600507b00514100607b005216005", + "0x12500519900600c00521600500c00519b00613d00521600513d00501a006", + "0x12005216005012005148006141005216005141005146006125005216005", + "0x60120061a401214112500c13d0060190051a40052160051a400514a006", + "0x514100600621600501900516800600621600501e00520a006006216005", + "0x521600513d00501a0060060052160050060050310061a8005216005148", + "0x514600612500521600512500519900600c00521600500c00519b00613d", + "0x52160051a800514a006012005216005012005148006141005216005141", + "0x13b0050510060062160050060120061a801214112500c13d0060190051a8", + "0x519300600621600502d00516800600621600501e00520a006006216005", + "0x2d0061ab00521600500606700607e00521600500620800600621600501a", + "0x21600500613b00608c0052160051ab07e00c02f0061ab0052160051ab005", + "0x608f00521600508e00514100608e00521600508c08d00c13d00608d005", + "0x500c00519b00602800521600502800501a006006005216005006005031", + "0x602a00521600502a00514600612500521600512500519900600c005216", + "0xc02800601900508f00521600508f00514a006012005216005012005148", + "0x519300600621600501e00520a00600621600500601200608f01202a125", + "0x600521600500600503100609000521600520700514100600621600501a", + "0x12500519900600c00521600500c00519b00602800521600502800501a006", + "0x1200521600501200514800602a00521600502a005146006125005216005", + "0x601200609001202a12500c02800601900509000521600509000514a006", + "0x516800600621600501a00519300600621600520c005051006006216005", + "0x1780060910052160050062080060062160051e9005069006006216005025", + "0x21600509209100c02f00609200521600509200502d006092005216005006", + "0x14100609500521600509309400c13d00609400521600500613b006093005", + "0x21600502000501a006006005216005006005031006096005216005095005", + "0x14600612500521600512500519900600c00521600500c00519b006020005", + "0x21600509600514a006012005216005012005148006021005216005021005", + "0x519300600621600500601200609601202112500c020006019005096005", + "0x2080060062160051e900506900600621600501d00516800600621600501a", + "0x9b00521600509b00502d00609b0052160050060590061b5005216005006", + "0x5f00c13d00605f00521600500613b00609c00521600509b1b500c02f006", + "0x521600500600503100609700521600509f00514100609f00521600509c", + "0x519900600c00521600500c00519b00602300521600502300501a006006", + "0x521600501200514800620d00521600520d005146006125005216005125", + "0xd700609701220d12500c02300601900509700521600509700514a006012", + "0x60200052160050060d900601e005216005006005006019005216005006", + "0x20c00521600500605b0060250052160050060b20060230052160050061b9", + "0x600621600500612500600621600500600c00602a005216005006189006", + "0x600621600500601200602d20700c27c20820a00c21600c12500600c010", + "0x20a00501a00613b02f00c21600501200501900601200521600501200501d", + "0x21600500601200613d00527d02600521600c13b00501e00620a005216005", + "0x501d00620800521600520800514600620a00521600520a00501a006006", + "0x2f20820a12505d00602600521600502620c00c17a00602f00521600502f", + "0x601200614a00527e14800521600c14600517f006146031141125216005", + "0x20d00521600c03900506100603903500c216005148005181006006216005", + "0x60b400603a0052160050350051e900600621600500601200601700527f", + "0x3c00c21600c03a0051b600620d00521600520d02500c0b6006006216005", + "0x1b400603f00521600514b0050b800600621600500601200603d00528014b", + "0x62810050061b000614e00521600503f0051b200604000521600503c005", + "0x52160051500051ac0061500052160050060bd006006216005006012006", + "0x51ae00614e0052160050440051b200604000521600503d0051b4006044", + "0x2160051520050bf00600621600500601200604700528215200521600c14e", + "0x2d00614100521600514100501a00615e0052160051560050c1006156005", + "0x1620051a700616204a00c21600515e14100c1aa00615e00521600515e005", + "0x521600504000505500600621600500601200604c00528302100521600c", + "0xc0c600604e00521600504e0051b400604e0052160051680051e9006168", + "0x1200617000528405016d00c21600c04e0051b6006021005216005021023", + "0x5200521600516d0051b40060510052160050500050b8006006216005006", + "0x62160050060120060062850050061b00061720052160050510051b2006", + "0x51700051b40060570052160050550051ac0060550052160050060bd006", + "0x28617400521600c1720051ae0061720052160050570051b2006052005216", + "0x1780050c10061780052160051740050bf006006216005006012006059005", + "0x5b00521600505b00502d00604a00521600504a00501a00605b005216005", + "0x528702800521600c05d0050dd00605d17a00c21600505b04a00c0db006", + "0x52160050520050550060062160050060c400600621600500601200617f", + "0x501d00603100521600503100514600617a00521600517a00501a006181", + "0x18103117a1251a500602800521600502802a00c187006181005216005181", + "0x601200606700528806500521600c1860050c8006186185061125216005", + "0x18a00521600c06b00519c00606b06900c2160050650051a3006006216005", + "0x502000618d0052160050690051e900600621600500601200606d005289", + "0x21600507000502300619607000c2160050ba0050210060ba00521600518d", + "0x502300619d19a00c21600507200502100607200521600500620d006006", + "0x1a000521600519d00502500607600521600519600502500600621600519a", + "0x1200600628a00621600c1a007600c20c006076005216005076005026006", + "0x2a0060062160050190050df006006216005020005184006006216005006", + "0x600621600502800502300600621600518a0050ca00600621600501e005", + "0x621600502600520a00600621600520d0051680060062160050210050cc", + "0x2160051a200502d0061a20052160050062070061a1005216005006208006", + "0x13d0061a400521600500613b00607b0052160051a21a100c02f0061a2005", + "0x506100501a00607e0052160051a80051410061a800521600507b1a400c", + "0x600c00521600500c00519900600500521600500500519b006061005216", + "0x507e00514a006010005216005010005148006185005216005185005146", + "0x603500600621600500601200607e01018500c00506101d00507e005216", + "0x21600c1ab1850611250170061ab0052160051ab0050390061ab005216005", + "0x9000521600500603a00600621600500601200608f08e00c28b08d08c00c", + "0x521600500603d00609200521600500614b00609100521600500603c006", + "0x21600500614e00609500521600500604000609400521600500603f006093", + "0x1b50050440061b5005216005096095094093092091090019150006096005", + "0x8c00521600508c00501a00600621600509b00515200609c09b00c216005", + "0xc00519900600500521600500500519b00608d00521600508d005146006", + "0x2600521600502600502d00601000521600501000514800600c005216005", + "0x2800502600602100521600502100519f00620d00521600520d00501d006", + "0x1000c00508d08c0200e100618a00521600518a0050cf006028005216005", + "0x1e902000c18200609701a01d1e909f05f01d21600518a02802120d02609c", + "0x21600501a01e00c15e00601d00521600501d01900c0e30061e9005216005", + "0x60062160050060120061bd00528c0a100521600c09700504a00601a005", + "0x2160051c100504c0061c10052160050a10051620061be005216005006208", + "0x14600605f00521600505f00501a0060062160050a60051680060a80a600c", + "0x2160051be00504e0060a80052160050a800501d00609f00521600509f005", + "0xc0ac0050500060ac0aa1bc1252160051be0a809f05f01016d0061be005", + "0x9800c2160050b00051700060062160050060120060a900528d0b0005216", + "0x51720060b41b900c2160050980050520060062160050b20050510060b2", + "0x1b60052160050b60050570060b60052160050b40050550060062160051b9", + "0x1e900519b0061bc0052160051bc00501a0060b80052160051b6005174006", + "0xaa0052160050aa00514600601d00521600501d0051990061e9005216005", + "0x1e91bc01d0050b80052160050b800514a00601a00521600501a005148006", + "0x1a0061b40052160050a90051410060062160050060120060b801a0aa01d", + "0x21600501d0051990061e90052160051e900519b0061bc0052160051bc005", + "0x14a00601a00521600501a0051480060aa0052160050aa00514600601d005", + "0x62160050060120061b401a0aa01d1e91bc01d0051b40052160051b4005", + "0x1e900519b00605f00521600505f00501a0061b20052160051bd005141006", + "0x9f00521600509f00514600601d00521600501d0051990061e9005216005", + "0x1e905f01d0051b20052160051b200514a00601a00521600501a005148006", + "0x50df0060062160050200051840060062160050060120061b201a09f01d", + "0x2300600621600518a0050ca00600621600501e00502a006006216005019", + "0x600621600520d0051680060062160050210050cc006006216005028005", + "0xbd0052160050060590061b000521600500620800600621600502600520a", + "0x613b0061ac0052160050bd1b000c02f0060bd0052160050bd00502d006", + "0x52160050bf0051410060bf0052160051ac1ae00c13d0061ae005216005", + "0x519900600500521600500500519b00608e00521600508e00501a0060c1", + "0x521600501000514800608f00521600508f00514600600c00521600500c", + "0x60120060c101008f00c00508e01d0050c10052160050c100514a006010", + "0x50df00600621600502000518400600621600506d005051006006216005", + "0x2300600621600506900516800600621600501e00502a006006216005019", + "0x600621600520d0051680060062160050210050cc006006216005028005", + "0x1a70052160050061950061aa00521600500620800600621600502600520a", + "0x613b0060c40052160051a71aa00c02f0061a70052160051a700502d006", + "0x52160051a50051410061a50052160050c40c600c13d0060c6005216005", + "0x519900600500521600500500519b00606100521600506100501a0060c8", + "0x521600501000514800618500521600518500514600600c00521600500c", + "0x60120060c801018500c00506101d0050c80052160050c800514a006010", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0xcc00600621600502800502300600621600502600520a00600621600501e", + "0x1a300521600506700514100600621600520d005168006006216005021005", + "0xc00519900600500521600500500519b00606100521600506100501a006", + "0x1000521600501000514800618500521600518500514600600c005216005", + "0x50060120061a301018500c00506101d0051a30052160051a300514a006", + "0x20d0051680060062160050210050cc00600621600517f005051006006216", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0x1800060062160050520050d400600621600502600520a00600621600501e", + "0x600628e0050061b000619c00521600517a00501a00600621600502a005", + "0x60062160050210050cc006006216005059005051006006216005006012", + "0x62160050190050df00600621600502000518400600621600520d005168", + "0x2160050520050d400600621600502600520a00600621600501e00502a006", + "0x50060c400619c00521600504a00501a00600621600502a005180006006", + "0xcc00502d0060cc0052160050060d20060ca005216005006208006006216", + "0x19900521600500613b00619b0052160050cc0ca00c02f0060cc005216005", + "0x501a0060cf00521600519f00514100619f00521600519b19900c13d006", + "0x521600500c00519900600500521600500500519b00619c00521600519c", + "0x514a00601000521600501000514800603100521600503100514600600c", + "0x60062160050060120060cf01003100c00519c01d0050cf0052160050cf", + "0x621600520d0051680060062160050400050d400600621600504c005051", + "0x21600501e00502a0060062160050190050df006006216005020005184006", + "0x502300518e00600621600502a00518000600621600502600520a006006", + "0x500601200600628f0050061b00060d100521600504a00501a006006216", + "0x20d0051680060062160050400050d4006006216005047005051006006216", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0x18000600621600502300518e00600621600502600520a00600621600501e", + "0x60062160050060c40060d100521600514100501a00600621600502a005", + "0x521600519300502d0061930052160050060d5006195005216005006208", + "0xc13d0060d400521600500613b0060d200521600519319500c02f006193", + "0x2160050d100501a0060d500521600518e00514100618e0052160050d20d4", + "0x14600600c00521600500c00519900600500521600500500519b0060d1005", + "0x2160050d500514a006010005216005010005148006031005216005031005", + "0x170050510060062160050060120060d501003100c0050d101d0050d5005", + "0x50df006006216005020005184006006216005035005168006006216005", + "0x18e00600621600502600520a00600621600501e00502a006006216005019", + "0x600621600502500519300600621600502a005180006006216005023005", + "0x52160050d700502d0060d7005216005006067006197005216005006208", + "0xc13d00618900521600500613b0060d90052160050d719700c02f0060d7", + "0x21600514100501a0060dd0052160050db0051410060db0052160050d9189", + "0x14600600c00521600500c00519900600500521600500500519b006141005", + "0x2160050dd00514a006010005216005010005148006031005216005031005", + "0x250051930060062160050060120060dd01003100c00514101d0050dd005", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0x18000600621600502300518e00600621600502600520a00600621600501e", + "0x521600514100501a00618700521600514a00514100600621600502a005", + "0x514600600c00521600500c00519900600500521600500500519b006141", + "0x521600518700514a006010005216005010005148006031005216005031", + "0x513d00505100600621600500601200618701003100c00514101d005187", + "0x2000518400600621600502500519300600621600502a005180006006216", + "0x518e00600621600501e00502a0060062160050190050df006006216005", + "0x20800600621600520c00506900600621600502f005168006006216005023", + "0xdf0052160050df00502d0060df005216005006178006184005216005006", + "0x18200c13d00618200521600500613b0060e10052160050df18400c02f006", + "0x521600520a00501a0061800052160050e30051410060e30052160050e1", + "0x514600600c00521600500c00519900600500521600500500519b00620a", + "0x521600518000514a006010005216005010005148006208005216005208", + "0x502a00518000600621600500601200618001020800c00520a01d005180", + "0x190050df006006216005020005184006006216005025005193006006216", + "0x518e00600621600501200516800600621600501e00502a006006216005", + "0x590060e500521600500620800600621600520c005069006006216005023", + "0x2160051790e500c02f00617900521600517900502d006179005216005006", + "0x1410061730052160050e717600c13d00617600521600500613b0060e7005", + "0x21600500500519b00620700521600520700501a0060e9005216005173005", + "0x14800602d00521600502d00514600600c00521600500c005199006005005", + "0x2d00c00520701d0050e90052160050e900514a006010005216005010005", + "0x50060d900601e0052160050060050060190052160050060d70060e9010", + "0x605b0060250052160050060e50060230052160050060b2006020005216", + "0x612500600621600500600c00602a00521600500618900620c005216005", + "0x601200602d20700c29020820a00c21600c12500600c010006006216005", + "0x13b02f00c21600501200501900601200521600501200501d006006216005", + "0x613d00529102600521600c13b00501e00620a00521600520a00501a006", + "0xc21600502f00517900602f00521600502f00501d006006216005006012", + "0x29220d00521600c0310050e700602600521600502620c00c17a006031141", + "0x20800514600620a00521600520a00501a006006216005006012006146005", + "0x521600520d02500c17600614100521600514100501d006208005216005", + "0x521600c03500517f00603514a14812521600514120820a12505d00620d", + "0x603c03a00c216005039005181006006216005006012006017005293039", + "0x3a0051e900600621600500601200614b00529402100521600c03c005061", + "0x602100521600502102300c0b60060062160050060b400603d005216005", + "0x50b800600621600500601200614e00529504003f00c21600c03d0051b6", + "0x52160051500051b200604400521600503f0051b4006150005216005040", + "0x470052160050060bd0060062160050060120060062960050061b0006152", + "0x1560051b200604400521600514e0051b40061560052160050470051ac006", + "0x21600500601200604a00529715e00521600c1520051ae006152005216005", + "0x501a00604c0052160051620050c100616200521600515e0050bf006006", + "0x21600504c14800c0db00604c00521600504c00502d006148005216005148", + "0x621600500601200616d00529802800521600c04e0050dd00604e16800c", + "0x21600516800501a0060500052160050440050550060062160050060c4006", + "0x18700605000521600505000501d00614a00521600514a005146006168005", + "0x605205117012521600505014a1681251a500602800521600502802a00c", + "0x1720051a300600621600500601200605500529917200521600c0520050c8", + "0x500601200617800529a05900521600c17400519c00617405700c216005", + "0x2100617a00521600505b00502000605b0052160050570051e9006006216", + "0x521600500620d00600621600505d00502300617f05d00c21600517a005", + "0x502500600621600506100502300618506100c216005181005021006181", + "0x521600518600502600606500521600518500502500618600521600517f", + "0x518400600621600500601200600629b00621600c06518600c20c006186", + "0xca00600621600501e00502a0060062160050190050df006006216005020", + "0x6006216005021005168006006216005028005023006006216005059005", + "0x6700521600500620800600621600502600520a00600621600520d005173", + "0x6906700c02f00606900521600506900502d006069005216005006207006", + "0x6d00521600506b18a00c13d00618a00521600500613b00606b005216005", + "0x500519b00617000521600517000501a00618d00521600506d005141006", + "0x5100521600505100514600600c00521600500c005199006005005216005", + "0x517001d00518d00521600518d00514a006010005216005010005148006", + "0x50390060ba00521600500603500600621600500601200618d01005100c", + "0x19a07200c29c19607000c21600c0ba0511701250170060ba0052160050ba", + "0x7600521600500603c00619d00521600500603a006006216005006012006", + "0x521600500603f0061a100521600500603d0061a000521600500614b006", + "0x7619d0191500061a400521600500614e00607b0052160050060400061a2", + "0x1520061ab07e00c2160051a80050440061a80052160051a407b1a21a11a0", + "0x521600519600514600607000521600507000501a00600621600507e005", + "0x514800600c00521600500c00519900600500521600500500519b006196", + "0x521600520d0050e900602600521600502600502d006010005216005010", + "0x50cf00602800521600502800502600602100521600502100501d00620d", + "0x505902802120d0261ab01000c0051960700200eb006059005216005059", + "0xc0e30061e90052160051e902000c18200608e01a01d1e908d08c01d216", + "0xc08e00516f00601a00521600501a01e00c15e00601d00521600501d019", + "0x609100521600500620800600621600500601200609000529d08f005216", + "0x9300516900609409300c21600509200517100609200521600508f00516e", + "0x608d00521600508d00514600608c00521600508c00501a006006216005", + "0x8d08c0100ef00609100521600509100504e00609400521600509400516c", + "0x609c00529e09b00521600c1b50050500061b5096095125216005091094", + "0x21600509f00505100609f05f00c21600509b005170006006216005006012", + "0x50550060062160050970051720060a109700c21600505f005052006006", + "0x52160051be0051740061be0052160051bd0050570061bd0052160050a1", + "0x51990061e90052160051e900519b00609500521600509500501a0061c1", + "0x521600501a00514800609600521600509600514600601d00521600501d", + "0x60120061c101a09601d1e909501d0051c10052160051c100514a00601a", + "0x609500521600509500501a0060a600521600509c005141006006216005", + "0x509600514600601d00521600501d0051990061e90052160051e900519b", + "0x50a60052160050a600514a00601a00521600501a005148006096005216", + "0x52160050900051410060062160050060120060a601a09601d1e909501d", + "0x51990061e90052160051e900519b00608c00521600508c00501a0060a8", + "0x521600501a00514800608d00521600508d00514600601d00521600501d", + "0x60120060a801a08d01d1e908c01d0050a80052160050a800514a00601a", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0x1680060062160050280050230060062160050590050ca00600621600501e", + "0x600621600502600520a00600621600520d005173006006216005021005", + "0x52160050aa00502d0060aa0052160050060590061bc005216005006208", + "0xc13d0060b000521600500613b0060ac0052160050aa1bc00c02f0060aa", + "0x21600507200501a0060980052160050a90051410060a90052160050ac0b0", + "0x14600600c00521600500c00519900600500521600500500519b006072005", + "0x21600509800514a00601000521600501000514800619a00521600519a005", + "0x17800505100600621600500601200609801019a00c00507201d005098005", + "0x502a0060062160050190050df006006216005020005184006006216005", + "0x16800600621600502800502300600621600505700516800600621600501e", + "0x600621600502600520a00600621600520d005173006006216005021005", + "0x52160051b900502d0061b90052160050061950060b2005216005006208", + "0xc13d0060b600521600500613b0060b40052160051b90b200c02f0061b9", + "0x21600517000501a0060b80052160051b60051410061b60052160050b40b6", + "0x14600600c00521600500c00519900600500521600500500519b006170005", + "0x2160050b800514a006010005216005010005148006051005216005051005", + "0x200051840060062160050060120060b801005100c00517001d0050b8005", + "0x520a00600621600501e00502a0060062160050190050df006006216005", + "0x173006006216005021005168006006216005028005023006006216005026", + "0x521600517000501a0061b400521600505500514100600621600520d005", + "0x514600600c00521600500c00519900600500521600500500519b006170", + "0x52160051b400514a006010005216005010005148006051005216005051", + "0x516d0050510060062160050060120061b401005100c00517001d0051b4", + "0x2000518400600621600520d005173006006216005021005168006006216", + "0x520a00600621600501e00502a0060062160050190050df006006216005", + "0x1a00600621600502a0051800060062160050440050d4006006216005026", + "0x5100600621600500601200600629f0050061b00061b2005216005168005", + "0x600621600520d00517300600621600502100516800600621600504a005", + "0x621600501e00502a0060062160050190050df006006216005020005184", + "0x21600502a0051800060062160050440050d400600621600502600520a006", + "0x2160050062080060062160050060c40061b200521600514800501a006006", + "0xc02f0060bd0052160050bd00502d0060bd0052160050060d20061b0005", + "0x2160051ac1ae00c13d0061ae00521600500613b0061ac0052160050bd1b0", + "0x19b0061b20052160051b200501a0060c10052160050bf0051410060bf005", + "0x21600514a00514600600c00521600500c005199006005005216005005005", + "0x1d0050c10052160050c100514a00601000521600501000514800614a005", + "0x600621600514b0050510060062160050060120060c101014a00c0051b2", + "0x621600502000518400600621600520d00517300600621600503a005168", + "0x21600502600520a00600621600501e00502a0060062160050190050df006", + "0x21600500620800600621600502300519300600621600502a005180006006", + "0xc02f0061a70052160051a700502d0061a70052160050060d50061aa005", + "0x2160050c40c600c13d0060c600521600500613b0060c40052160051a71aa", + "0x19b00614800521600514800501a0060c80052160051a50051410061a5005", + "0x21600514a00514600600c00521600500c005199006005005216005005005", + "0x1d0050c80052160050c800514a00601000521600501000514800614a005", + "0x60062160050230051930060062160050060120060c801014a00c005148", + "0x62160050190050df00600621600502000518400600621600520d005173", + "0x21600502a00518000600621600502600520a00600621600501e00502a006", + "0x519b00614800521600514800501a0061a3005216005017005141006006", + "0x521600514a00514600600c00521600500c005199006005005216005005", + "0x14801d0051a30052160051a300514a00601000521600501000514800614a", + "0x1930060062160051460050510060062160050060120061a301014a00c005", + "0x60062160050190050df006006216005020005184006006216005023005", + "0x621600502a00518000600621600502600520a00600621600501e00502a", + "0x521600500620800600621600502500516a006006216005141005168006", + "0x19c00c02f0060ca0052160050ca00502d0060ca00521600500606700619c", + "0x52160050cc19b00c13d00619b00521600500613b0060cc0052160050ca", + "0x519b00620a00521600520a00501a00619f005216005199005141006199", + "0x521600520800514600600c00521600500c005199006005005216005005", + "0x20a01d00519f00521600519f00514a006010005216005010005148006208", + "0x19300600621600513d00505100600621600500601200619f01020800c005", + "0x60062160050190050df006006216005020005184006006216005023005", + "0x621600502a00518000600621600502f00516800600621600501e00502a", + "0x521600500620800600621600520c00506900600621600502500516a006", + "0xcf00c02f0060d10052160050d100502d0060d10052160050061780060cf", + "0x521600519519300c13d00619300521600500613b0061950052160050d1", + "0x519b00620a00521600520a00501a0060d40052160050d20051410060d2", + "0x521600520800514600600c00521600500c005199006005005216005005", + "0x20a01d0050d40052160050d400514a006010005216005010005148006208", + "0x1680060062160050230051930060062160050060120060d401020800c005", + "0x60062160050190050df006006216005020005184006006216005012005", + "0x621600502a00518000600621600520c00506900600621600501e00502a", + "0x521600500605900618e00521600500620800600621600502500516a006", + "0x13b0061970052160050d518e00c02f0060d50052160050d500502d0060d5", + "0x2160050d90051410060d90052160051970d700c13d0060d7005216005006", + "0x19900600500521600500500519b00620700521600520700501a006189005", + "0x21600501000514800602d00521600502d00514600600c00521600500c005", + "0xd700618901002d00c00520701d00518900521600518900514a006010005", + "0x12500600621600500600c00601a00521600500600500601d005216005006", + "0x1200602102000c2a01e901e00c21600c00c00600c010006006216005006", + "0x2300c21600501000501900601000521600501000501d006006216005006", + "0x260052a102500521600c20d00501e00601e00521600501e00501a00620d", + "0x21600520c00502000620c0052160050230051e9006006216005006012006", + "0x20d00600621600502a00502300620a02a00c216005028005021006028005", + "0x21600520700502300602d20700c216005208005021006208005216005006", + "0x502600613b00521600502d00502500602f00521600520a005025006006", + "0x2160050060120060062a200621600c13b02f00c20c00602f00521600502f", + "0x502500520a00600621600501a00502a00600621600501d0050df006006", + "0x14100502d00614100521600500620700613d005216005006208006006216", + "0x14600521600500613b00603100521600514113d00c02f006141005216005", + "0x501a00614a00521600514800514100614800521600503114600c13d006", + "0x52160051e900514600600500521600500500519900601e00521600501e", + "0x1e01200514a00521600514a00514a0061250052160051250051480061e9", + "0x503900603500521600500603500600621600500601200614a1251e9005", + "0x3c03a00c2a301703900c21600c0351e901e125017006035005216005035", + "0x3d00521600500603c00614b00521600500603a006006216005006012006", + "0x521600500603f00604000521600500603d00603f00521600500614b006", + "0x3d14b01915000604400521600500614e00615000521600500604000614e", + "0x15200615604700c21600515200504400615200521600504415014e04003f", + "0x521600501700514600603900521600503900501a006006216005047005", + "0x502d006125005216005125005148006005005216005005005199006017", + "0x1204a15e01221600502515612500501703901d0f1006025005216005025", + "0x1900521600501901a00c15e00601200521600501201d00c0e3006162019", + "0x62080060062160050060120061680052a404c00521600c16200504a006", + "0x5000c21600516d00504c00616d00521600504c00516200604e005216005", + "0x4a00514600615e00521600515e00501a006006216005050005168006170", + "0x4e00521600504e00504e00617000521600517000501d00604a005216005", + "0x521600c17200505000617205205112521600504e17004a15e01016d006", + "0x605917400c2160050550051700060062160050060120060570052a5055", + "0x517800517200605b17800c216005174005052006006216005059005051", + "0x17400605d00521600517a00505700617a00521600505b005055006006216", + "0x21600501200519900605100521600505100501a00617f00521600505d005", + "0x14a006019005216005019005148006052005216005052005146006012005", + "0x600621600500601200617f01905201205101200517f00521600517f005", + "0x501200519900605100521600505100501a006181005216005057005141", + "0x6019005216005019005148006052005216005052005146006012005216", + "0x621600500601200618101905201205101200518100521600518100514a", + "0x1200519900615e00521600515e00501a006061005216005168005141006", + "0x1900521600501900514800604a00521600504a005146006012005216005", + "0x21600500601200606101904a01215e01200506100521600506100514a006", + "0x502500520a00600621600501a00502a00600621600501d0050df006006", + "0x18600502d006186005216005006059006185005216005006208006006216", + "0x6700521600500613b00606500521600518618500c02f006186005216005", + "0x501a00606b00521600506900514100606900521600506506700c13d006", + "0x521600503c00514600600500521600500500519900603a00521600503a", + "0x3a01200506b00521600506b00514a00612500521600512500514800603c", + "0x50df00600621600502600505100600621600500601200606b12503c005", + "0x20800600621600502300516800600621600501a00502a00600621600501d", + "0x6d00521600506d00502d00606d00521600500617800618a005216005006", + "0xba00c13d0060ba00521600500613b00618d00521600506d18a00c02f006", + "0x521600501e00501a00619600521600507000514100607000521600518d", + "0x51480061e90052160051e900514600600500521600500500519900601e", + "0x1961251e900501e01200519600521600519600514a006125005216005125", + "0x621600501a00502a006006216005010005168006006216005006012006", + "0x521600500605900607200521600500620800600621600501d0050df006", + "0x13b00619d00521600519a07200c02f00619a00521600519a00502d00619a", + "0x2160051a00051410061a000521600519d07600c13d006076005216005006", + "0x14600600500521600500500519900602000521600502000501a0061a1005", + "0x2160051a100514a006125005216005125005148006021005216005021005", + "0xc00500c0100060062160050061250061a11250210050200120051a1005", + "0x501200501a00600621600500601200601a01900c2a601d01200c21600c", + "0x1e12521600501001200c06b00601000521600501000501d006012005216", + "0x60062160050060120060230052a702100521600c02000518a0060201e9", + "0x502500502100602500521600520d00502000620d0052160051e90051e9", + "0x2100602800521600500620d00600621600502600502300620c02600c216", + "0x21600520c00502500600621600502a00502300620a02a00c216005028005", + "0x20c00620800521600520800502600620700521600520a005025006208005", + "0x21600502100506d0060062160050060120060062a800621600c20720800c", + "0x502f00502d00602f00521600500620700602d005216005006208006006", + "0x613d00521600500613b00613b00521600502f02d00c02f00602f005216", + "0x600503100603100521600514100514100614100521600513b13d00c13d", + "0x1d00521600501d00514600601e00521600501e00501a006006005216005", + "0x1e00601200503100521600503100514a006125005216005125005148006", + "0x14600503900614600521600500603500600621600500601200603112501d", + "0x603903500c2a914a14800c21600c14601d01e125017006146005216005", + "0x603a00521600500603c00601700521600500603a006006216005006012", + "0x3d00521600500603f00614b00521600500603d00603c00521600500614b", + "0x3c03a01701915000604000521600500614e00603f005216005006040006", + "0x14a00514600614800521600514800501a00614e00521600504003f03d14b", + "0x12500521600512500514800600600521600500600503100614a005216005", + "0x1221600502114e12500614a14801d16b00602100521600502100518d006", + "0x500601200604a0052aa15e00521600c156005186006156047152044150", + "0x16200505200616200521600500620800600621600515e005065006006216", + "0x4e00521600516800505500600621600504c00517200616804c00c216005", + "0x15200503100605000521600516d00517400616d00521600504e005057006", + "0x4400521600504400514600615000521600515000501a006152005216005", + "0x15015201200505000521600505000514a006047005216005047005148006", + "0x503100617000521600504a005141006006216005006012006050047044", + "0x521600504400514600615000521600515000501a006152005216005152", + "0x15201200517000521600517000514a006047005216005047005148006044", + "0x620800600621600502100506d006006216005006012006170047044150", + "0x605200521600505200502d006052005216005006059006051005216005", + "0x17205500c13d00605500521600500613b00617200521600505205100c02f", + "0x6005216005006005031006174005216005057005141006057005216005", + "0x12500514800603900521600503900514600603500521600503500501a006", + "0x617412503903500601200517400521600517400514a006125005216005", + "0x60062160051e9005168006006216005023005051006006216005006012", + "0x521600517800502d006178005216005006178006059005216005006208", + "0xc13d00617a00521600500613b00605b00521600517805900c02f006178", + "0x21600500600503100617f00521600505d00514100605d00521600505b17a", + "0x14800601d00521600501d00514600601e00521600501e00501a006006005", + "0x12501d01e00601200517f00521600517f00514a006125005216005125005", + "0x521600500620800600621600501000516800600621600500601200617f", + "0x18100c02f00606100521600506100502d006061005216005006059006181", + "0x521600518518600c13d00618600521600500613b006185005216005061", + "0x501a006006005216005006005031006067005216005065005141006065", + "0x521600512500514800601a00521600501a005146006019005216005019", + "0x500612500606712501a01900601200506700521600506700514a006125", + "0x500601200601901d00c2ab01201000c21600c00500600c010006006216", + "0x2100601e00521600501a00502000601a0052160051250051e9006006216", + "0x521600500620d0060062160051e90050230060201e900c21600501e005", + "0x502500600621600502300502300620d02300c216005021005021006021", + "0x521600502500502600602600521600520d005025006025005216005020", + "0x60062ac00621600c02602500c20c00601000521600501000501a006025", + "0x602800521600500620700620c005216005006208006006216005006012", + "0x500613b00602a00521600502820c00c02f00602800521600502800502d", + "0x20700521600520800514100620800521600502a20a00c13d00620a005216", + "0xc00514800601200521600501200514600601000521600501000501a006", + "0x1200620700c01201001000520700521600520700514a00600c005216005", + "0x602d00521600502d00503900602d005216005006035006006216005006", + "0x621600500601200614113d00c2ad13b02f00c21600c02d012010125017", + "0x521600500614b00614600521600500603c00603100521600500603a006", + "0x21600500604000603500521600500603f00614a00521600500603d006148", + "0x501703903514a14814603101915000601700521600500614e006039005", + "0x600621600503c00515200614b03c00c21600503a00504400603a005216", + "0x500c00514800613b00521600513b00514600602f00521600502f00501a", + "0x50f500614e04003f03d01021600514b00c13b02f0100f300600c005216", + "0x52160050062080060062160050060120060440052ae15000521600c14e", + "0x6d00615e15600c216005047005096006047005216005150005161006152", + "0x521600515200504e00615e00521600515e00518d006006216005156005", + "0x5200600621600516200505100616204a00c21600515215e00c1b5006152", + "0x21600516800505500600621600504c00517200616804c00c21600504a005", + "0x1a00605000521600516d00517400616d00521600504e00505700604e005", + "0x21600504000514800603f00521600503f00514600603d00521600503d005", + "0x500601200605004003f03d01000505000521600505000514a006040005", + "0x14600603d00521600503d00501a006170005216005044005141006006216", + "0x21600517000514a00604000521600504000514800603f00521600503f005", + "0x521600500620800600621600500601200617004003f03d010005170005", + "0x5100c02f00605200521600505200502d006052005216005006059006051", + "0x521600517205500c13d00605500521600500613b006172005216005052", + "0x514600613d00521600513d00501a006174005216005057005141006057", + "0x521600517400514a00600c00521600500c005148006141005216005141", + "0x621600512500516800600621600500601200617400c14113d010005174", + "0x21600517800502d006178005216005006059006059005216005006208006", + "0x13d00617a00521600500613b00605b00521600517805900c02f006178005", + "0x501d00501a00617f00521600505d00514100605d00521600505b17a00c", + "0x600c00521600500c00514800601900521600501900514600601d005216", + "0x600621600500612500617f00c01901d01000517f00521600517f00514a", + "0x600621600500601200601901d00c2af01201000c21600c00500600c010", + "0x501e00502100601e00521600501a00502000601a0052160051250051e9", + "0x2100602100521600500620d0060062160051e90050230060201e900c216", + "0x21600502000502500600621600502300502300620d02300c216005021005", + "0x1a00602500521600502500502600602600521600520d005025006025005", + "0x50060120060062b000621600c02602500c20c006010005216005010005", + "0x2800502d00602800521600500620700620c005216005006208006006216", + "0x20a00521600500613b00602a00521600502820c00c02f006028005216005", + "0x501a00620700521600520800514100620800521600502a20a00c13d006", + "0x521600500c005148006012005216005012005146006010005216005010", + "0x21600500601200620700c01201001000520700521600520700514a00600c", + "0x1012501700602d00521600502d00503900602d005216005006035006006", + "0x603a00600621600500601200614113d00c2b113b02f00c21600c02d012", + "0x3d00614800521600500614b00614600521600500603c006031005216005", + "0x603900521600500604000603500521600500603f00614a005216005006", + "0x3a00521600501703903514a14814603101915000601700521600500614e", + "0x2f00501a00600621600503c00515200614b03c00c21600503a005044006", + "0xc00521600500c00514800613b00521600513b00514600602f005216005", + "0x21600c14e00508f00614e04003f03d01021600514b00c13b02f01015f006", + "0x900061520052160050062080060062160050060120060440052b2150005", + "0x51560051ab00615e15600c216005047005091006047005216005150005", + "0x9200615200521600515200504e00615e00521600515e00508c006006216", + "0x504a00505200600621600516200505100616204a00c21600515215e00c", + "0x604e00521600516800505500600621600504c00517200616804c00c216", + "0x503d00501a00605000521600516d00517400616d00521600504e005057", + "0x604000521600504000514800603f00521600503f00514600603d005216", + "0x600621600500601200605004003f03d01000505000521600505000514a", + "0x503f00514600603d00521600503d00501a006170005216005044005141", + "0x517000521600517000514a00604000521600504000514800603f005216", + "0x5900605100521600500620800600621600500601200617004003f03d010", + "0x21600505205100c02f00605200521600505200502d006052005216005006", + "0x14100605700521600517205500c13d00605500521600500613b006172005", + "0x21600514100514600613d00521600513d00501a006174005216005057005", + "0x1000517400521600517400514a00600c00521600500c005148006141005", + "0x620800600621600512500516800600621600500601200617400c14113d", + "0x617800521600517800502d006178005216005006059006059005216005", + "0x5b17a00c13d00617a00521600500613b00605b00521600517805900c02f", + "0x1d00521600501d00501a00617f00521600505d00514100605d005216005", + "0x17f00514a00600c00521600500c005148006019005216005019005146006", + "0x500c01000600621600500612500617f00c01901d01000517f005216005", + "0x1200501a00600621600500601200601a01900c2b301d01200c21600c00c", + "0x12521600501001200c1a800601000521600501000501d006012005216005", + "0x62160050060120060230052b402100521600c02000507e0060201e901e", + "0x2500502100602500521600520d00502000620d0052160051e90051e9006", + "0x602800521600500620d00600621600502600502300620c02600c216005", + "0x520c00502500600621600502a00502300620a02a00c216005028005021", + "0x620800521600520800502600620700521600520a005025006208005216", + "0x50210051ab0060062160050060120060062b500621600c20720800c20c", + "0x2f00502d00602f00521600500620700602d005216005006208006006216", + "0x13d00521600500613b00613b00521600502f02d00c02f00602f005216005", + "0x503100603100521600514100514100614100521600513b13d00c13d006", + "0x521600501d00514600601e00521600501e00501a006006005216005006", + "0x601200503100521600503100514a00612500521600512500514800601d", + "0x503900614600521600500603500600621600500601200603112501d01e", + "0x3903500c2b614a14800c21600c14601d01e125017006146005216005146", + "0x3a00521600500603c00601700521600500603a006006216005006012006", + "0x521600500603f00614b00521600500603d00603c00521600500614b006", + "0x3a01701915000604000521600500614e00603f00521600500604000603d", + "0x514600614800521600514800501a00614e00521600504003f03d14b03c", + "0x521600512500514800600600521600500600503100614a00521600514a", + "0x21600502114e12500614a14801d15b00602100521600502100508c006125", + "0x601200604a0052b715e00521600c156005186006156047152044150012", + "0x505200616200521600500620800600621600515e005065006006216005", + "0x521600516800505500600621600504c00517200616804c00c216005162", + "0x503100605000521600516d00517400616d00521600504e00505700604e", + "0x521600504400514600615000521600515000501a006152005216005152", + "0x15201200505000521600505000514a006047005216005047005148006044", + "0x3100617000521600504a005141006006216005006012006050047044150", + "0x21600504400514600615000521600515000501a006152005216005152005", + "0x1200517000521600517000514a006047005216005047005148006044005", + "0x2080060062160050210051ab006006216005006012006170047044150152", + "0x5200521600505200502d006052005216005006059006051005216005006", + "0x5500c13d00605500521600500613b00617200521600505205100c02f006", + "0x5216005006005031006174005216005057005141006057005216005172", + "0x514800603900521600503900514600603500521600503500501a006006", + "0x17412503903500601200517400521600517400514a006125005216005125", + "0x62160051e9005168006006216005023005051006006216005006012006", + "0x21600517800502d006178005216005006178006059005216005006208006", + "0x13d00617a00521600500613b00605b00521600517805900c02f006178005", + "0x500600503100617f00521600505d00514100605d00521600505b17a00c", + "0x601d00521600501d00514600601e00521600501e00501a006006005216", + "0x1d01e00601200517f00521600517f00514a006125005216005125005148", + "0x21600500620800600621600501000516800600621600500601200617f125", + "0xc02f00606100521600506100502d006061005216005006059006181005", + "0x21600518518600c13d00618600521600500613b006185005216005061181", + "0x1a006006005216005006005031006067005216005065005141006065005", + "0x21600512500514800601a00521600501a005146006019005216005019005", + "0x612500606712501a01900601200506700521600506700514a006125005", + "0x601200601a01900c2b801d01200c21600c00c00500c010006006216005", + "0x601000521600501000501d00601200521600501200501a006006216005", + "0x52b902100521600c02000518a0060201e901e12521600501001200c06b", + "0x51e900501d00601e00521600501e00501a006006216005006012006023", + "0x21600c02600507e00602602520d1252160051e901e00c1a80061e9005216", + "0x602a0052160050250051e90060062160050060120060280052ba20c005", + "0x20800502300620720800c21600520a00502100620a00521600502a005020", + "0x613b02f00c21600502d00502100602d00521600500620d006006216005", + "0x21600513b00502500613d00521600520700502500600621600502f005023", + "0x62bb00621600c14113d00c20c00613d00521600513d005026006141005", + "0x621600502100506d00600621600520c0051ab006006216005006012006", + "0x21600514600502d006146005216005006207006031005216005006208006", + "0x13d00614a00521600500613b00614800521600514603100c02f006146005", + "0x500600503100603900521600503500514100603500521600514814a00c", + "0x601d00521600501d00514600620d00521600520d00501a006006005216", + "0x1d20d00601200503900521600503900514a006125005216005125005148", + "0x5017005039006017005216005006035006006216005006012006039125", + "0x1200603d14b00c2bc03c03a00c21600c01701d20d125017006017005216", + "0x14b00604000521600500603c00603f00521600500603a006006216005006", + "0x604400521600500603f00615000521600500603d00614e005216005006", + "0x15014e04003f01915000604700521600500614e006152005216005006040", + "0x503c00514600603a00521600503a00501a006156005216005047152044", + "0x612500521600512500514800600600521600500600503100603c005216", + "0x3c03a01916600620c00521600520c00508c00602100521600502100518d", + "0x521600c16800518600616804c16204a15e01221600520c021156125006", + "0x620800600621600504e00506500600621600500601200616d0052bd04e", + "0x621600517000517200605117000c216005050005052006050005216005", + "0x172005174006172005216005052005057006052005216005051005055006", + "0x15e00521600515e00501a006162005216005162005031006055005216005", + "0x5500514a00604c00521600504c00514800604a00521600504a005146006", + "0x514100600621600500601200605504c04a15e162012005055005216005", + "0x521600515e00501a00616200521600516200503100605700521600516d", + "0x514a00604c00521600504c00514800604a00521600504a00514600615e", + "0x1ab00600621600500601200605704c04a15e162012005057005216005057", + "0x617400521600500620800600621600502100506d00600621600520c005", + "0x505917400c02f00605900521600505900502d006059005216005006059", + "0x617a00521600517805b00c13d00605b00521600500613b006178005216", + "0x514b00501a00600600521600500600503100605d00521600517a005141", + "0x612500521600512500514800603d00521600503d00514600614b005216", + "0x621600500601200605d12503d14b00601200505d00521600505d00514a", + "0x21600502100506d006006216005025005168006006216005028005051006", + "0x518100502d00618100521600500606700617f005216005006208006006", + "0x618500521600500613b00606100521600518117f00c02f006181005216", + "0x600503100606500521600518600514100618600521600506118500c13d", + "0x1d00521600501d00514600620d00521600520d00501a006006005216005", + "0x20d00601200506500521600506500514a006125005216005125005148006", + "0x1e900516800600621600502300505100600621600500601200606512501d", + "0x502d006069005216005006178006067005216005006208006006216005", + "0x521600500613b00606b00521600506906700c02f006069005216005069", + "0x3100618d00521600506d00514100606d00521600506b18a00c13d00618a", + "0x21600501d00514600601e00521600501e00501a006006005216005006005", + "0x1200518d00521600518d00514a00612500521600512500514800601d005", + "0x20800600621600501000516800600621600500601200618d12501d01e006", + "0x7000521600507000502d0060700052160050060590060ba005216005006", + "0x7200c13d00607200521600500613b0061960052160050700ba00c02f006", + "0x521600500600503100619d00521600519a00514100619a005216005196", + "0x514800601a00521600501a00514600601900521600501900501a006006", + "0x19d12501a01900601200519d00521600519d00514a006125005216005125", + "0x100052be12500c00c21600c0050051b60060050052160050060051e9006", + "0x21600500c0051b40060120052160051250050b8006006216005006012006", + "0x50060120060062bf0050061b00060190052160050120051b200601d005", + "0x51b400601e00521600501a0051ac00601a0052160050060bd006006216", + "0x521600501d00505500601900521600501e0051b200601d005216005010", + "0x210052c002000521600c0190051ae0061e90052160051e900501d0061e9", + "0x2160050230050c10060230052160050200050bf006006216005006012006", + "0xe90061e90052160051e900501d00602500521600520d00516400620d005", + "0x210050510060062160050060120060251e900c005025005216005025005", + "0x1d00620c0052160050260050fa0060260052160050060bd006006216005", + "0xc400620c1e900c00520c00521600520c0050e90061e90052160051e9005", + "0x1901000c21600501000515700601d005216005006208006006216005006", + "0x21600501a0050fe00620d0230210201e901e01a0192160050190050fc006", + "0x50210051010060062160051e900515800600621600501e005155006006", + "0x600501a00600621600520d005153006006216005023005103006006216", + "0xc00521600500c005031006005005216005005005146006006005216005", + "0x502d00602501200c216005012005105006125005216005125005148006", + "0x2820c02601221600502502012500c00500601d151006025005216005025", + "0x60062160050060120062070052c120800521600c20a00510700620a02a", + "0x502f02d00c14d00602f00521600500610900602d00521600520800514f", + "0x614100521600513d01200c14d00613d00521600500610900613b005216", + "0x502800503100620c00521600520c00514600602600521600502600501a", + "0x613b00521600513b00502d00602a00521600502a005148006028005216", + "0x20c02601a14c00601d00521600501d00504e00614100521600514100502d", + "0x21600c03500510c00603514a14814603101221600501001d14113b02a028", + "0x3c03a1252160050390051490060062160050060120060170052c2039005", + "0x503a00505200600621600514b00505100600621600503c00520a00614b", + "0x604000521600503f00505500600621600503d00517200603f03d00c216", + "0x503100501a00615000521600514e00517400614e005216005040005057", + "0x6148005216005148005031006146005216005146005146006031005216", + "0x14814603101200515000521600515000514a00614a00521600514a005148", + "0x3100501a00604400521600501700514100600621600500601200615014a", + "0x148005216005148005031006146005216005146005146006031005216005", + "0x14603101200504400521600504400514a00614a00521600514a005148006", + "0x1d00517200600621600501000515200600621600500601200604414a148", + "0x1a00615200521600520700514100600621600501200520a006006216005", + "0x21600502800503100620c00521600520c005146006026005216005026005", + "0x1200515200521600515200514a00602a00521600502a005148006028005", + "0x1000c00c21600500c0051470060062160050060c400615202a02820c026", + "0x1d00502000601d0052160050120051e900601200521600501000510f006", + "0x621600501a00502300601e01a00c216005019005021006019005216005", + "0x2000502d0060200052160051e90051bd0061e900521600501e005025006", + "0x521600500c00510f00602100521600502012500c02f006020005216005", + "0x501d00600500521600500500514600600600521600500600501a006023", + "0x2102300500601014300602100521600502100504e006023005216005023", + "0x60120060280052c320c00521600c02600505000602602520d125216005", + "0x521600520a02a00c11100620a02a00c21600520c005170006006216005", + "0x514600620d00521600520d00501a006207005216005208005113006208", + "0x1200620702520d125005207005216005207005142006025005216005025", + "0x20d00521600520d00501a00602d005216005028005145006006216005006", + "0x2520d12500502d00521600502d005142006025005216005025005146006", + "0xc1250051b600612500521600500c0051e90060062160050060c400602d", + "0x52160050120050b800600621600500601200601d0052c401201000c216", + "0x61b000601e0052160050190051b200601a0052160050100051b4006019", + "0x1e90051ac0061e90052160050060bd0060062160050060120060062c5005", + "0x1e0052160050200051b200601a00521600501d0051b4006020005216005", + "0x1e0051ae00602100521600502100501d00602100521600501a005055006", + "0x52160050230050bf00600621600500601200620d0052c602300521600c", + "0x600501a00620c0052160050250050c1006026005216005006208006025", + "0x2100521600502100501d006005005216005005005146006006005216005", + "0x601211500620c00521600520c00502d00602600521600502600504e006", + "0x52c720800521600c20a0050a600620a02a02812521600520c026021005", + "0x2f0051bc00602f02d00c2160052080050a8006006216005006012006207", + "0xc21600513b00505200600621600500601200613d0052c813b00521600c", + "0x513e006146005216005031005055006006216005141005172006031141", + "0x21600514a00513900614a00521600514802d00c119006148005216005146", + "0x11c00602a00521600502a00514600602800521600502800501a006035005", + "0x513600600621600500601200603502a028125005035005216005035005", + "0x21600501700513900601700521600503902d00c11900603900521600513d", + "0x11c00602a00521600502a00514600602800521600502800501a00603a005", + "0x513700600621600500601200603a02a02812500503a00521600503a005", + "0x521600502a00514600602800521600502800501a00603c005216005207", + "0x621600500601200603c02a02812500503c00521600503c00511c00602a", + "0x21600514b00513600614b0052160050060bd00600621600520d005051006", + "0x604000521600503f00513900603f00521600503d02100c11900603d005", + "0x504000511c00600500521600500500514600600600521600500600501a", + "0x21600500600c00601a005216005006006006040005006125005040005216", + "0x50051460061e901e00c2160050100050440060062160050060c4006006", + "0x12521600512500500c126006125005216005125005148006005005216005", + "0x62160050060120060250052c920d00521600c0230050f5006023021020", + "0x2000514600600600521600500600501a00602600521600520d005161006", + "0x2100521600502100514800600c00521600500c005031006020005216005", + "0x502d00620c01200c21600501200510500602600521600502600518d006", + "0x2a02801221600520c0261e902100c0200060190ba00620c00521600520c", + "0x621600500601200602f0052ca02d00521600c20700507000620720820a", + "0x61410052cb13d00521600c13b00512f00613b00521600502d005196006", + "0x600621600501d00516800600621600513d005051006006216005006012", + "0x621600501a00502800600621600501e00515200600621600501200520a", + "0x21600514600502d006146005216005006000006031005216005006208006", + "0x13d00614a00521600500613b00614800521600514603100c02f006146005", + "0x502800501a0060390052160050350052cc00603500521600514814a00c", + "0x620a00521600520a00503100602a00521600502a005146006028005216", + "0x20a02a0280120050390052160050390052cd006208005216005208005148", + "0x501d005147006006216005141005051006006216005006012006039208", + "0x3c00521600503a00502000603a0052160050170051e900601701d00c216", + "0x503c0052cf00603c00521600503c00502600614b0052160050062ce006", + "0x21600c14b03d0281252d000614b00521600514b00502600603d03c00c216", + "0x621600504000502300600621600500601200615014e00c2d104003f00c", + "0x21600503c00502300600621600501200520a00600621600501d005168006", + "0x21600500620800600621600501a00502800600621600501e005152006006", + "0xc02f00615200521600515200502d0061520052160050062d2006044005", + "0x21600504715600c13d00615600521600500613b006047005216005152044", + "0x14600603f00521600503f00501a00604a00521600515e0052cc00615e005", + "0x21600520800514800620a00521600520a00503100602a00521600502a005", + "0x601200604a20820a02a03f01200504a00521600504a0052cd006208005", + "0xfc00616200521600503c0051bd006006216005150005023006006216005", + "0x14e00521600514e00501a00605117005016d04e16804c01921600501e005", + "0x20800514800620a00521600520a00503100602a00521600502a005146006", + "0x521600505200502d00605201200c216005012005105006208005216005", + "0x516205216d20820a02a14e0192d300616200521600516200502d006052", + "0x1740052d400601900521600501901a00c156006174057019055172012216", + "0xc2160050590052d60060062160050060120061780052d505900521600c", + "0x14700605d01200c21600501200510500600621600517a00505100617a05b", + "0x4c01915000618100521600517f05d00c21c00617f01d00c21600501d005", + "0x14600617200521600517200501a00606100521600505117005005b04e168", + "0x2160051810052d7006057005216005057005148006055005216005055005", + "0x51860060670651861850102160051810610570551720122d8006181005", + "0x521600500610900600621600500601200606b0052d906900521600c067", + "0x60ba18d00c2160050690052da00606d00521600518a01200c14d00618a", + "0x1a007619d19a07219607001921600518d0050fc0060062160050ba005051", + "0x1900503100618600521600518600514600618500521600518500501a006", + "0x1d00521600501d00501d006065005216005065005148006019005216005", + "0x21600506d19a01d0650191861850192db00606d00521600506d00502d006", + "0x60120061ab0052dd07e00521600c1a80052dc0061a81a407b1a21a1012", + "0x21600508c00516800608f08e08d08c01021600507e0052de006006216005", + "0x2160050060bd00600621600508f00505100600621600508e00520a006006", + "0x9100c2df0060910052160051a007619d08d072196070019150006090005", + "0x52160051a100501a00609300521600509200521b006092005216005090", + "0x514800607b00521600507b0050310061a20052160051a20051460061a1", + "0x931a407b1a21a10120050930052160050930052cd0061a40052160051a4", + "0x62160051a00051530060062160050700050fe006006216005006012006", + "0x21600519600515500600621600519d005101006006216005076005103006", + "0x1a100501a0060940052160051ab0052cc006006216005072005158006006", + "0x7b00521600507b0050310061a20052160051a20051460061a1005216005", + "0x1a21a10120050940052160050940052cd0061a40052160051a4005148006", + "0x1200520a00600621600501d0051680060062160050060120060941a407b", + "0x618500521600518500501a00609500521600506b0052cc006006216005", + "0x5065005148006019005216005019005031006186005216005186005146", + "0x120060950650191861850120050950052160050950052cd006065005216", + "0xfe00600621600501200520a00600621600501d005168006006216005006", + "0x600621600517000510300600621600505100515300600621600504c005", + "0x621600504e005158006006216005168005155006006216005050005101", + "0x5500514600617200521600517200501a0060960052160051780052cc006", + "0x57005216005057005148006019005216005019005031006055005216005", + "0x2160050060120060960570190551720120050960052160050960052cd006", + "0x501e00515200600621600501200520a00600621600501d005168006006", + "0x501a0061b500521600502f0052cc00600621600501a005028006006216", + "0x521600520a00503100602a00521600502a005146006028005216005028", + "0x280120051b50052160051b50052cd00620800521600520800514800620a", + "0x520a00600621600501d0051680060062160050060120061b520820a02a", + "0x15200600621600501a00502800600621600501e005152006006216005012", + "0x521600500600501a00609b0052160050250052cc0060062160051e9005", + "0x514800600c00521600500c005031006020005216005020005146006006", + "0x9b02100c02000601200509b00521600509b0052cd006021005216005021", + "0x501e00612500c00c21600500500501900600500521600500500501d006", + "0xc01000600c2e10060062160050060120060120052e001000521600c125", + "0x52160050190052e300600621600500601200601a0052e201901d00c216", + "0x52e400600c00521600500c00501d00601d00521600501d00501a00601e", + "0x50060bd00600621600500601200601e00c01d12500501e00521600501e", + "0x601a00521600501a00501a0060200052160051e90052e50061e9005216", + "0x2000c01a1250050200052160050200052e400600c00521600500c00501d", + "0x21600500600501a0060210052160050120052e5006006216005006012006", + "0x1250050210052160050210052e400600c00521600500c00501d006006005", + "0x50fe0060230210201e901e01a0190192160050100050fc00602100c006", + "0x1f200600621600501e00515800600621600501a005155006006216005019", + "0x60062160050230051530060062160050200051010060062160051e9005", + "0x500514600600600521600500600501a00620d00521600501201d00c2e6", + "0x12500521600512500514800600c00521600500c005031006005005216005", + "0x1221600520d02112500c00500601d2e800620d00521600520d0052e7006", + "0x50060120062080052e920a00521600c02a00507000602a02820c026025", + "0x2ea00602d00521600520700517c00620700521600520a005196006006216", + "0x21600502600514600602500521600502500501a00602f00521600502d005", + "0x2eb00602800521600502800514800620c00521600520c005031006026005", + "0x600621600500601200602f02820c02602501200502f00521600502f005", + "0x502600514600602500521600502500501a00613b0052160052080052ec", + "0x602800521600502800514800620c00521600520c005031006026005216", + "0x2160050060052ed00613b02820c02602501200513b00521600513b0052eb", + "0x60062160050060120060100052ee12500521600c00c00512f00600c005", + "0x521600501200502d0060120052160050062ef006006216005125005051", + "0x62160050100050510060062160050060120060062f00050061b000601d", + "0x501d0052f100601d00521600501900502d006019005216005006109006", + "0x600500521600500500504e00600621600501a00520a00601e01a00c216", + "0x50060bd0060062160050200050510060201e900c21600500501e00c21a", + "0x621600500600c00601a0052160050060060060211e900c005021005216", + "0x2160051250051480060050052160050050051460060062160050060c4006", + "0x521600c0200050f50060201e901e12521600512500500c126006125005", + "0x602520d00c2160050100050440060062160050060120060230052f2021", + "0x501e00514600600600521600500600501a006026005216005021005161", + "0x61e90052160051e900514800600c00521600500c00503100601e005216", + "0x1d00510500620c00521600520c00518d00620c02600c2160050260052f3", + "0x1e900c01e0060190ba00602800521600502800502d00602801d00c216005", + "0x2f402f00521600c02d00507000602d20720820a02a01221600502820c025", + "0x13d00512f00613d00521600502f00519600600621600500601200613b005", + "0x62160051410050510060062160050060120060310052f514100521600c", + "0x2a00501a00614a0052160050062ef00614814600c21600520d005044006", + "0x20800521600520800503100620a00521600520a00514600602a005216005", + "0x14a00502d00602600521600502600518d006207005216005207005148006", + "0x1703903501221600514a02614820720820a02a0190ba00614a005216005", + "0x600621600500601200603d0052f614b00521600c03c00507000603c03a", + "0x503900514600604000521600503500501a00603f00521600514b005196", + "0x604400521600503a00514800615000521600501700503100614e005216", + "0x2f80050061b000604700521600503f00519d0061520052160051460052f7", + "0x21600501a005028006006216005146005152006006216005006012006006", + "0x503d0052cc00600621600501d00520a00600621600501200506d006006", + "0x603900521600503900514600603500521600503500501a006156005216", + "0x51560052cd00603a00521600503a005148006017005216005017005031", + "0x3100505100600621600500601200615603a017039035012005156005216", + "0x52f900615e0052160050060bd00600621600502600506d006006216005", + "0x521600520a00514600604000521600502a00501a00604a00521600515e", + "0x52f700604400521600520700514800615000521600520800503100614e", + "0x521600c04700512f00604700521600504a00519d00615200521600520d", + "0x502800600621600516200505100600621600500601200604c0052fa162", + "0x15200600621600501d00520a00600621600501200506d00600621600501a", + "0x604e005216005006000006168005216005006208006006216005152005", + "0x500613b00616d00521600504e16800c02f00604e00521600504e00502d", + "0x510052160051700052cc00617000521600516d05000c13d006050005216", + "0x15000503100614e00521600514e00514600604000521600504000501a006", + "0x510052160050510052cd006044005216005044005148006150005216005", + "0x621600504c00505100600621600500601200605104415014e040012005", + "0x21600501d0051050061780591740570551720520192160051520050fc006", + "0x521600517a05b00c2e600617a01200c2160050120052f300605b01d00c", + "0x4000501a00618100521600517f0052f900617f0052160050060bd00605d", + "0x15000521600515000503100614e00521600514e005146006040005216005", + "0x18100519d00605d00521600505d0052e7006044005216005044005148006", + "0x1918506101221600518105d05904415014e0400192fb006181005216005", + "0x2fd06700521600c0650052fc00601900521600501901a00c156006065186", + "0x505100618a06b00c2160050670052fe006006216005006012006069005", + "0x618d00521600506d0052f900606d0052160050060bd00600621600518a", + "0x517806b1740570551720520191500060ba00521600518d01d0121252ff", + "0x618500521600518500514600606100521600506100501a006070005216", + "0x1850610123010060ba0052160050ba005300006186005216005186005148", + "0x530207600521600c19d00518600619d19a0721960102160050ba070186", + "0x1a20050510061a21a100c2160050760052da0060062160050060120061a0", + "0x61a400521600507b1a100c2df00607b0052160050060bd006006216005", + "0x507200514600619600521600519600501a0061a80052160051a400521b", + "0x619a00521600519a005148006019005216005019005031006072005216", + "0x62160050060120061a819a0190721960120051a80052160051a80052cd", + "0x7200514600619600521600519600501a00607e0052160051a00052cc006", + "0x19a00521600519a005148006019005216005019005031006072005216005", + "0x21600500601200607e19a01907219601200507e00521600507e0052cd006", + "0x501d00520a0060062160051780051530060062160050520050fe006006", + "0x550051580060062160050570051f2006006216005174005101006006216", + "0x52cc00600621600501200506d006006216005172005155006006216005", + "0x521600518500514600606100521600506100501a0061ab005216005069", + "0x52cd006186005216005186005148006019005216005019005031006185", + "0x280060062160050060120061ab1860191850610120051ab0052160051ab", + "0x600621600501d00520a00600621600501200506d00600621600501a005", + "0x521600513b0052cc00600621600520d00515200600621600502600506d", + "0x503100620a00521600520a00514600602a00521600502a00501a00608c", + "0x521600508c0052cd006207005216005207005148006208005216005208", + "0x21600501a00502800600621600500601200608c20720820a02a01200508c", + "0x501d00520a00600621600501200506d006006216005010005152006006", + "0x14600600600521600500600501a00608d0052160050230052cc006006216", + "0x2160051e900514800600c00521600500c00503100601e00521600501e005", + "0x600600608d1e900c01e00601200508d00521600508d0052cd0061e9005", + "0x50051460060062160050060c400600621600500600c00601a005216005", + "0x12521600512500500c126006125005216005125005148006005005216005", + "0x621600500601200602300530302100521600c0200050f50060201e901e", + "0x501a00602600521600502100516100602520d00c216005010005044006", + "0x521600500c00503100601e00521600501e005146006006005216005006", + "0x18d00620c02600c2160050260052f30061e90052160051e900514800600c", + "0x502800502d00602801d00c21600501d00510500620c00521600520c005", + "0x20720820a02a01221600502820c0251e900c01e0060190ba006028005216", + "0x19600600621600500601200613b00530402f00521600c02d00507000602d", + "0x601200603100530514100521600c13d00512f00613d00521600502f005", + "0x614814600c21600520d005044006006216005141005051006006216005", + "0x21600520a00514600602a00521600502a00501a00614a0052160050062ef", + "0x18d00620700521600520700514800620800521600520800503100620a005", + "0x20820a02a0190ba00614a00521600514a00502d006026005216005026005", + "0x14b00521600c03c00507000603c03a01703903501221600514a026148207", + "0x501a00603f00521600514b00519600600621600500601200603d005306", + "0x521600501700503100614e005216005039005146006040005216005035", + "0x519d0061520052160051460052f700604400521600503a005148006150", + "0x51520060062160050060120060063070050061b000604700521600503f", + "0x20a00600621600501200506d00600621600501a005028006006216005146", + "0x521600503500501a00615600521600503d0052cc00600621600501d005", + "0x5148006017005216005017005031006039005216005039005146006035", + "0x15603a0170390350120051560052160051560052cd00603a00521600503a", + "0x621600502600506d006006216005031005051006006216005006012006", + "0x502a00501a00604a00521600515e0052f900615e0052160050060bd006", + "0x615000521600520800503100614e00521600520a005146006040005216", + "0x504a00519d00615200521600520d0052f7006044005216005207005148", + "0x621600500601200604c00530816200521600c04700512f006047005216", + "0x21600501200506d00600621600501a005028006006216005162005051006", + "0x21600500620800600621600515200515200600621600501d00520a006006", + "0xc02f00604e00521600504e00502d00604e005216005006000006168005", + "0x21600516d05000c13d00605000521600500613b00616d00521600504e168", + "0x14600604000521600504000501a0060510052160051700052cc006170005", + "0x21600504400514800615000521600515000503100614e00521600514e005", + "0x601200605104415014e0400120050510052160050510052cd006044005", + "0x551720520192160051520050fc00600621600504c005051006006216005", + "0xc2160050120052f300605b01d00c21600501d005105006178059174057", + "0x30900617f0052160050060bd00605d00521600517a05b00c2e600617a012", + "0x21600514e00514600604000521600504000501a00618100521600517f005", + "0x2e700604400521600504400514800615000521600515000503100614e005", + "0x15014e0400192fb00618100521600518100519d00605d00521600505d005", + "0x521600501901a00c15600606518601918506101221600518105d059044", + "0x2fe00600621600500601200606900530a06700521600c0650052fc006019", + "0x52160050060bd00600621600518a00505100618a06b00c216005067005", + "0x60ba00521600518d01d0121252ff00618d00521600506d00530900606d", + "0x521600506100501a00607000521600517806b174057055172052019150", + "0x5300006186005216005186005148006185005216005185005146006061", + "0x19d19a0721960102160050ba0701861850610123010060ba0052160050ba", + "0x52da0060062160050060120061a000530b07600521600c19d005186006", + "0x7b0052160050060bd0060062160051a20050510061a21a100c216005076", + "0x501a0061a80052160051a400521b0061a400521600507b1a100c2df006", + "0x5216005019005031006072005216005072005146006196005216005196", + "0x1960120051a80052160051a80052cd00619a00521600519a005148006019", + "0x1a00607e0052160051a00052cc0060062160050060120061a819a019072", + "0x216005019005031006072005216005072005146006196005216005196005", + "0x1200507e00521600507e0052cd00619a00521600519a005148006019005", + "0x1530060062160050520050fe00600621600500601200607e19a019072196", + "0x600621600517400510100600621600501d00520a006006216005178005", + "0x62160051720051550060062160050550051580060062160050570051f2", + "0x506100501a0061ab0052160050690052cc00600621600501200506d006", + "0x6019005216005019005031006185005216005185005146006061005216", + "0x191850610120051ab0052160051ab0052cd006186005216005186005148", + "0x501200506d00600621600501a0050280060062160050060120061ab186", + "0x20d00515200600621600502600506d00600621600501d00520a006006216", + "0x602a00521600502a00501a00608c00521600513b0052cc006006216005", + "0x520700514800620800521600520800503100620a00521600520a005146", + "0x1200608c20720820a02a01200508c00521600508c0052cd006207005216", + "0x6d00600621600501000515200600621600501a005028006006216005006", + "0x8d0052160050230052cc00600621600501d00520a006006216005012005", + "0xc00503100601e00521600501e00514600600600521600500600501a006", + "0x8d00521600508d0052cd0061e90052160051e900514800600c005216005", + "0x210201e901e01a0190192160050100050fc00608d1e900c01e006012005", + "0x501e00515800600621600501a0051550060062160050190050fe006023", + "0x210051030060062160050200051010060062160051e90051f2006006216", + "0x600521600500600501a00620d00521600501d01200c2e6006006216005", + "0x12500514800600c00521600500c005031006005005216005005005146006", + "0x2312500c00500601d30c00620d00521600520d0052e7006125005216005", + "0x20800530d20a00521600c02a00507000602a02820c02602501221600520d", + "0x21600520700517c00620700521600520a005196006006216005006012006", + "0x14600602500521600502500501a00602f00521600502d0052ea00602d005", + "0x21600502800514800620c00521600520c005031006026005216005026005", + "0x601200602f02820c02602501200502f00521600502f0052eb006028005", + "0x602500521600502500501a00613b0052160052080052ec006006216005", + "0x502800514800620c00521600520c005031006026005216005026005146", + "0x600613b02820c02602501200513b00521600513b0052eb006028005216", + "0x51460060062160050060c400600621600500600c00601a005216005006", + "0x21600512500500c126006125005216005125005148006005005216005005", + "0x21600500601200602300530e02100521600c0200050f50060201e901e125", + "0x1a00602600521600502100516100602520d00c216005010005044006006", + "0x21600500c00503100601e00521600501e005146006006005216005006005", + "0x620c02600c2160050260052f30061e90052160051e900514800600c005", + "0x2800502d00602801200c21600501200510500620c00521600520c00518d", + "0x20820a02a01221600502820c0251e900c01e0060190ba006028005216005", + "0x600621600500601200613b00530f02f00521600c02d00507000602d207", + "0x1200603100531014100521600c13d00512f00613d00521600502f005196", + "0x14814600c21600520d005044006006216005141005051006006216005006", + "0x520a00514600602a00521600502a00501a00614a0052160050062ef006", + "0x620700521600520700514800620800521600520800503100620a005216", + "0x20a02a0190ba00614a00521600514a00502d00602600521600502600518d", + "0x521600c03c00507000603c03a01703903501221600514a026148207208", + "0x1a00603f00521600514b00519600600621600500601200603d00531114b", + "0x21600501700503100614e005216005039005146006040005216005035005", + "0x19d0061520052160051460052f700604400521600503a005148006150005", + "0x1520060062160050060120060063120050061b000604700521600503f005", + "0x600621600501d00506d00600621600501200520a006006216005146005", + "0x21600503500501a00615600521600503d0052cc00600621600501a005028", + "0x148006017005216005017005031006039005216005039005146006035005", + "0x3a0170390350120051560052160051560052cd00603a00521600503a005", + "0x21600502600506d006006216005031005051006006216005006012006156", + "0x2a00501a00604a00521600515e0052f900615e0052160050060bd006006", + "0x15000521600520800503100614e00521600520a005146006040005216005", + "0x4a00519d00615200521600520d0052f7006044005216005207005148006", + "0x21600500601200604c00531316200521600c04700512f006047005216005", + "0x501d00506d00600621600501200520a006006216005162005051006006", + "0x500620800600621600515200515200600621600501a005028006006216", + "0x2f00604e00521600504e00502d00604e005216005006314006168005216", + "0x516d05000c13d00605000521600500613b00616d00521600504e16800c", + "0x604000521600504000501a0060510052160051700052cc006170005216", + "0x504400514800615000521600515000503100614e00521600514e005146", + "0x1200605104415014e0400120050510052160050510052cd006044005216", + "0x1720520192160051520050fc00600621600504c005051006006216005006", + "0x21600501d0052f300605b01200c216005012005105006178059174057055", + "0x617f0052160050060bd00605d00521600517a05b00c2e600617a01d00c", + "0x514e00514600604000521600504000501a00618100521600517f0052f9", + "0x604400521600504400514800615000521600515000503100614e005216", + "0x14e04001931500618100521600518100519d00605d00521600505d0052e7", + "0x21600501901a00c15600606518601918506101221600518105d178044150", + "0x600621600500601200606900531706700521600c065005316006019005", + "0x2160050060bd00600621600518a00505100618a06b00c216005067005318", + "0xba00521600518d01d01212531900618d00521600506d0052f900606d005", + "0x21600506100501a00607000521600506b059174057055172052019150006", + "0x219006186005216005186005148006185005216005185005146006061005", + "0x19a0721960102160050ba07018618506101231a0060ba0052160050ba005", + "0x2da0060062160050060120061a000531b07600521600c19d00518600619d", + "0x52160050060bd0060062160051a20050510061a21a100c216005076005", + "0x1a0061a80052160051a400521b0061a400521600507b1a100c2df00607b", + "0x216005019005031006072005216005072005146006196005216005196005", + "0x120051a80052160051a80052cd00619a00521600519a005148006019005", + "0x607e0052160051a00052cc0060062160050060120061a819a019072196", + "0x501900503100607200521600507200514600619600521600519600501a", + "0x507e00521600507e0052cd00619a00521600519a005148006019005216", + "0x60062160050520050fe00600621600500601200607e19a019072196012", + "0x621600517400510100600621600505900510300600621600501d00506d", + "0x2160051720051550060062160050550051580060062160050570051f2006", + "0x6100501a0061ab0052160050690052cc00600621600501200520a006006", + "0x19005216005019005031006185005216005185005146006061005216005", + "0x1850610120051ab0052160051ab0052cd006186005216005186005148006", + "0x1d00506d00600621600501200520a0060062160050060120061ab186019", + "0x515200600621600502600506d00600621600501a005028006006216005", + "0x2a00521600502a00501a00608c00521600513b0052cc00600621600520d", + "0x20700514800620800521600520800503100620a00521600520a005146006", + "0x608c20720820a02a01200508c00521600508c0052cd006207005216005", + "0x600621600501000515200600621600501200520a006006216005006012", + "0x52160050230052cc00600621600501a00502800600621600501d00506d", + "0x503100601e00521600501e00514600600600521600500600501a00608d", + "0x521600508d0052cd0061e90052160051e900514800600c00521600500c", + "0x21600500600c00601a00521600500600600608d1e900c01e00601200508d", + "0x51250051480060050052160050050051460060062160050060c4006006", + "0x21600c0200050f50060201e901e12521600512500500c126006125005216", + "0x2520d00c21600501000504400600621600500601200602300531c021005", + "0x1e00514600600600521600500600501a006026005216005021005161006", + "0x1e90052160051e900514800600c00521600500c00503100601e005216005", + "0x52f300620c00521600520c00502d00620c01200c216005012005105006", + "0xc01e0060191a200602800521600502800518d00602802600c216005026", + "0x2f00521600c02d00507000602d20720820a02a01221600502820c0251e9", + "0x60b400613d00521600502f00519600600621600500601200613b00531d", + "0x621600500601200603100531e14100521600c13d00512f006006216005", + "0x2a00501a00614814600c21600520d005044006006216005141005051006", + "0x20800521600520800503100620a00521600520a00514600602a005216005", + "0x518d00614a02600c2160050260052f3006207005216005207005148006", + "0x21600503500502d00603501200c21600501200510500614a00521600514a", + "0x14b03c03a01703901221600503514a14820720820a02a0190ba006035005", + "0x519600600621600500601200603f00531f03d00521600c14b005070006", + "0x521600501700514600614e00521600503900501a00604000521600503d", + "0x52f700615200521600503c00514800604400521600503a005031006150", + "0x60063200050061b000615600521600504000519d006047005216005146", + "0x6d00600621600501200520a0060062160050060c4006006216005006012", + "0x600621600502600506d00600621600501a00502800600621600501d005", + "0x21600503900501a00615e00521600503f0052cc006006216005146005152", + "0x14800603a00521600503a005031006017005216005017005146006039005", + "0x3c03a01703901200515e00521600515e0052cd00603c00521600503c005", + "0x52160050060bd00600621600503100505100600621600500601200615e", + "0x514600614e00521600502a00501a00616200521600504a0052f900604a", + "0x521600520700514800604400521600520800503100615000521600520a", + "0x512f00615600521600516200519d00604700521600520d0052f7006152", + "0x62160050060c400600621600500601200616800532104c00521600c156", + "0x50062ef00616d04e00c21600504700504400600621600504c005051006", + "0x615000521600515000514600614e00521600514e00501a006050005216", + "0x502600518d006152005216005152005148006044005216005044005031", + "0x2616d15204415014e0190ba00605000521600505000502d006026005216", + "0x17400532205700521600c055005070006055172052051170012216005050", + "0x21600517000501a006059005216005057005196006006216005006012006", + "0x14800617a00521600505200503100605b005216005051005146006178005", + "0x21600505900519d00617f00521600504e0052f700605d005216005172005", + "0x21600504e0051520060062160050060120060063230050061b0006181005", + "0x501a00502800600621600501d00506d00600621600501200520a006006", + "0x14600617000521600517000501a0060610052160051740052cc006006216", + "0x216005172005148006052005216005052005031006051005216005051005", + "0x60120060611720520511700120050610052160050610052cd006172005", + "0x2600506d0060062160051680050510060062160050060c4006006216005", + "0x1a0061860052160051850052f90061850052160050060bd006006216005", + "0x21600504400503100605b00521600515000514600617800521600514e005", + "0x19d00617f0052160050470052f700605d00521600515200514800617a005", + "0x601200606700532406500521600c18100512f006181005216005186005", + "0x506d00600621600501200520a006006216005065005051006006216005", + "0x20800600621600517f00515200600621600501a00502800600621600501d", + "0x6b00521600506b00502d00606b005216005006314006069005216005006", + "0x6d00c13d00606d00521600500613b00618a00521600506b06900c02f006", + "0x521600517800501a0060ba00521600518d0052cc00618d00521600518a", + "0x514800617a00521600517a00503100605b00521600505b005146006178", + "0xba05d17a05b1780120050ba0052160050ba0052cd00605d00521600505d", + "0x1921600517f0050fc006006216005067005051006006216005006012006", + "0x1d0052f30061a101200c2160050120051050061a007619d19a072196070", + "0x52160050060bd00607b0052160051a21a100c2e60061a201d00c216005", + "0x514600617800521600517800501a0061a80052160051a40053090061a4", + "0x521600505d00514800617a00521600517a00503100605b00521600505b", + "0x193150061a80052160051a800519d00607b00521600507b0052e700605d", + "0x1901a00c15600608d08c0191ab07e0122160051a807b1a005d17a05b178", + "0x21600500601200608f00532508e00521600c08d005316006019005216005", + "0x60bd00600621600509100505100609109000c21600508e005318006006", + "0x21600509301d012125319006093005216005092005309006092005216005", + "0x7e00501a00609500521600509007619d19a072196070019150006094005", + "0x8c00521600508c0051480061ab0052160051ab00514600607e005216005", + "0x9601021600509409508c1ab07e01231a006094005216005094005219006", + "0x621600500601200609f00532605f00521600c09c00518600609c09b1b5", + "0x50060bd0060062160050a10050510060a109700c21600505f0052da006", + "0x1c10052160051be00521b0061be0052160051bd09700c2df0061bd005216", + "0x190050310061b50052160051b500514600609600521600509600501a006", + "0x1c10052160051c10052cd00609b00521600509b005148006019005216005", + "0x521600509f0052cc0060062160050060120061c109b0191b5096012005", + "0x50310061b50052160051b500514600609600521600509600501a0060a6", + "0x52160050a60052cd00609b00521600509b005148006019005216005019", + "0x2160050700050fe0060062160050060120060a609b0191b50960120050a6", + "0x519d00510100600621600507600510300600621600501d00506d006006", + "0x19600515500600621600507200515800600621600519a0051f2006006216", + "0x1a0060a800521600508f0052cc00600621600501200520a006006216005", + "0x2160050190050310061ab0052160051ab00514600607e00521600507e005", + "0x120050a80052160050a80052cd00608c00521600508c005148006019005", + "0x6d00600621600501200520a0060062160050060120060a808c0191ab07e", + "0x600621600502600506d00600621600501a00502800600621600501d005", + "0x21600502a00501a0061bc00521600513b0052cc00600621600520d005152", + "0x14800620800521600520800503100620a00521600520a00514600602a005", + "0x20720820a02a0120051bc0052160051bc0052cd006207005216005207005", + "0x21600501000515200600621600501200520a0060062160050060120061bc", + "0x50230052cc00600621600501a00502800600621600501d00506d006006", + "0x601e00521600501e00514600600600521600500600501a0060aa005216", + "0x50aa0052cd0061e90052160051e900514800600c00521600500c005031", + "0x1900600500521600500500501d0060aa1e900c01e0060120050aa005216", + "0x1200601200532701000521600c12500501e00612500c00c216005005005", + "0x601200601a00532901901d00c21600c01000600c328006006216005006", + "0x601d00521600501d00501a00601e00521600501900532a006006216005", + "0x1e00c01d12500501e00521600501e00532b00600c00521600500c00501d", + "0x52160051e900532c0061e90052160050060bd006006216005006012006", + "0x532b00600c00521600500c00501d00601a00521600501a00501a006020", + "0x1200532c00600621600500601200602000c01a125005020005216005020", + "0xc00521600500c00501d00600600521600500600501a006021005216005", + "0x1900521600500600600602100c00612500502100521600502100532b006", + "0x60062160050060c400600621600500600c00601e00521600500632d006", + "0x12500500c126006125005216005125005148006005005216005005005146", + "0x601200602300532e01a00521600c0210050f50060210201e9125216005", + "0x602602500c21600501000504400620d005216005006208006006216005", + "0x502800517200602a02800c21600520d00505200620c00521600500632f", + "0x14600600600521600500600501a00620a00521600502a005055006006216", + "0x2160050120053300060200052160050200051480061e90052160051e9005", + "0x620c00521600520c00502d00620800521600520800508c00620801200c", + "0x601933100601a00521600501a01e00c21800620a00521600520a00501d", + "0x521600c13b00504a00613b02f02d20701021600520a20c2080260201e9", + "0x4c00603100521600513d00516200600621600500601200614100533213d", + "0x521600500620d00600621600514600516800614814600c216005031005", + "0x501a0060390052160050350053330060350052160051480051e900614a", + "0x521600514a0050260060390052160050390051b4006207005216005207", + "0x3c00521600c03a00533500603a01700c21600514a03920712533400614a", + "0x50bf00603d00521600503c00533700600621600500601200614b005336", + "0x14e0192160050250050fc00604000521600500633800603f00521600503d", + "0x503f0050c100616204a00c21600504700533900615e156047152044150", + "0x602d00521600502d00514600601700521600501700501a00604c005216", + "0x504c00502d00602f00521600502f00514800600c00521600500c005031", + "0x16202f00c02d01701d33a00604c16800c216005168005105006168005216", + "0x17200533b05200521600c05100508f00605117005016d04e012216005168", + "0x216005055005330006055005216005052005090006006216005006012006", + "0x60062160051740051ab00605917400c21600505700509100605705500c", + "0x505b0052f100605b00521600517800533d00617800521600505900533c", + "0x617f00521600505d0050c100600621600517a00520a00605d17a00c216", + "0x2160050062ef00600621600518100520a00606118100c21600517f0052f1", + "0xc100600621600518600520a00606518600c2160051850052f1006185005", + "0x506906700c33e0060690052160050650050c1006067005216005061005", + "0x502d0060062160050060b400618a00521600501a00516100606b005216", + "0x21600500601200606d00534000621600c06b00533f00606b00521600506b", + "0xc2e600618d04c00c21600504c0051050060062160050550051ab006006", + "0x52160050700052f90060700052160050060bd0060ba00521600518a18d", + "0x503100616d00521600516d00514600604e00521600504e00501a006196", + "0x52160050ba0052e7006170005216005170005148006050005216005050", + "0x51960ba15617005016d04e0192fb00619600521600519600519d0060ba", + "0x120061a20053411a100521600c1a00052fc0061a007619d19a072012216", + "0x62160051a40050510061a407b00c2160051a10052fe006006216005006", + "0x21600507200501a0061a800521600515e07b04a15204415014e019150006", + "0x14800608c00521600519d0050310061ab00521600519a00514600607e005", + "0x21600504000508c00608e0052160051a80052f700608d005216005076005", + "0x62160050060c40060062160050060120060063420050061b000608f005", + "0x2160050190050280060062160050120051ab0060062160050400051ab006", + "0x514e0050fe00600621600515e00515300600621600504c00520a006006", + "0x440051580060062160051520051f200600621600504a005101006006216", + "0x1a0060900052160051a20052cc006006216005150005155006006216005", + "0x21600519d00503100619a00521600519a005146006072005216005072005", + "0x120050900052160050900052cd00607600521600507600514800619d005", + "0x1ab00600621600506d00534300600621600500601200609007619d19a072", + "0x609100521600515e15604a15204415014e019150006006216005040005", + "0x16d00514600604e00521600504e00501a00609309200c216005091005044", + "0x17000521600517000514800605000521600505000503100616d005216005", + "0x502d00609404c00c21600504c00510500618a00521600518a00518d006", + "0x9609501221600509418a09317005016d04e0190ba006094005216005094", + "0x621600500601200609f00534405f00521600c09c00507000609c09b1b5", + "0x61bd0053450a100521600c09700512f00609700521600505f005196006", + "0x1ab0060062160050a10050510060062160050060c4006006216005006012", + "0x60062160050920051520060062160050120051ab006006216005055005", + "0x1be00521600500620800600621600504c00520a006006216005019005028", + "0x1c11be00c02f0061c10052160051c100502d0061c1005216005006346006", + "0x1bc0052160050a60a800c13d0060a800521600500613b0060a6005216005", + "0x9600514600609500521600509500501a0060aa0052160051bc0052cc006", + "0x9b00521600509b0051480061b50052160051b5005031006096005216005", + "0x2160050060120060aa09b1b50960950120050aa0052160050aa0052cd006", + "0x9600514600607e00521600509500501a0060062160051bd005051006006", + "0x8d00521600509b00514800608c0052160051b50050310061ab005216005", + "0x8e0050fc00608f00521600505500508c00608e0052160050920052f7006", + "0x14600607e00521600507e00501a0060b41b90b20980a90b00ac019216005", + "0x21600508d00514800608c00521600508c0050310061ab0052160051ab005", + "0x60b60052160050b600502d0060b604c00c21600504c00510500608d005", + "0x7e0193470061b60052160051b600508c0061b601200c216005012005330", + "0x501d01900c1560061b01b201d1b40b80122160051b60b60b208d08c1ab", + "0x62160050060120061ac0053490bd00521600c1b000534800601d005216", + "0x50bf0050510060bf1ae00c2160050bd0052170060062160050060c4006", + "0x1ae0980a90b00ac0191500060c100521600508f01204c12534a006006216", + "0x2160051b40051460060b80052160050b800501a0061aa0052160050b41b9", + "0x34c0060c10052160050c100534b0061b20052160051b20051480061b4005", + "0x521600c1a50051860061a50c60c41a70102160050c11aa1b21b40b8012", + "0x60ca19c00c2160050c80052da0060062160050060120061a300534d0c8", + "0x2160050cc19c00c2df0060cc0052160050060bd0060062160050ca005051", + "0x1460061a70052160051a700501a00619900521600519b00521b00619b005", + "0x2160050c600514800601d00521600501d0050310060c40052160050c4005", + "0x60120061990c601d0c41a70120051990052160051990052cd0060c6005", + "0x61a70052160051a700501a00619f0052160051a30052cc006006216005", + "0x50c600514800601d00521600501d0050310060c40052160050c4005146", + "0x1200619f0c601d0c41a701200519f00521600519f0052cd0060c6005216", + "0x51530060062160050ac0050fe0060062160050060c4006006216005006", + "0x1f200600621600504c00520a0060062160051b90051030060062160050b4", + "0x60062160050b00051550060062160050a9005158006006216005098005", + "0x52160051ac0052cc0060062160050120051ab00600621600508f0051ab", + "0x50310061b40052160051b40051460060b80052160050b800501a0060cf", + "0x52160050cf0052cd0061b20052160051b200514800601d00521600501d", + "0x62160050060c40060062160050060120060cf1b201d1b40b80120050cf", + "0x2160050920051520060062160050120051ab0060062160050550051ab006", + "0x509f0052cc00600621600504c00520a006006216005019005028006006", + "0x609600521600509600514600609500521600509500501a0060d1005216", + "0x50d10052cd00609b00521600509b0051480061b50052160051b5005031", + "0x400051ab0060062160050060120060d109b1b50960950120050d1005216", + "0x51580060062160051520051f2006006216005150005155006006216005", + "0x2800600621600504a0051010060062160050120051ab006006216005044", + "0x600621600515e00515300600621600504c00520a006006216005019005", + "0x621600501a00534e00600621600515600510300600621600514e0050fe", + "0x16d00514600604e00521600504e00501a0061950052160051720052cc006", + "0x17000521600517000514800605000521600505000503100616d005216005", + "0x21600500601200619517005016d04e0120051950052160051950052cd006", + "0x501a00534e0060062160050120051ab006006216005025005152006006", + "0x501a00619300521600514b0052cc006006216005019005028006006216", + "0x521600500c00503100602d00521600502d005146006017005216005017", + "0x170120051930052160051930052cd00602f00521600502f00514800600c", + "0x51ab00600621600502500515200600621600500601200619302f00c02d", + "0x2cc00600621600501900502800600621600501a00534e006006216005012", + "0x21600502d00514600620700521600520700501a0060d2005216005141005", + "0x2cd00602f00521600502f00514800600c00521600500c00503100602d005", + "0x60062160050060120060d202f00c02d2070120050d20052160050d2005", + "0x62160050100051520060062160050120051ab006006216005019005028", + "0x500600501a0060d40052160050230052cc00600621600501e00534f006", + "0x600c00521600500c0050310061e90052160051e9005146006006005216", + "0xc1e90060120050d40052160050d40052cd006020005216005020005148", + "0x1d0050fe0060210201e901e01a01901d0192160050100050fc0060d4020", + "0x51f200600621600501a005158006006216005019005155006006216005", + "0x1a00600621600502100515300600621600502000510300600621600501e", + "0x21600500c005031006005005216005005005146006006005216005006005", + "0x33a00601200521600501200502d00612500521600512500514800600c005", + "0xc20c00508f00620c02602520d0230122160050121e912500c00500601d", + "0x20a00521600502800509000600621600500601200602a005350028005216", + "0x2300501a00620700521600520800535200620800521600520a005351006", + "0x2500521600502500503100620d00521600520d005146006023005216005", + "0x20d023012005207005216005207005353006026005216005026005148006", + "0x501a00602d00521600502a005354006006216005006012006207026025", + "0x521600502500503100620d00521600520d005146006023005216005023", + "0x2301200502d00521600502d005353006026005216005026005148006025", + "0x12500521600500c00533d00600c00521600500600533c00602d02602520d", + "0x1200502d00600621600501000520a00601201000c2160051250052f1006", + "0xc21600500501200c21a00600500521600500500504e006012005216005", + "0x1a01d00c00501a0052160050060bd00600621600501900505100601901d", + "0x621600500600c0061e900521600500635500601a005216005006006006", + "0x20c02602520d0230210200192160050100050fc0060062160050060c4006", + "0x514600600600521600500600501a00602a02800c216005021005356006", + "0x2a125005006010357006125005216005125005148006005005216005005", + "0x1200613b00535802f00521600c02d00508f00602d20720820a010216005", + "0x614100521600502f00509000613d005216005006208006006216005006", + "0x514600505500600621600503100517200614603100c21600513d005052", + "0xb400603500521600514a00530900614a0052160050060bd006148005216", + "0x521600514800501d00603901200c216005012005105006006216005006", + "0x21600c03514803914120720801d35900603500521600503500519d006148", + "0x3c00c35b00600621600500601200604003f03d12535a14b03c03a017010", + "0x521600501700514600615000521600514e00535c00614e00521600514b", + "0x61b000604700521600515000535d00615200521600503a005148006044", + "0x514600615600521600504000535f00600621600500601200600635e005", + "0x521600515600535d00615200521600503f00514800604400521600503d", + "0x16200536204a00521600c15e00536100615e005216005047005360006047", + "0x21600504c00536400604c00521600504a005363006006216005006012006", + "0x601e00521600501e1e900c36500600621600516800516800616801e00c", + "0x4400514600616d00521600504e00536600604e01e00c21600501e0052f3", + "0x16d00521600516d005367006152005216005152005148006044005216005", + "0x1036800605000521600505000508c00605001d00c21600501d005330006", + "0x536917200521600c0520050b000605205117012521600505016d152044", + "0x21600501e0052f30060062160051720050a9006006216005006012006055", + "0x617000521600517000514600617400521600505700536a00605701e00c", + "0xf500605b17805912521600505117000c126006051005216005051005148", + "0x2160050060c400600621600500601200605d00536b17a00521600c05b005", + "0xbd00618100521600517f17400c2e600617f00521600517a005161006006", + "0x521600520a00501a0061850052160050610052f9006061005216005006", + "0x514800600c00521600500c00503100605900521600505900514600620a", + "0x521600518500519d0061810052160051810052e7006178005216005178", + "0x606906701906518601221600518518102617800c05920a0192fb006185", + "0x618a00536c06b00521600c0690052fc00601900521600501901a00c156", + "0x21600518d00505100618d06d00c21600506b0052fe006006216005006012", + "0x700052160050ba01d01212536d0060ba01e00c21600501e0052f3006006", + "0x21600518600501a00619600521600520c06d02520d023028020019150006", + "0x36e006067005216005067005148006065005216005065005146006186005", + "0x19d19a07201021600507019606706518601236f006070005216005070005", + "0x2da0060062160050060120061a10053701a000521600c076005186006076", + "0x501e1a200c37100600621600507b00505100607b1a200c2160051a0005", + "0x607200521600507200501a0061a80052160051a40053720061a4005216", + "0x519d00514800601900521600501900503100619a00521600519a005146", + "0x120061a819d01919a0720120051a80052160051a800537300619d005216", + "0x607e0052160051a100537400600621600501e00506d006006216005006", + "0x501900503100619a00521600519a00514600607200521600507200501a", + "0x507e00521600507e00537300619d00521600519d005148006019005216", + "0x600621600501e00506d00600621600500601200607e19d01919a072012", + "0x621600501200520a00600621600520c0051530060062160050200050fe", + "0x21600502300515800600621600520d0051f2006006216005025005101006", + "0x518a00537400600621600501d0051ab006006216005028005155006006", + "0x606500521600506500514600618600521600518600501a0061ab005216", + "0x51ab005373006067005216005067005148006019005216005019005031", + "0x50060c40060062160050060120061ab0670190651860120051ab005216", + "0x200050fe00600621600501e00506d006006216005028005155006006216", + "0x51ab00600621600502300515800600621600520d0051f2006006216005", + "0x10100600621600501200520a00600621600520c00515300600621600501d", + "0x600621600502600510300600621600501a005028006006216005025005", + "0x21600520a00501a00608c00521600505d00537400600621600517400520a", + "0x14800600c00521600500c00503100605900521600505900514600620a005", + "0x17800c05920a01200508c00521600508c005373006178005216005178005", + "0x62160050280051550060062160050060c400600621600500601200608c", + "0x21600520d0051f20060062160050200050fe00600621600501e00506d006", + "0x520c00515300600621600501d0051ab006006216005023005158006006", + "0x1a00502800600621600502500510100600621600501200520a006006216", + "0x1a00608d005216005055005374006006216005026005103006006216005", + "0x21600500c00503100617000521600517000514600620a00521600520a005", + "0x1200508d00521600508d00537300605100521600505100514800600c005", + "0x51550060062160050060c400600621600500601200608d05100c17020a", + "0x15800600621600520d0051f20060062160050200050fe006006216005028", + "0x600621600520c00515300600621600501d0051ab006006216005023005", + "0x621600501a00502800600621600502500510100600621600501200520a", + "0x2160051620053740060062160051e9005375006006216005026005103006", + "0x3100604400521600504400514600620a00521600520a00501a00608e005", + "0x21600508e00537300615200521600515200514800600c00521600500c005", + "0x502800515500600621600500601200608e15200c04420a01200508e005", + "0x20d0051f20060062160050200050fe0060062160051e9005375006006216", + "0x515300600621600501d0051ab006006216005023005158006006216005", + "0x2800600621600502500510100600621600501200520a00600621600520c", + "0x8f00521600513b00537400600621600502600510300600621600501a005", + "0xc00503100620800521600520800514600620a00521600520a00501a006", + "0x8f00521600508f00537300620700521600520700514800600c005216005", + "0x500c00536a00600c00521600500600537600608f20700c20820a012005", + "0x600621600501000520a00601201000c2160051250052f1006125005216", + "0x501200c21a00600500521600500500504e00601200521600501200502d", + "0x501a0052160050060bd00600621600501900505100601901d00c216005", + "0x50060c400600621600500600c00601a00521600500600600601a01d00c", + "0x2001200c2160050120052f30061e901e00c216005010005044006006216", + "0x12500514800600500521600500500514600602100521600502000536a006", + "0xc0250050f500602520d02312521600512500500c126006125005216005", + "0x2800521600502600516100600621600500601200620c005377026005216", + "0xc00503100602300521600502300514600600600521600500600501a006", + "0x2100521600502100502d00620d00521600520d00514800600c005216005", + "0x2160050280211e920d00c02300601937800602800521600502800518d006", + "0xc2070050b000601900521600501901a00c15600620720801920a02a012", + "0x600621600502d0050a900600621600500601200602f00537902d005216", + "0x20a00514600613d00521600513b00536600613b01200c2160050120052f3", + "0x13d00521600513d00536700620800521600520800514800620a005216005", + "0x1036800614100521600514100508c00614101d00c21600501d005330006", + "0x537a14a00521600c1480050b000614814603112521600514113d20820a", + "0x21600501d00533000600621600514a0050a9006006216005006012006035", + "0x2a00521600502a00501a00601700521600501203900c37b00603901d00c", + "0x1700537c006146005216005146005148006031005216005031005146006", + "0x603d14b03c03a01021600501701e14603102a01237d006017005216005", + "0x3f0052da00600621600500601200604000537e03f00521600c03d005186", + "0x521600501d14e00c37f00600621600515000505100615014e00c216005", + "0x514600603a00521600503a00501a006152005216005044005380006044", + "0x521600514b00514800601900521600501900503100603c00521600503c", + "0x500601200615214b01903c03a01200515200521600515200538100614b", + "0x501a00604700521600504000538200600621600501d0051ab006006216", + "0x521600501900503100603c00521600503c00514600603a00521600503a", + "0x3a01200504700521600504700538100614b00521600514b005148006019", + "0x515200600621600501d0051ab00600621600500601200604714b01903c", + "0x615600521600503500538200600621600501200506d00600621600501e", + "0x501900503100603100521600503100514600602a00521600502a00501a", + "0x5156005216005156005381006146005216005146005148006019005216", + "0x600621600501d0051ab00600621600500601200615614601903102a012", + "0x521600502f00538200600621600501200506d00600621600501e005152", + "0x503100620a00521600520a00514600602a00521600502a00501a00615e", + "0x521600515e005381006208005216005208005148006019005216005019", + "0x21600501200506d00600621600500601200615e20801920a02a01200515e", + "0x501a00502800600621600501e00515200600621600501d0051ab006006", + "0x20c0053820060062160051e900515200600621600502100520a006006216", + "0x2300521600502300514600600600521600500600501a00604a005216005", + "0x4a00538100620d00521600520d00514800600c00521600500c005031006", + "0x120100192160051250050fc00604a20d00c02300601200504a005216005", + "0x21600500600501a00602102000c21600501d0053830061e901e01a01901d", + "0x38400600c00521600500c005148006005005216005005005146006006005", + "0x20c00521600c02600538500602602520d02301021600502100c005006010", + "0x638800602a00521600520c005387006006216005006012006028005386", + "0x2a00c21600502a0052cf00602300521600502300501a00620a005216005", + "0x12538900620a00521600520a005026006208005216005208005026006208", + "0x613b00538a02f00521600c02d00538500602d20700c21600520a208023", + "0x521600520d00514600613d00521600502f005387006006216005006012", + "0x1038b00613d00521600513d00502600602500521600502500514800620d", + "0x538d14800521600c14600538c00614603114112521600513d02002520d", + "0x3900505100603903500c21600514800538e00600621600500601200614a", + "0xc38f0060170052160051e901e01a019035012010019150006006216005", + "0x21600520700501a00603c00521600503a00539000603a00521600502a017", + "0x220006031005216005031005148006141005216005141005146006207005", + "0x2300600621600500601200603c03114120701000503c00521600503c005", + "0x600621600501e0051030060062160051e900515300600621600502a005", + "0x62160050100050fe0060062160050190051f200600621600501a005101", + "0x520700501a00614b00521600514a005391006006216005012005155006", + "0x6031005216005031005148006141005216005141005146006207005216", + "0x600621600500601200614b03114120701000514b00521600514b005220", + "0x621600502a0050230060062160050100050fe006006216005012005155", + "0x21600501a00510100600621600501e0051030060062160051e9005153006", + "0x513b0053910060062160050200051580060062160050190051f2006006", + "0x620d00521600520d00514600620700521600520700501a00603d005216", + "0x2520d20701000503d00521600503d005220006025005216005025005148", + "0x2160050100050fe00600621600501200515500600621600500601200603d", + "0x501a00510100600621600501e0051030060062160051e9005153006006", + "0x280053910060062160050200051580060062160050190051f2006006216", + "0x20d00521600520d00514600602300521600502300501a00603f005216005", + "0x20d02301000503f00521600503f005220006025005216005025005148006", + "0x1250051b600612500521600500c0051e90060062160050060c400603f025", + "0x2160050120050b800600621600500601200601d00539201201000c21600c", + "0x1b000601e0052160050190051b200601a0052160050100051b4006019005", + "0x51ac0061e90052160050060bd006006216005006012006006393005006", + "0x52160050200051b200601a00521600501d0051b40060200052160051e9", + "0x51ae00602100521600502100501d00602100521600501a00505500601e", + "0x2160050230050bf00600621600500601200620d00539402300521600c01e", + "0x501a00620c0052160050250050c1006026005216005006208006025005", + "0x521600502100501d006005005216005005005146006006005216005006", + "0x1211500620c00521600520c00502d00602600521600502600504e006021", + "0x39520800521600c20a0050a600620a02a02812521600520c026021005006", + "0xc39600602f02d00c2160052080050a8006006216005006012006207005", + "0x21600502800501a00613d00521600513b00539700613b00521600502f02d", + "0x12500513d00521600513d00539800602a00521600502a005146006028005", + "0x501a00614100521600520700539900600621600500601200613d02a028", + "0x521600514100539800602a00521600502a005146006028005216005028", + "0x600621600520d00505100600621600500601200614102a028125005141", + "0x514602100c39600614600521600503100539a0060310052160050060bd", + "0x600600521600500600501a00614a005216005148005397006148005216", + "0x14a00500612500514a00521600514a005398006005005216005005005146", + "0x500500514800600600521600500600514600600621600500c005152006", + "0x21600c0190050f500601901d01212521600500500600c126006005005216", + "0x61e900521600501a00516100600621600500601200601e00539b01a005", + "0x502100518d00600621600502000506d00602102000c2160051e9005096", + "0x2300c21600512502100c1b500612500521600512500504e006021005216", + "0x517200602602500c21600502300505200600621600520d00505100620d", + "0x20c00521600520c00501d00620c005216005026005055006006216005025", + "0x601200620720820a12539d02a02800c21600c01020c01d01201039c006", + "0x14600602f00521600502d00539e00602d0052160050060bd006006216005", + "0x21600502f00539f00613d00521600502a00514800613b005216005028005", + "0x2160052070053a10060062160050060120060063a00050061b0006141005", + "0x39f00613d00521600520800514800613b00521600520a005146006031005", + "0x21600c1460050b00061460052160051410053a2006141005216005031005", + "0xbd0060062160051480050a900600621600500601200614a0053a3148005", + "0x52160050390053a50060390052160050350053a4006035005216005006", + "0x53a600613d00521600513d00514800613b00521600513b005146006017", + "0x14a0053a700600621600500601200601713d13b125005017005216005017", + "0x13d00521600513d00514800613b00521600513b00514600603a005216005", + "0x600621600500601200603a13d13b12500503a00521600503a0053a6006", + "0x521600501e0053a7006006216005125005172006006216005010005168", + "0x53a600601d00521600501d00514800601200521600501200514600603c", + "0x12500c00c21600c00500600c3a800603c01d01212500503c00521600503c", + "0x501a0060120052160051250053aa0060062160050060120060100053a9", + "0x60063ac0050061b00060190052160050120053ab00601d00521600500c", + "0x1e00521600501a0053ad00601a0052160050060bd006006216005006012", + "0x1901d00c00501900521600501e0053ab00601d00521600501000501a006", + "0x21600c1250051b600612500521600500c0051e90060062160050060c4006", + "0x190052160050120050b800600621600500601200601d0053ae01201000c", + "0x50061b000601e0052160050190051b200601a0052160050100051b4006", + "0x51e90051ac0061e90052160050060bd0060062160050060120060063af", + "0x601e0052160050200051b200601a00521600501d0051b4006020005216", + "0xc01e0051ae00602100521600502100501d00602100521600501a005055", + "0x250052160050230050bf00600621600500601200620d0053b0023005216", + "0x500600501a00620c0052160050250050c10060260052160050063b1006", + "0x602100521600502100501d006005005216005005005146006006005216", + "0x50060123b300620c00521600520c00502d0060260052160050260053b2", + "0x2070053b520800521600c20a0053b400620a02a02812521600520c026021", + "0xc02f0053b700602f02d00c2160052080053b6006006216005006012006", + "0x14100c21600513b0053b900600621600500601200613d0053b813b005216", + "0x1460053bc0061460052160050310053bb0060062160051410053ba006031", + "0x521600514a0053be00614a00521600514802d00c3bd006148005216005", + "0x53bf00602a00521600502a00514600602800521600502800501a006035", + "0x13d0053c000600621600500601200603502a028125005035005216005035", + "0x52160050170053be00601700521600503902d00c3bd006039005216005", + "0x53bf00602a00521600502a00514600602800521600502800501a00603a", + "0x2070053c100600621600500601200603a02a02812500503a00521600503a", + "0x2a00521600502a00514600602800521600502800501a00603c005216005", + "0x600621600500601200603c02a02812500503c00521600503c0053bf006", + "0x521600514b0053c000614b0052160050060bd00600621600520d005051", + "0x1a00604000521600503f0053be00603f00521600503d02100c3bd00603d", + "0x2160050400053bf006005005216005005005146006006005216005006005", + "0x52160050060d9006023005216005006006006040005006125005040005", + "0x21600500600c00602a00521600500600500620c0052160050060d7006025", + "0x500514600620820a00c21600501d0050440060062160050060c4006006", + "0x12521600501200500c126006012005216005012005148006005005216005", + "0x621600500601200613d0053c213b00521600c02f0050f500602f02d207", + "0x20700514600600600521600500600501a00614100521600513b005161006", + "0x2d00521600502d005148006125005216005125005031006207005216005", + "0x518d00603100521600503100502d00603101900c216005019005105006", + "0x14814601221600514103120802d125207006019378006141005216005141", + "0x521600502802a00c15e00602100521600502102300c15600614a028021", + "0xa90060062160050060120060390053c303500521600c14a0050b0006028", + "0x521600514800514600614600521600514600501a006006216005035005", + "0x1d00601701a00c21600501a005147006010005216005010005199006148", + "0x3d14b03c03a0102160050170101481460103c4006017005216005017005", + "0x514f0060062160050060120060400053c503f00521600c03d005107006", + "0x521600503c00514600603a00521600503a00501a00614e00521600503f", + "0x514800614b00521600514b00519900600c00521600500c00519b00603c", + "0x21600515000502d00615001900c216005019005105006028005216005028", + "0x604401e00c21600501e0053c600614e00521600514e00502d006150005", + "0x15200501d0061521e900c2160051e900514700604400521600504400519f", + "0x2814b00c03c03a1e93c70060200052160050200050cf006152005216005", + "0x520d02500c18200604a15e02620d15604701d21600502015204414e150", + "0x16200521600c04a0050b000602600521600502620c00c0e300620d005216", + "0x190103c90060062160051620050a900600621600500601200604c0053c8", + "0x515600514600604700521600504700501a0061680052160051e901e01a", + "0x61680052160051680053ca00615e00521600515e005148006156005216", + "0x21600c17000518600617005016d04e01021600516820a15e1560470123cb", + "0x5517200c2160050510052da0060062160050060120060520053cc051005", + "0x505717200c2df0060570052160050060bd006006216005055005051006", + "0x604e00521600504e00501a00605900521600517400521b006174005216", + "0x502100503100620d00521600520d00519b00616d00521600516d005146", + "0x6050005216005050005148006026005216005026005199006021005216", + "0x500601200605905002602120d16d04e0190050590052160050590052cd", + "0x14600604e00521600504e00501a0061780052160050520052cc006006216", + "0x21600502100503100620d00521600520d00519b00616d00521600516d005", + "0x2cd006050005216005050005148006026005216005026005199006021005", + "0x21600500601200617805002602120d16d04e019005178005216005178005", + "0x501e0050cc0060062160051e900516800600621600520a005152006006", + "0x4c0052cc00600621600501900520a00600621600501a005168006006216", + "0x15600521600515600514600604700521600504700501a00605b005216005", + "0x2600519900602100521600502100503100620d00521600520d00519b006", + "0x5b00521600505b0052cd00615e00521600515e005148006026005216005", + "0x501a00516800600621600500601200605b15e02602120d156047019005", + "0x20a00515200600621600501900520a00600621600501e0050cc006006216", + "0x50df0060062160050250051840060062160051e9005168006006216005", + "0x617a0052160050400052cc0060062160050200050ca00600621600520c", + "0x500c00519b00603c00521600503c00514600603a00521600503a00501a", + "0x614b00521600514b00519900602100521600502100503100600c005216", + "0xc03c03a01900517a00521600517a0052cd006028005216005028005148", + "0x50cc00600621600501a00516800600621600500601200617a02814b021", + "0x16800600621600520a00515200600621600501900520a00600621600501e", + "0x600621600520c0050df0060062160050250051840060062160051e9005", + "0x21600514600501a00605d0052160050390052cc0060062160050200050ca", + "0x3100600c00521600500c00519b006148005216005148005146006146005", + "0x216005028005148006010005216005010005199006021005216005021005", + "0x605d02801002100c14814601900505d00521600505d0052cd006028005", + "0x600621600501e0050cc00600621600501a005168006006216005006012", + "0x62160051e900516800600621600520a00515200600621600501900520a", + "0x2160050200050ca00600621600520c0050df006006216005025005184006", + "0x520800515200600621600502a00502a006006216005023005028006006", + "0x14600600600521600500600501a00617f00521600513d0052cc006006216", + "0x21600512500503100600c00521600500c00519b006207005216005207005", + "0x2cd00602d00521600502d005148006010005216005010005199006125005", + "0x21600500600600617f02d01012500c20700601900517f00521600517f005", + "0x500605b0060250052160050060d70060230052160050060d9006020005", + "0x600c0062080052160050063cd00602a00521600500600500620c005216", + "0x14600602d20700c21600501d0050440060062160050060c4006006216005", + "0x501200500c126006012005216005012005148006005005216005005005", + "0x50060120060310053ce14100521600c13d0050f500613d13b02f125216", + "0x14600600600521600500600501a006146005216005141005161006006216", + "0x21600513b00514800612500521600512500503100602f00521600502f005", + "0x614800521600514800502d00614801900c21600501900510500613b005", + "0x1221600514614802d13b12502f00601937800614600521600514600518d", + "0x500601200614b0053cf03c00521600c03a0050b000603a01703903514a", + "0x14e04003f03d0192160052070050fc00600621600503c0050a9006006216", + "0x14a00521600514a00501a00615604700c216005150005339006152044150", + "0x17005148006039005216005039005031006035005216005035005146006", + "0x521600515e00502d00615e01900c216005019005105006017005216005", + "0x15600604c0281e916204a01221600515e15601703903514a01d33a00615e", + "0x4c00508f00602800521600502802a00c15e0061e90052160051e902000c", + "0x62160051680053d100600621600500601200604e0053d016800521600c", + "0x21600504a00501a00605000521600500620d00616d005216005006208006", + "0x22200605000521600505000502600616200521600516200514600604a005", + "0x516d00504e0061700052160051700050cf00617001e00c21600501e005", + "0x53d300617205205112521600516d17005016204a0123d200616d005216", + "0x21600505100501a0060062160050060120060550053d420a00521600c172", + "0x147006010005216005010005199006052005216005052005146006051005", + "0x20a20800c3d500605700521600505700501d00605701a00c21600501a005", + "0x10700605b1780591740102160050570100520510103c400620a005216005", + "0x520a0053d700600621600500601200605d0053d617a00521600c05b005", + "0x600621600506100505100600621600518100502300606118117f125216", + "0x21600517f0050520061850052160050063d800602600521600517a00514f", + "0x1a00606700521600506500505500600621600518600517200606518600c", + "0x21600500c00519b006059005216005059005146006174005216005174005", + "0x10500602800521600502800514800617800521600517800519900600c005", + "0x502600510500606900521600506900502d00606901900c216005019005", + "0x18500521600518500519f00606b00521600506b00502d00606b02600c216", + "0x20c00c17a00601e00521600501e0050cf00606700521600506700501d006", + "0x21600501e06718506b06902817800c0591741e93c7006026005216005026", + "0x700050b000602100521600502102300c1820060700ba18d02106d18a01d", + "0x62160051960050a90060062160050060120060720053d919600521600c", + "0x18d00519900606d00521600506d00514600618a00521600518a00501a006", + "0x1900c2160050190051050060ba0052160050ba00514800618d005216005", + "0x1d3da00602600521600502600502d00619a00521600519a00502d00619a", + "0x520d02500c0e30061a11a020d07619d01221600502619a0ba18d06d18a", + "0x621600500601200607b0053db1a200521600c1a10050b000620d005216", + "0x3d0191500061a400521600501a01900c3dc0060062160051a20050a9006", + "0x14600619d00521600519d00501a0061a800521600515204404714e04003f", + "0x2160051a40052210061a00052160051a0005148006076005216005076005", + "0x518600608d08c1ab07e0102160051a41a81a007619d0123dd0061a4005", + "0x21600508e0052da00600621600500601200608f0053de08e00521600c08d", + "0xc2df0060920052160050060bd00600621600509100505100609109000c", + "0x21600507e00501a00609400521600509300521b006093005216005092090", + "0x3100602100521600502100519b0061ab0052160051ab00514600607e005", + "0x21600508c00514800620d00521600520d0051990061e90052160051e9005", + "0x609408c20d1e90211ab07e0190050940052160050940052cd00608c005", + "0x521600507e00501a00609500521600508f0052cc006006216005006012", + "0x503100602100521600502100519b0061ab0052160051ab00514600607e", + "0x521600508c00514800620d00521600520d0051990061e90052160051e9", + "0x1200609508c20d1e90211ab07e0190050950052160050950052cd00608c", + "0x10300600621600515200515300600621600503d0050fe006006216005006", + "0x600621600514e0051f2006006216005047005101006006216005044005", + "0x621600501a00516800600621600503f005155006006216005040005158", + "0x519d00501a00609600521600507b0052cc00600621600501900520a006", + "0x602100521600502100519b00607600521600507600514600619d005216", + "0x51a000514800620d00521600520d0051990061e90052160051e9005031", + "0x961a020d1e902107619d0190050960052160050960052cd0061a0005216", + "0x621600503d0050fe00600621600501a005168006006216005006012006", + "0x21600501900520a00600621600503f005155006006216005040005158006", + "0x5047005101006006216005044005103006006216005152005153006006", + "0x2600520a0060062160050250050df00600621600514e0051f2006006216", + "0x618a00521600518a00501a0061b50052160050720052cc006006216005", + "0x51e900503100602100521600502100519b00606d00521600506d005146", + "0x60ba0052160050ba00514800618d00521600518d0051990061e9005216", + "0x50060120061b50ba18d1e902106d18a0190051b50052160051b50052cd", + "0x4000515800600621600503d0050fe00600621600501a005168006006216", + "0x515300600621600501900520a00600621600503f005155006006216005", + "0x1f2006006216005047005101006006216005044005103006006216005152", + "0x60062160050230051840060062160050250050df00600621600514e005", + "0x621600520c00506900600621600520a0053df00600621600501e0050ca", + "0x5900514600617400521600517400501a00609b00521600505d0052cc006", + "0x1e90052160051e900503100600c00521600500c00519b006059005216005", + "0x9b0052cd006028005216005028005148006178005216005178005199006", + "0x600621600500601200609b0281781e900c05917401900509b005216005", + "0x621600503d0050fe00600621600501a00516800600621600520c005069", + "0x21600501900520a00600621600503f005155006006216005040005158006", + "0x5047005101006006216005044005103006006216005152005153006006", + "0x230051840060062160050250050df00600621600514e0051f2006006216", + "0x52cc0060062160052080053e000600621600501e0050ca006006216005", + "0x521600505200514600605100521600505100501a00609c005216005055", + "0x51990061e90052160051e900503100600c00521600500c00519b006052", + "0x521600509c0052cd006028005216005028005148006010005216005010", + "0x20c00506900600621600500601200609c0280101e900c05205101900509c", + "0x515800600621600503d0050fe00600621600501a005168006006216005", + "0x15300600621600501900520a00600621600503f005155006006216005040", + "0x6006216005047005101006006216005044005103006006216005152005", + "0x62160050230051840060062160050250050df00600621600514e0051f2", + "0x21600504e0052cc0060062160052080053e000600621600501e0050ca006", + "0x19b00616200521600516200514600604a00521600504a00501a00605f005", + "0x2160050100051990061e90052160051e900503100600c00521600500c005", + "0x1900505f00521600505f0052cd006028005216005028005148006010005", + "0x621600520c00506900600621600500601200605f0280101e900c16204a", + "0x21600501900520a00600621600502a00502a00600621600501a005168006", + "0x50250050df0060062160050200050280060062160052080053e0006006", + "0x20700515200600621600501e0050ca006006216005023005184006006216", + "0x614a00521600514a00501a00609f00521600514b0052cc006006216005", + "0x503900503100600c00521600500c00519b006035005216005035005146", + "0x6017005216005017005148006010005216005010005199006039005216", + "0x500601200609f01701003900c03514a01900509f00521600509f0052cd", + "0x2a00502a00600621600501a00516800600621600520c005069006006216", + "0x53e000600621600501900520a00600621600501e0050ca006006216005", + "0x152006006216005023005184006006216005020005028006006216005208", + "0x600621600502d0051520060062160050250050df006006216005207005", + "0x502f00514600600600521600500600501a0060970052160050310052cc", + "0x612500521600512500503100600c00521600500c00519b00602f005216", + "0x50970052cd00613b00521600513b005148006010005216005010005199", + "0xc21600c00500600c3e100609713b01012500c02f006019005097005216", + "0x60120052160051250053e30060062160050060120060100053e212500c", + "0x3e50050061b00060190052160050120053e400601d00521600500c00501a", + "0x21600501a0053e600601a0052160050060bd006006216005006012006006", + "0xc00501900521600501e0053e400601d00521600501000501a00601e005", + "0x500600501a0060062160050120051520060062160050060c400601901d", + "0x6125005216005125005199006005005216005005005146006006005216", + "0x230210200102160050191250050060103c400601900521600501900501d", + "0x14f0060062160050060120060260053e702500521600c20d00510700620d", + "0x21600502100514600602000521600502000501a00620c005216005025005", + "0x14800602300521600502300519900600c00521600500c00519b006021005", + "0x21600520c00502d00601d00521600501d00502d006010005216005010005", + "0xcf00601e00521600501e00502600601a00521600501a00519f00620c005", + "0x51e901e01a20c01d01002300c0210201e93e80061e90052160051e9005", + "0x613b0053e902f00521600c02d00504a00602d20720820a02a02801d216", + "0x521600513d00505700613d00521600502f005162006006216005006012", + "0x514600602800521600502800501a006031005216005141005174006141", + "0x521600520800519900620a00521600520a00519b00602a00521600502a", + "0x2801d00503100521600503100514a006207005216005207005148006208", + "0x614600521600513b00514100600621600500601200603120720820a02a", + "0x520a00519b00602a00521600502a00514600602800521600502800501a", + "0x620700521600520700514800620800521600520800519900620a005216", + "0x21600500601200614620720820a02a02801d00514600521600514600514a", + "0x501a0050cc00600621600501e0050230060062160051e90050ca006006", + "0x501a00614800521600502600514100600621600501d00520a006006216", + "0x521600500c00519b006021005216005021005146006020005216005020", + "0x514a00601000521600501000514800602300521600502300519900600c", + "0x521600500600501d00614801002300c02102001d005148005216005148", + "0x53ea12500521600c00c00501e00600c00500c216005006005019006006", + "0x1200533f00601212500c216005125005105006006216005006012006010", + "0x600621600512500520a00600621600500601200601d0053eb00621600c", + "0x1a00501e00601a01900c21600500500501900600500521600500500501d", + "0x521600501e0051640060062160050060120061e90053ec01e00521600c", + "0x61b00060230052160050200050e900602100521600501900501d006020", + "0x501d00620d0052160051e90053ee0060062160050060120060063ed005", + "0x601200620d01900c00520d00521600520d0053ef006019005216005019", + "0xc33e00602500521600500610900600621600501d005343006006216005", + "0x21600c02600533f00602600521600502600502d006026005216005025125", + "0x3f100600500521600500500501d00600621600500601200620c0053f0006", + "0x120062080053f320a00521600c02a0053f200602a02800c216005005005", + "0x2100521600502800501d00620700521600520a0050fa006006216005006", + "0x2100501d00602d0052160050230053f40060230052160052070050e9006", + "0x500601200602d02100c00502d00521600502d0053ef006021005216005", + "0x3ef00602800521600502800501d00602f0052160052080053ee006006216", + "0x20c00534300600621600500601200602f02800c00502f00521600502f005", + "0x1d00613d00521600513b0053ee00613b0052160050060bd006006216005", + "0x1200613d00500c00513d00521600513d0053ef006005005216005005005", + "0x500521600500500501d0061410052160050100053ee006006216005006", + "0x1520060062160050060c400614100500c0051410052160051410053ef006", + "0x2000521600501a0051e9006006216005019005173006006216005012005", + "0x502300620d02300c216005021005021006021005216005020005020006", + "0x20c02600c21600502500502100602500521600500620d006006216005023", + "0x520c00502500602800521600520d005025006006216005026005023006", + "0x3f500621600c02a02800c20c00602800521600502800502600602a005216", + "0x21600501e0050230060062160051e90050ca006006216005006012006006", + "0x2160050063f600620a00521600500620800600621600501d00520a006006", + "0x620700521600520820a00c02f00620800521600520800502d006208005", + "0x502f0053f700602f00521600520702d00c13d00602d00521600500613b", + "0x600500521600500500514600600600521600500600501a00613b005216", + "0x501000514800612500521600512500519900600c00521600500c00519b", + "0x613b01012500c00500601d00513b00521600513b00521f006010005216", + "0x14100521600513d0053f800613d0052160050060bd006006216005006012", + "0xc00519b00600500521600500500514600600600521600500600501a006", + "0x1000521600501000514800612500521600512500519900600c005216005", + "0x1e0050260061410052160051410053f900601d00521600501d00502d006", + "0x1012500c00500601e3fa0061e90052160051e90050cf00601e005216005", + "0x521600c03900516f00603903514a14814603101d2160051e901e14101d", + "0x3fc00603c00521600501700516e00600621600500601200603a0053fb017", + "0x21600503100501a00603d00521600514b0053fd00614b00521600503c005", + "0x19900614800521600514800519b006146005216005146005146006031005", + "0x21600503d00521f00603500521600503500514800614a00521600514a005", + "0x3a0053f700600621600500601200603d03514a14814603101d00503d005", + "0x14600521600514600514600603100521600503100501a00603f005216005", + "0x3500514800614a00521600514a00519900614800521600514800519b006", + "0x3f03514a14814603101d00503f00521600503f00521f006035005216005", + "0x500600501a00601201000c21600500c0053fe0060062160050060c4006", + "0x601000521600501000501d006005005216005005005146006006005216", + "0x1a01901d12521600512501000500601016d00612500521600512500504e", + "0x51700060062160050060120061e90053ff01e00521600c01a005050006", + "0x521600501d00501a00600621600502100505100602102000c21600501e", + "0x504e00601200521600501200540000601900521600501900514600601d", + "0x5000602520d02312521600502001201901d010401006020005216005020", + "0x502600517000600621600500601200620c00540202600521600c025005", + "0x521600520a00511300620a00521600502a02800c11100602a02800c216", + "0x514200620d00521600520d00514600602300521600502300501a006208", + "0x20c00514500600621600500601200620820d023125005208005216005208", + "0x20d00521600520d00514600602300521600502300501a006207005216005", + "0x600621600500601200620720d023125005207005216005207005142006", + "0x21600501d00501a00602d0052160051e9005145006006216005012005403", + "0x12500502d00521600502d00514200601900521600501900514600601d005", + "0x50060bd0060062160050100051520060062160050060c400602d01901d", + "0x600600521600500600501a00601900521600501d0053f800601d005216", + "0x512500514800600c00521600500c005199006005005216005005005146", + "0x60190052160050190053f900601200521600501200502d006125005216", + "0x2100504a0060210201e901e01a01221600501901212500c00500601d404", + "0x521600502300516200600621600500601200620d00540502300521600c", + "0x501a00620c005216005026005174006026005216005025005057006025", + "0x52160051e900519900601e00521600501e00514600601a00521600501a", + "0x1a01200520c00521600520c00514a0060200052160050200051480061e9", + "0x1a00602800521600520d00514100600621600500601200620c0201e901e", + "0x2160051e900519900601e00521600501e00514600601a00521600501a005", + "0x1200502800521600502800514a0060200052160050200051480061e9005", + "0xc400600621600500600c0060190052160050060060060280201e901e01a", + "0x521600500500514600601e01a00c216005010005044006006216005006", + "0x210201e912521600512500500c126006125005216005125005148006005", + "0x516100600621600500601200620d00540602300521600c0210050f5006", + "0x600521600500600501a0060260052160050062ef006025005216005023", + "0x2000514800600c00521600500c0050310061e90052160051e9005146006", + "0x2600521600502600502d00602500521600502500518d006020005216005", + "0x15600620a02a01d02820c01221600502602501e02000c1e90060190ba006", + "0x1200620700540720800521600c20a00507000601d00521600501d01900c", + "0x2f00521600c02d00512f00602d005216005208005196006006216005006", + "0x1200506d00600621600502f00505100600621600500601200613b005408", + "0x640900613d00521600500620800600621600501a005152006006216005", + "0x521600514113d00c02f00614100521600514100502d006141005216005", + "0x52cc00614800521600503114600c13d00614600521600500613b006031", + "0x521600502800514600620c00521600520c00501a00614a005216005148", + "0x52cd00602a00521600502a00514800601d00521600501d005031006028", + "0x5100600621600500601200614a02a01d02820c01200514a00521600514a", + "0x603d14b03c03a01703903501921600501a0050fc00600621600513b005", + "0x2800514600620c00521600520c00501a00604003f00c21600503500540a", + "0x504002a02820c01040b00602a00521600502a005148006028005216005", + "0x601200615600540d04700521600c15200540c00615204415014e010216", + "0x4a00521600515e00540e00615e01200c2160050120052f3006006216005", + "0x4a00540f006044005216005044005148006150005216005150005146006", + "0x541000616804c16212521600504a03f04415001021e00604a005216005", + "0x21600504700541200600621600500601200616d00541104e00521600c168", + "0x605205100c21600504e005414006170005216005050005413006050005", + "0x3905101915000617200521600517001200c415006006216005052005051", + "0x514600614e00521600514e00501a00605500521600503d14b03c03a017", + "0x521600517200541600604c00521600504c005148006162005216005162", + "0x17800518600617805917405701021600517205504c16214e012417006172", + "0xc21600505b0052da00600621600500601200617a00541805b00521600c", + "0x5d00c2df0061810052160050060bd00600621600517f00505100617f05d", + "0x521600505700501a00618500521600506100521b006061005216005181", + "0x514800601d00521600501d005031006174005216005174005146006057", + "0x18505901d1740570120051850052160051850052cd006059005216005059", + "0x21600505700501a00618600521600517a0052cc006006216005006012006", + "0x14800601d00521600501d005031006174005216005174005146006057005", + "0x5901d1740570120051860052160051860052cd006059005216005059005", + "0x21600503d00515300600621600501200506d006006216005006012006186", + "0x503a0051f200600621600503c00510100600621600514b005103006006", + "0x47005419006006216005039005155006006216005017005158006006216", + "0x614e00521600514e00501a00606500521600516d0052cc006006216005", + "0x504c00514800601d00521600501d005031006162005216005162005146", + "0x1200606504c01d16214e0120050650052160050650052cd00604c005216", + "0x15300600621600503900515500600621600501200506d006006216005006", + "0x600621600503c00510100600621600514b00510300600621600503d005", + "0x621600503f0050fe00600621600501700515800600621600503a0051f2", + "0x15000514600614e00521600514e00501a0060670052160051560052cc006", + "0x4400521600504400514800601d00521600501d005031006150005216005", + "0x21600500601200606704401d15014e0120050670052160050670052cd006", + "0x52070052cc00600621600501a00515200600621600501200506d006006", + "0x602800521600502800514600620c00521600520c00501a006069005216", + "0x50690052cd00602a00521600502a00514800601d00521600501d005031", + "0x1200506d00600621600500601200606902a01d02820c012005069005216", + "0x515200600621600501900502800600621600501a005152006006216005", + "0x600521600500600501a00606b00521600520d0052cc00600621600501e", + "0x2000514800600c00521600500c0050310061e90052160051e9005146006", + "0x606b02000c1e900601200506b00521600506b0052cd006020005216005", + "0x62160050120051550061e901e01a01901d0120100192160051250050fc", + "0x21600501a0051010060062160050190051f200600621600501d005158006", + "0x500600501a0060062160051e900515300600621600501e005103006006", + "0x600c00521600500c005148006005005216005005005146006006005216", + "0x521600c20d00540c00620d02302102001021600501000c00500601040b", + "0x41300620c00521600502500541200600621600500601200602600541a025", + "0x21600502a00541c00602a00521600502800541b00602800521600520c005", + "0x14800602100521600502100514600602000521600502000501a00620a005", + "0x20a02302102001000520a00521600520a00541d006023005216005023005", + "0x21600502000501a00620800521600502600541e006006216005006012006", + "0x41d006023005216005023005148006021005216005021005146006020005", + "0x100192160051250050fc006208023021020010005208005216005208005", + "0x621600501d0051580060062160050100050fe0061e901e01a01901d012", + "0x21600501e00510300600621600501a0051010060062160050190051f2006", + "0x500514600600600521600500600501a0060062160051e9005153006006", + "0x501200c00500601035700600c00521600500c005148006005005216005", + "0x601200602600541f02500521600c20d00508f00620d023021020010216", + "0x602800521600520c00535100620c005216005025005090006006216005", + "0x502100514600602000521600502000501a00602a005216005028005352", + "0x502a00521600502a005353006023005216005023005148006021005216", + "0x620a00521600502600535400600621600500601200602a023021020010", + "0x502300514800602100521600502100514600602000521600502000501a", + "0x600600620a02302102001000520a00521600520a005353006023005216", + "0x120053300060062160050060c400600621600500600c006019005216005", + "0x21600501e0051ab0061e901e00c21600501a00509100601a01200c216005", + "0x52f100602100521600502000533d0060200052160051e900533c006006", + "0x521600520d0050c100600621600502300520a00620d02300c216005021", + "0x62ef00600621600502600520a00620c02600c2160050250052f1006025", + "0x621600502a00520a00620a02a00c2160050280052f1006028005216005", + "0x20800c33e00620700521600520a0050c100620800521600520c0050c1006", + "0x621600c02d00533f00602d00521600502d00502d00602d005216005207", + "0x13b0052f900613b0052160050060bd00600621600500601200602f005420", + "0x120060064210050061b000614100521600513d00519d00613d005216005", + "0x3090060310052160050060bd00600621600502f005343006006216005006", + "0x21600514100542200614100521600514600519d006146005216005031005", + "0x542314a00521600c14800512f00614800521600514800519d006148005", + "0x2160050120051ab00600621600514a005051006006216005006012006035", + "0x216005006208006006216005010005152006006216005019005028006006", + "0xc02f00601700521600501700502d006017005216005006424006039005", + "0x21600503a03c00c13d00603c00521600500613b00603a005216005017039", + "0x14600600600521600500600501a00603d00521600514b0052cc00614b005", + "0x21600512500514800600c00521600500c005031006005005216005005005", + "0x601200603d12500c00500601200503d00521600503d0052cd006125005", + "0x604003f00c216005010005044006006216005035005051006006216005", + "0x12500500c425006125005216005125005148006005005216005005005146", + "0x601200604700542615200521600c04400521d00604415014e125216005", + "0x615e005216005156005428006156005216005152005427006006216005", + "0x605705517205205117005016d04e16804c16204a02321600515e005429", + "0x621600516800516800600621600504c00542a00600621600504a00520a", + "0x21600505000520a00600621600516d00520a00600621600504e00520a006", + "0x505200516800600621600505100542a00600621600517000542b006006", + "0x57005168006006216005055005023006006216005172005023006006216", + "0x14600600600521600500600501a0061740052160050062ef006006216005", + "0x21600515000514800600c00521600500c00503100614e00521600514e005", + "0xba00617400521600517400502d00616200521600516200518d006150005", + "0x1900c15600617a05b01d17805901221600517416204015000c14e006019", + "0x500601200617f00542c05d00521600c17a00507000601d00521600501d", + "0x542d06100521600c18100512f00618100521600505d005196006006216", + "0x21600503f005152006006216005061005051006006216005006012006185", + "0x21600500642e0061860052160050062080060062160050120051ab006006", + "0x606700521600506518600c02f00606500521600506500502d006065005", + "0x506b0052cc00606b00521600506706900c13d00606900521600500613b", + "0x617800521600517800514600605900521600505900501a00618a005216", + "0x518a0052cd00605b00521600505b00514800601d00521600501d005031", + "0x18500505100600621600500601200618a05b01d17805901200518a005216", + "0x42f00606d01200c2160050120053300060062160050060b4006006216005", + "0x62160050060120060721960701254300ba18d00c21600c06d05b178125", + "0x518d00514600619d00521600519a00539e00619a0052160050060bd006", + "0x61a100521600519d00539f0061a00052160050ba005148006076005216", + "0x61a20052160050720053a10060062160050060120060064310050061b0", + "0x51a200539f0061a0005216005196005148006076005216005070005146", + "0x4331a400521600c07b0050b000607b0052160051a10054320061a1005216", + "0x2160051a40050a90060062160050060c40060062160050060120061a8005", + "0x514600605900521600505900501a00607e005216005012005434006006", + "0x521600507e0054350061a00052160051a0005148006076005216005076", + "0x8e00518600608e08d08c1ab01021600507e03f1a007605901243600607e", + "0xc21600508f0052da00600621600500601200609000543708f00521600c", + "0x9100c2df0060930052160050060bd006006216005092005051006092091", + "0x52160051ab00501a00609500521600509400521b006094005216005093", + "0x514800601d00521600501d00503100608c00521600508c0051460061ab", + "0x9508d01d08c1ab0120050950052160050950052cd00608d00521600508d", + "0x2160051ab00501a0060960052160050900052cc006006216005006012006", + "0x14800601d00521600501d00503100608c00521600508c0051460061ab005", + "0x8d01d08c1ab0120050960052160050960052cd00608d00521600508d005", + "0x621600503f0051520060062160050060c4006006216005006012006096", + "0x505900501a0061b50052160051a80052cc0060062160050120051ab006", + "0x601d00521600501d005031006076005216005076005146006059005216", + "0x1d0760590120051b50052160051b50052cd0061a00052160051a0005148", + "0x50120051ab00600621600503f0051520060062160050060120061b51a0", + "0x14600605900521600505900501a00609b00521600517f0052cc006006216", + "0x21600505b00514800601d00521600501d005031006178005216005178005", + "0x601200609b05b01d17805901200509b00521600509b0052cd00605b005", + "0x50280060062160050120051ab00600621600503f005152006006216005", + "0x609c0052160050470052cc006006216005040005152006006216005019", + "0x500c00503100614e00521600514e00514600600600521600500600501a", + "0x509c00521600509c0052cd00615000521600515000514800600c005216", + "0x600621600500600c00601a00521600500600600609c15000c14e006012", + "0x52160051250051480060050052160050050051460060062160050060c4", + "0x2100521600c02000521d0060201e901e12521600512500500c425006125", + "0x542800620d005216005021005427006006216005006012006023005438", + "0x620720820a02a02820c0260192160050100050fc00602500521600520d", + "0x51e900514800601e00521600501e00514600602d00521600501200540e", + "0x21600502d0261e901e01021e00602d00521600502d00540f0061e9005216", + "0x14100521600c13d00541000602500521600502500543900613d13b02f125", + "0x514800602f00521600502f00514600600621600500601200603100543a", + "0x1d20c13b02f01043b00601d00521600501d00508c00613b00521600513b", + "0x601200603900543d03500521600c14a00543c00614a148146125216005", + "0x4415014e04003f03d14b03c03a017023216005025005429006006216005", + "0x516800600621600503c00542a00600621600501700520a006156047152", + "0x20a00600621600503f00520a00600621600503d00520a00600621600514b", + "0x600621600515000542a00600621600514e00542b006006216005040005", + "0x6216005047005023006006216005152005023006006216005044005168", + "0x21600503a0052f300615e0052160050062ef006006216005156005168006", + "0x604c0052160050060bd00616200521600504a15e00c2e600604a03a00c", + "0x514600514600600600521600500600501a00616800521600504c0052f9", + "0x614800521600514800514800600c00521600500c005031006146005216", + "0x1460060192fb00616800521600516800519d0061620052160051620052e7", + "0x21600501901a00c15600617005001916d04e01221600516816220814800c", + "0x600621600500601200605200543e05100521600c1700052fc006019005", + "0x5016d00c43f00605000521600505000514800616d00521600516d005146", + "0x601200605900544017400521600c0570050f5006057055172125216005", + "0x600621600505b00505100605b17800c216005141005414006006216005", + "0x50510052fe00600621600505d00505100605d17a00c216005035005441", + "0x606100521600517400516100600621600518100505100618117f00c216", + "0x21600520717f20a02a02817a17801915000618500521600503a06100c442", + "0x14800617200521600517200514600604e00521600504e00501a006186005", + "0x5517204e012444006185005216005185005443006055005216005055005", + "0x6d00544518a00521600c06b00518600606b069067065010216005185186", + "0x50ba0050510060ba18d00c21600518a0052da006006216005006012006", + "0x21b00619600521600507018d00c2df0060700052160050060bd006006216", + "0x21600506700514600606500521600506500501a006072005216005196005", + "0x2cd006069005216005069005148006019005216005019005031006067005", + "0x6006216005006012006072069019067065012005072005216005072005", + "0x506700514600606500521600506500501a00619a00521600506d0052cc", + "0x6069005216005069005148006019005216005019005031006067005216", + "0x621600500601200619a06901906706501200519a00521600519a0052cd", + "0x216005141005447006006216005207005153006006216005035005446006", + "0x502800515800600621600502a0051f200600621600520a005101006006", + "0x590052cc00600621600503a00506d006006216005051005448006006216", + "0x17200521600517200514600604e00521600504e00501a00619d005216005", + "0x19d0052cd006055005216005055005148006019005216005019005031006", + "0x544600600621600500601200619d05501917204e01200519d005216005", + "0x44700600621600520700515300600621600503a00506d006006216005035", + "0x600621600502a0051f200600621600520a005101006006216005141005", + "0x21600504e00501a0060760052160050520052cc006006216005028005158", + "0x14800601900521600501900503100616d00521600516d00514600604e005", + "0x5001916d04e0120050760052160050760052cd006050005216005050005", + "0x216005025005449006006216005028005158006006216005006012006076", + "0x520700515300600621600502a0051f200600621600520a005101006006", + "0x20800510300600621600501a005028006006216005141005447006006216", + "0x600600521600500600501a0061a00052160050390052cc006006216005", + "0x514800514800600c00521600500c005031006146005216005146005146", + "0x120061a014800c1460060120051a00052160051a00052cd006148005216", + "0x101006006216005025005449006006216005028005158006006216005006", + "0x600621600520700515300600621600502a0051f200600621600520a005", + "0x621600501d0051ab00600621600520800510300600621600501a005028", + "0x500600501a0061a10052160050310052cc00600621600520c005155006", + "0x600c00521600500c00503100602f00521600502f005146006006005216", + "0xc02f0060120051a10052160051a10052cd00613b00521600513b005148", + "0x501000515200600621600501200506d0060062160050060120061a113b", + "0x230052cc00600621600501a00502800600621600501d0051ab006006216", + "0x1e00521600501e00514600600600521600500600501a0061a2005216005", + "0x1a20052cd0061e90052160051e900514800600c00521600500c005031006", + "0x600600521600500600501a0061a21e900c01e0060120051a2005216005", + "0xc00601044a00601200521600501200502d00600c00521600500c005031", + "0x500620d00601e00521600501a00544b00601a01901d125216005012010", + "0x21600c01e1e912500501044c0061e90052160051e90050260061e9005216", + "0x502300544e00600621600500601200602602520d12544d023021020125", + "0x602a00521600502100514800602800521600502000514600620c005216", + "0x60062160050060120060064500050061b000620a00521600520c00544f", + "0x502500514800602800521600520d005146006208005216005026005451", + "0x620700521600520a00545200620a00521600520800544f00602a005216", + "0x2d00514f00600621600500601200602f00545302d00521600c207005107", + "0x14100521600513d00545500613d00521600513b00545400613b005216005", + "0x1900503100602800521600502800514600601d00521600501d00501a006", + "0x14100521600514100545600602a00521600502a005148006019005216005", + "0x521600502f00545700600621600500601200614102a01902801d012005", + "0x503100602800521600502800514600601d00521600501d00501a006031", + "0x521600503100545600602a00521600502a005148006019005216005019", + "0x52160050060350060062160050060c400603102a01902801d012005031", + "0x1e901e00c21600c01a00500612501700601a00521600501a00503900601a", + "0x602301000c21600501000510500600621600500601200602102000c458", + "0x502d00602500521600520d02300c33e00620d01200c216005012005105", + "0x621600c02500533f00601e00521600501e00501a006025005216005025", + "0x1000520a006006216005019005152006006216005006012006026005459", + "0x2800521600520c01201d12545a00620c0052160050060bd006006216005", + "0x1e900514600601e00521600501e00501a00602a00521600502800545b006", + "0x12500521600512500514800600c00521600500c0050310061e9005216005", + "0x21600500601200602a12500c1e901e01200502a00521600502a00545c006", + "0x50fc00620a01900c216005019005157006006216005026005343006006", + "0x1550060062160052080050fe00614113d13b02f02d20720801921600520a", + "0x600621600513b00510100600621600502d005158006006216005207005", + "0x521600501e00501a00600621600514100515300600621600513d005103", + "0x514800600c00521600500c0050310061e90052160051e900514600601e", + "0x21600503100502d00603101200c216005012005105006125005216005125", + "0x603903514a14814601221600503102f12500c1e901e01d151006031005", + "0x1700514f00600621600500601200603a00545d01700521600c039005107", + "0x3d00521600500610900614b00521600503c01d00c02f00603c005216005", + "0x514600614600521600514600501a00603f00521600503d01200c14d006", + "0x521600503500514800614a00521600514a005031006148005216005148", + "0x504e00603f00521600503f00502d00601000521600501000502d006035", + "0x4001221600501914b03f01003514a14814601a14c00614b00521600514b", + "0x21600500601200615600545e04700521600c15200510c00615204415014e", + "0x521600516204a15e12545a00616204a15e125216005047005149006006", + "0x514600604000521600504000501a00616800521600504c00545b00604c", + "0x521600504400514800615000521600515000503100614e00521600514e", + "0x500601200616804415014e04001200516800521600516800545c006044", + "0x14600604000521600504000501a00604e00521600515600545f006006216", + "0x21600504400514800615000521600515000503100614e00521600514e005", + "0x601200604e04415014e04001200504e00521600504e00545c006044005", + "0x520a00600621600501200520a006006216005019005152006006216005", + "0x616d00521600503a00545f00600621600501d005172006006216005010", + "0x514a00503100614800521600514800514600614600521600514600501a", + "0x516d00521600516d00545c00603500521600503500514800614a005216", + "0x600621600501000520a00600621600500601200616d03514a148146012", + "0x621600501200520a00600621600501d005172006006216005019005152", + "0x21600517000502d006170005216005006059006050005216005006208006", + "0x13d00605200521600500613b00605100521600517005000c02f006170005", + "0x502000501a00605500521600517200545f00617200521600505105200c", + "0x600c00521600500c005031006021005216005021005146006020005216", + "0xc02102001200505500521600505500545c006125005216005125005148", + "0x50100050390060100052160050060350060062160050060c4006055125", + "0x1200601a01900c46001d01200c21600c010005006125017006010005216", + "0x1a0060062160050060b400601e00521600500c0051e9006006216005006", + "0x120060210054610201e900c21600c01e0051b6006012005216005012005", + "0x20d0052160051e90051b40060230052160050200050b8006006216005006", + "0x62160050060120060064620050061b00060250052160050230051b2006", + "0x50210051b400620c0052160050260051ac0060260052160050060bd006", + "0x46302800521600c0250051ae00602500521600520c0051b200620d005216", + "0x2160050280050bf0060062160050060c400600621600500601200602a005", + "0x21a00612500521600512500504e00620a00521600520a00502d00620a005", + "0x520d00505500600621600520700505100620720800c21600512520a00c", + "0x601d00521600501d00514600601200521600501200501a00602d005216", + "0x1d01201014300620800521600520800504e00602d00521600502d00501d", + "0x603100546414100521600c13d00505000613d13b02f12521600520802d", + "0x21600514800505100614814600c216005141005170006006216005006012", + "0x504e00603500521600513b00514600614a00521600502f00501a006006", + "0x51450060062160050060120060064650050061b0006039005216005146", + "0x521600513b00514600602f00521600502f00501a006017005216005031", + "0x621600500601200601713b02f12500501700521600501700514200613b", + "0x621600520d0050d400600621600502a0050510060062160050060c4006", + "0x12500504e00603500521600501d00514600614a00521600501200501a006", + "0x3c00521600503a03900c11100603a0052160050060bd006039005216005", + "0x3500514600614a00521600514a00501a00614b00521600503c005113006", + "0x601200614b03514a12500514b00521600514b005142006035005216005", + "0x620800600621600500c005168006006216005125005172006006216005", + "0x603f00521600503f00502d00603f00521600500605900603d005216005", + "0x4014e00c13d00614e00521600500613b00604000521600503f03d00c02f", + "0x1900521600501900501a006044005216005150005145006150005216005", + "0x1a01912500504400521600504400514200601a00521600501a005146006", + "0x2160050120050390060120052160050060350060062160050060c4006044", + "0x601200601e01a00c46601901d00c21600c012005006125017006012005", + "0x1d00521600501d00501a0061e901000c216005010005105006006216005", + "0x1000520a00600621600500601200602000546700621600c1e900533f006", + "0x2300521600502100c00c396006021005216005125005468006006216005", + "0x1900514600601d00521600501d00501a00620d005216005023005397006", + "0x601200620d01901d12500520d00521600520d005398006019005216005", + "0x1900600c00521600500c00501d006006216005020005343006006216005", + "0x1200602800546920c00521600c02600501e00602602500c21600500c005", + "0x20a00521600500610900602a00521600520c12500c02f006006216005006", + "0x514600601d00521600501d00501a00620800521600520a01000c33e006", + "0x521600502a00504e00602500521600502500501d006019005216005019", + "0x12521600520802a02501901d01211500620800521600520800502d00602a", + "0x621600500601200613d00546a13b00521600c02f0050a600602f02d207", + "0x39700614600521600503114100c39600603114100c21600513b0050a8006", + "0x21600502d00514600620700521600520700501a006148005216005146005", + "0x21600500601200614802d20712500514800521600514800539800602d005", + "0x514600620700521600520700501a00614a00521600513d005399006006", + "0x1200614a02d20712500514a00521600514a00539800602d00521600502d", + "0x39a00600621600512500517200600621600501000520a006006216005006", + "0x503900539700603900521600503502500c396006035005216005028005", + "0x601900521600501900514600601d00521600501d00501a006017005216", + "0x20a00600621600500601200601701901d125005017005216005017005398", + "0x600621600500c005168006006216005125005172006006216005010005", + "0x521600503c00502d00603c00521600500605900603a005216005006208", + "0xc13d00603d00521600500613b00614b00521600503c03a00c02f00603c", + "0x21600501a00501a00604000521600503f00539900603f00521600514b03d", + "0x12500504000521600504000539800601e00521600501e00514600601a005", + "0x600500521600500500514800600600521600500600514600604001e01a", + "0x546d01200521600c01000546c00601012500c12521600500500600c46b", + "0x501900546f00601900521600501200546e00600621600500601200601d", + "0x501e0054710060230210201e901e01221600501a00547000601a005216", + "0x2300520a00600621600502100506d0060062160051e9005472006006216", + "0x602500521600520d00541c00620d00521600502000541b006006216005", + "0x502500541d00612500521600512500514800600c00521600500c005146", + "0x21600501d00541e00600621600500601200602512500c125005025005216", + "0x41d00612500521600512500514800600c00521600500c005146006026005", + "0x1a01900c21600501000547300602612500c125005026005216005026005", + "0x1200502d00600c00521600500c00503100600600521600500600501a006", + "0x544b0060201e901e12521600501201a00c00601044a006012005216005", + "0x2300521600502300502600602300521600500620d006021005216005020", + "0x1200602820c02612547502520d00c21600c01d021023125005012474006", + "0x620a00521600502a00539e00602a0052160050060bd006006216005006", + "0x520a00539f00620700521600502500514800620800521600520d005146", + "0x50280053a10060062160050060120060064760050061b000602d005216", + "0x620700521600520c00514800620800521600502600514600602f005216", + "0xc13b0050b000613b00521600502d0053a200602d00521600502f00539f", + "0x3100521600513d00547800600621600500601200614100547713d005216", + "0x501a00614800521600514600547a00614600521600503101900c479006", + "0x52160051e900503100620800521600520800514600601e00521600501e", + "0x1e01200514800521600514800547b0062070052160052070051480061e9", + "0x547c0060062160050190051f20060062160050060120061482071e9208", + "0x521600520800514600601e00521600501e00501a00614a005216005141", + "0x547b0062070052160052070051480061e90052160051e9005031006208", + "0x2d70060062160050060c400614a2071e920801e01200514a00521600514a", + "0x5216005006208006012005216005010005226006010005216005010005", + "0x547e00601e01a00c21600501200547d00601900521600500620800601d", + "0x500521600500500514600600600521600500600501a00600621600501a", + "0x1900504e00601d00521600501d00504e00601e00521600501e00547f006", + "0x4810060210201e912521600501901d01e005006012480006019005216005", + "0x502300548300600621600500601200620d00548202300521600c021005", + "0x2800c21600502500505200600621600520c00505100620c026025125216", + "0x2600505200620a00521600502a00505500600621600502800517200602a", + "0x2d00521600520700505500600621600520800517200620720800c216005", + "0x21600502d00501d00620a00521600520a00501d0060062160050060b4006", + "0x603114113d12548413b02f00c21600c02d20a00c02001039c00602d005", + "0x14800521600514600539e0061460052160050060bd006006216005006012", + "0x14800539f00603500521600513b00514800614a00521600502f005146006", + "0x310053a10060062160050060120060064850050061b0006039005216005", + "0x3500521600514100514800614a00521600513d005146006017005216005", + "0x3a0050b000603a0052160050390053a200603900521600501700539f006", + "0x60062160050060c400600621600500601200614b00548603c00521600c", + "0x3f00521b00603f00521600503d12500c2df00603d00521600503c005478", + "0x14a00521600514a0051460061e90052160051e900501a006040005216005", + "0x14a1e90100050400052160050400052cd006035005216005035005148006", + "0x2160051250051520060062160050060c4006006216005006012006040035", + "0x51460061e90052160051e900501a00614e00521600514b0052cc006006", + "0x521600514e0052cd00603500521600503500514800614a00521600514a", + "0x621600512500515200600621600500601200614e03514a1e901000514e", + "0x200051460061e90052160051e900501a00615000521600520d0052cc006", + "0x1500052160051500052cd00600c00521600500c005148006020005216005", + "0x60190052160050060350060062160050060c400615000c0201e9010005", + "0xc48701e01a00c21600c019005006125017006019005216005019005039", + "0x50060b40060210052160050100051e90060062160050060120060201e9", + "0x48820d02300c21600c0210051b600601a00521600501a00501a006006216", + "0x230051b400602600521600520d0050b8006006216005006012006025005", + "0x120060064890050061b00060280052160050260051b200620c005216005", + "0x620a00521600502a0051ac00602a0052160050060bd006006216005006", + "0x520c00505500602800521600520a0051b200620c0052160050250051b4", + "0x48a20700521600c0280051ae00620800521600520800501d006208005216", + "0x2160052070050bf0060062160050060c400600621600500601200602d005", + "0x14600601a00521600501a00501a00613b00521600502f0050c100602f005", + "0x21600512500514800600c00521600500c00503100601e00521600501e005", + "0x613d00521600513d00502d00613d01d00c21600501d005105006125005", + "0x1221600513b13d01212500c01e01a0192d300613b00521600513b00502d", + "0x500601200603900548b03500521600c14a0052d400614a148146031141", + "0x2d600603a00521600501701d00c14d006017005216005006109006006216", + "0x21600514100501a00600621600514b00505100614b03c00c216005035005", + "0x148006146005216005146005031006031005216005031005146006141005", + "0x21600503a00502d00620800521600520800501d006148005216005148005", + "0x15014e04003f03d01221600503a03c2081481460311410192db00603a005", + "0x52de00600621600500601200615200548c04400521600c1500052dc006", + "0x616200521600504a15e15604701048d00604a15e156047010216005044", + "0x503f00514600603d00521600503d00501a00604c00521600516200548e", + "0x614e00521600514e00514800604000521600504000503100603f005216", + "0x621600500601200604c14e04003f03d01200504c00521600504c00548f", + "0x3f00514600603d00521600503d00501a006168005216005152005490006", + "0x14e00521600514e00514800604000521600504000503100603f005216005", + "0x21600500601200616814e04003f03d01200516800521600516800548f006", + "0x503900549000600621600520800516800600621600501d00520a006006", + "0x603100521600503100514600614100521600514100501a00604e005216", + "0x504e00548f006148005216005148005148006146005216005146005031", + "0x50060c400600621600500601200604e14814603114101200504e005216", + "0x20801048d00616d0052160050060bd00600621600502d005051006006216", + "0x501a00501a00617000521600505000548e00605000521600516d01d012", + "0x600c00521600500c00503100601e00521600501e00514600601a005216", + "0xc01e01a01200517000521600517000548f006125005216005125005148", + "0x501000516800600621600501d00520a006006216005006012006170125", + "0x50060590060510052160050062080060062160050120051f2006006216", + "0x17200521600505205100c02f00605200521600505200502d006052005216", + "0x5700549000605700521600517205500c13d00605500521600500613b006", + "0x200052160050200051460061e90052160051e900501a006174005216005", + "0x17400548f00612500521600512500514800600c00521600500c005031006", + "0x600600521600500600501a00617412500c0201e9012005174005216005", + "0xc0060104910060120052160050120052e700600c00521600500c005031", + "0x500620d00601e00521600501a00544b00601a01901d125216005012010", + "0x21600c01e1e912500501044c0061e90052160051e90050260061e9005216", + "0x50230052f100600621600500601200602602520d125492023021020125", + "0x2f100602a0052160050062ef00600621600520c00520a00602820c00c216", + "0x2160050280050c100600621600520a00520a00620820a00c21600502a005", + "0xc100600621600502d00520a00602f02d00c2160052070052f1006207005", + "0x513d00520a00614113d00c21600513b0052f100613b005216005208005", + "0x2d0061460052160051410050c100603100521600502f0050c1006006216", + "0x514800502d00614800521600514603100c33e006031005216005031005", + "0x6021005216005021005148006020005216005020005146006148005216", + "0x2160050060bd00600621600500601200614a00549300621600c14800533f", + "0x1b000601700521600503900519d0060390052160050350052f9006035005", + "0x60bd00600621600514a005343006006216005006012006006494005006", + "0x1700521600503c00519d00603c00521600503a00530900603a005216005", + "0x2000514600603d00521600514b00549500614b005216005017005422006", + "0x14e00521600503d00549600604000521600502100514800603f005216005", + "0x1500052160050260054980060062160050060120060064970050061b0006", + "0x15000549600604000521600502500514800603f00521600520d005146006", + "0x15200521600c04400507000604400521600514e00549900614e005216005", + "0x517c00615600521600515200519600600621600500601200604700549a", + "0x521600501d00501a00604a00521600515e0052ea00615e005216005156", + "0x514800601900521600501900503100603f00521600503f00514600601d", + "0x4a04001903f01d01200504a00521600504a0052eb006040005216005040", + "0x21600501d00501a0061620052160050470052ec006006216005006012006", + "0x14800601900521600501900503100603f00521600503f00514600601d005", + "0x4001903f01d0120051620052160051620052eb006040005216005040005", + "0xbd00612500521600500c00500c02f00600c0052160050060050c1006162", + "0x549b00601012500c00512500521600512500504e006010005216005006", + "0x21600500c00503100600600521600500600501a00601a01900c216005010", + "0x12521600501201a00c0060104910060120052160050120052e700600c005", + "0x602300521600502000544b00602100521600501d00549c0060201e901e", + "0x20d12500501247400620d00521600520d00502600620d00521600500620d", + "0xbd00600621600500601200602a02820c12549d02602500c21600c021023", + "0x521600502500514600620800521600520a00539e00620a005216005006", + "0x61b000602f00521600520800539f00602d005216005026005148006207", + "0x514600613b00521600502a0053a100600621600500601200600649e005", + "0x521600513b00539f00602d00521600502800514800620700521600520c", + "0x3100549f14100521600c13d0050b000613d00521600502f0053a200602f", + "0x514601900c4a0006146005216005141005478006006216005006012006", + "0x601e00521600501e00501a00614a0052160051480054a1006148005216", + "0x502d0051480061e90052160051e9005031006207005216005207005146", + "0x1200614a02d1e920701e01200514a00521600514a0054a200602d005216", + "0x60350052160050310054a3006006216005019005103006006216005006", + "0x51e900503100620700521600520700514600601e00521600501e00501a", + "0x50350052160050350054a200602d00521600502d0051480061e9005216", + "0x100052160050100053000060062160050060c400603502d1e920701e012", + "0x21600500620800601d0052160050062080060120052160050100054a4006", + "0x1a00600621600501a00547e00601e01a00c21600501200547d006019005", + "0x21600501e00547f006005005216005005005146006006005216005006005", + "0x48000601900521600501900504e00601d00521600501d00504e00601e005", + "0x2300521600c0210054810060210201e912521600501901d01e005006012", + "0x620c02602512521600502300548300600621600500601200620d0054a5", + "0x502800517200602a02800c21600502500505200600621600520c005051", + "0x620720800c21600502600505200620a00521600502a005055006006216", + "0x62160050060b400602d005216005207005055006006216005208005172", + "0x2001039c00602d00521600502d00501d00620a00521600520a00501d006", + "0x600621600500601200603114113d1254a613b02f00c21600c02d20a00c", + "0x21600502f00514600614800521600514600539e0061460052160050060bd", + "0x1b000603900521600514800539f00603500521600513b00514800614a005", + "0x1460060170052160050310053a10060062160050060120060064a7005006", + "0x21600501700539f00603500521600514100514800614a00521600513d005", + "0x54a803c00521600c03a0050b000603a0052160050390053a2006039005", + "0x521600503c0054780060062160050060c400600621600500601200614b", + "0x1a00604000521600503f00521b00603f00521600503d12500c2df00603d", + "0x21600503500514800614a00521600514a0051460061e90052160051e9005", + "0x500601200604003514a1e90100050400052160050400052cd006035005", + "0x514b0052cc0060062160051250051520060062160050060c4006006216", + "0x614a00521600514a0051460061e90052160051e900501a00614e005216", + "0x3514a1e901000514e00521600514e0052cd006035005216005035005148", + "0x21600520d0052cc00600621600512500515200600621600500601200614e", + "0x1480060200052160050200051460061e90052160051e900501a006150005", + "0x15000c0201e90100051500052160051500052cd00600c00521600500c005", + "0x120052e700600c00521600500c00503100600600521600500600501a006", + "0x544b00601a01901d12521600501201000c0060104a9006012005216005", + "0x1e90052160051e90050260061e900521600500620d00601e00521600501a", + "0x1200602602520d1254aa02302102012521600c01e1e912500501044c006", + "0x621600520c00520a00602820c00c2160050230052f1006006216005006", + "0x20a00520a00620820a00c21600502a0052f100602a0052160050062ef006", + "0x2f02d00c2160052070052f10062070052160050280050c1006006216005", + "0x513b0052f100613b0052160052080050c100600621600502d00520a006", + "0x603100521600502f0050c100600621600513d00520a00614113d00c216", + "0x14603100c33e00603100521600503100502d0061460052160051410050c1", + "0x2000521600502000514600614800521600514800502d006148005216005", + "0x1200614a0054ab00621600c14800533f006021005216005021005148006", + "0x60390052160050350052f90060350052160050060bd006006216005006", + "0x60062160050060120060064ac0050061b000601700521600503900519d", + "0x521600503a00530900603a0052160050060bd00600621600514a005343", + "0x549500614b00521600501700542200601700521600503c00519d00603c", + "0x521600502100514800603f00521600502000514600603d00521600514b", + "0x2160050060120060064ad0050061b000614e00521600503d005496006040", + "0x514800603f00521600520d005146006150005216005026005498006006", + "0x521600514e00549900614e005216005150005496006040005216005025", + "0x1960060062160050060120060470054ae15200521600c044005070006044", + "0x21600515e0052ea00615e00521600515600517c006156005216005152005", + "0x3100603f00521600503f00514600601d00521600501d00501a00604a005", + "0x21600504a0052eb006040005216005040005148006019005216005019005", + "0x50470052ec00600621600500601200604a04001903f01d01200504a005", + "0x603f00521600503f00514600601d00521600501d00501a006162005216", + "0x51620052eb006040005216005040005148006019005216005019005031", + "0x601a01900c2160050100054af00616204001903f01d012005162005216", + "0x50120052e700600c00521600500c00503100600600521600500600501a", + "0x1d00549c0060201e901e12521600501201a00c0060104a9006012005216", + "0x620d00521600500620d00602300521600502000544b006021005216005", + "0x2602500c21600c02102320d12500501247400620d00521600520d005026", + "0x39e00620a0052160050060bd00600621600500601200602a02820c1254b0", + "0x21600502600514800620700521600502500514600620800521600520a005", + "0x50060120060064b10050061b000602f00521600520800539f00602d005", + "0x14800620700521600520c00514600613b00521600502a0053a1006006216", + "0x21600502f0053a200602f00521600513b00539f00602d005216005028005", + "0x60062160050060120060310054b214100521600c13d0050b000613d005", + "0x1480054b400614800521600514601900c4b3006146005216005141005478", + "0x20700521600520700514600601e00521600501e00501a00614a005216005", + "0x14a0054b500602d00521600502d0051480061e90052160051e9005031006", + "0x515300600621600500601200614a02d1e920701e01200514a005216005", + "0x1e00521600501e00501a0060350052160050310054b6006006216005019", + "0x2d0051480061e90052160051e9005031006207005216005207005146006", + "0x603502d1e920701e0120050350052160050350054b500602d005216005", + "0x52160050100054b70060100052160050100052190060062160050060c4", + "0x501200547d00601900521600500620800601d005216005006208006012", + "0x600600521600500600501a00600621600501a00547e00601e01a00c216", + "0x501d00504e00601e00521600501e00547f006005005216005005005146", + "0x501901d01e00500601248000601900521600501900504e00601d005216", + "0x500601200620d0054b802300521600c0210054810060210201e9125216", + "0x600621600520c00505100620c026025125216005023005483006006216", + "0x502a00505500600621600502800517200602a02800c216005025005052", + "0x600621600520800517200620720800c21600502600505200620a005216", + "0x521600520a00501d0060062160050060b400602d005216005207005055", + "0x2f00c21600c02d20a00c02001039c00602d00521600502d00501d00620a", + "0x61460052160050060bd00600621600500601200603114113d1254b913b", + "0x513b00514800614a00521600502f00514600614800521600514600539e", + "0x60120060064ba0050061b000603900521600514800539f006035005216", + "0x614a00521600513d0051460060170052160050310053a1006006216005", + "0x50390053a200603900521600501700539f006035005216005141005148", + "0x621600500601200614b0054bb03c00521600c03a0050b000603a005216", + "0x503d12500c2df00603d00521600503c0054780060062160050060c4006", + "0x61e90052160051e900501a00604000521600503f00521b00603f005216", + "0x50400052cd00603500521600503500514800614a00521600514a005146", + "0x2160050060c400600621600500601200604003514a1e9010005040005216", + "0x1e900501a00614e00521600514b0052cc006006216005125005152006006", + "0x3500521600503500514800614a00521600514a0051460061e9005216005", + "0x621600500601200614e03514a1e901000514e00521600514e0052cd006", + "0x51e900501a00615000521600520d0052cc006006216005125005152006", + "0x600c00521600500c0051480060200052160050200051460061e9005216", + "0x60062160050060c400615000c0201e90100051500052160051500052cd", + "0x621600501a0051550060230210201e901e01a0190192160051250050fc", + "0x2160050200051010060062160051e90051f200600621600501e005158006", + "0x500600501a006006216005023005153006006216005021005103006006", + "0x600c00521600500c005148006005005216005005005146006006005216", + "0x521600c20c00540c00620c02602520d01021600501900c00500601040b", + "0x1a00620a00521600502800541200600621600500601200602a0054bc028", + "0x21600502600514800602500521600502500514600620d00521600520d005", + "0x2d00601000521600501000508c00620a00521600520a00540f006026005", + "0x2602520d0194bd00601d00521600501d00501d006012005216005012005", + "0x4be13b00521600c02f00504a00602f02d20720801021600501d01201020a", + "0x14100505700614100521600513b00516200600621600500601200613d005", + "0x20800521600520800501a006146005216005031005174006031005216005", + "0x14600514a00602d00521600502d005148006207005216005207005146006", + "0x13d00514100600621600500601200614602d207208010005146005216005", + "0x20700521600520700514600620800521600520800501a006148005216005", + "0x20720801000514800521600514800514a00602d00521600502d005148006", + "0x501200520a00600621600501d00516800600621600500601200614802d", + "0x501a00614a00521600502a0051410060062160050100051ab006006216", + "0x521600502600514800602500521600502500514600620d00521600520d", + "0x50061254bf00614a02602520d01000514a00521600514a00514a006026", + "0x50100054c10060062160050060120060120054c001012500c21600c00c", + "0x612500521600512500501a00601900521600501d0054c200601d005216", + "0x620800600621600500601200601912500c0050190052160050190054c3", + "0x601e00521600501e00502d00601e00521600500622800601a005216005", + "0x1e902000c13d00602000521600500613b0061e900521600501e01a00c02f", + "0x1200521600501200501a0060230052160050210054c4006021005216005", + "0x600521600500600501a00602301200c0050230052160050230054c3006", + "0x60104c500601200521600501200502d00600c00521600500c005031006", + "0x620d00601e00521600501a00544b00601a01901d12521600501201000c", + "0xc01e1e912500501044c0061e90052160051e90050260061e9005216005", + "0x1d00501a00600621600500601200602602520d1254c6023021020125216", + "0xc21600502301d00c4c700602300521600502300502d00601d005216005", + "0x7e00602100521600502100514800602000521600502000514600602820c", + "0x502a0054c900600621600500601200620a0054c802a00521600c028005", + "0x602d00521600502000514600620700521600520c00501a006208005216", + "0x4cb0050061b000613b0052160052080054ca00602f005216005021005148", + "0x521600500620800600621600520a005051006006216005006012006006", + "0x13d00c02f00614100521600514100502d0061410052160050064cc00613d", + "0x521600503114600c13d00614600521600500613b006031005216005141", + "0x514600620c00521600520c00501a00614a005216005148005354006148", + "0x5216005021005148006019005216005019005031006020005216005020", + "0x500601200614a02101902020c01200514a00521600514a005353006021", + "0x14600620700521600501d00501a0060350052160050260054cd006006216", + "0x2160050350054ca00602f00521600502500514800602d00521600520d005", + "0x54ce01700521600c03900508f00603900521600513b00522700613b005", + "0x503c00535100603c00521600501700509000600621600500601200603a", + "0x620700521600520700501a00603d00521600514b00535200614b005216", + "0x502f00514800601900521600501900503100602d00521600502d005146", + "0x1200603d02f01902d20701200503d00521600503d00535300602f005216", + "0x20700521600520700501a00603f00521600503a005354006006216005006", + "0x2f00514800601900521600501900503100602d00521600502d005146006", + "0x603f02f01902d20701200503f00521600503f00535300602f005216005", + "0xc00503100600600521600500600501a00601a01900c216005010005339", + "0x501201a00c0060104c500601200521600501200502d00600c005216005", + "0x521600502000544b00602100521600501d00533d0060201e901e125216", + "0x501247400620d00521600520d00502600620d00521600500620d006023", + "0x621600500601200602a02820c1254cf02602500c21600c02102320d125", + "0x502500514600620800521600520a00539e00620a0052160050060bd006", + "0x602f00521600520800539f00602d005216005026005148006207005216", + "0x613b00521600502a0053a10060062160050060120060064d00050061b0", + "0x513b00539f00602d00521600502800514800620700521600520c005146", + "0x4d114100521600c13d0050b000613d00521600502f0053a200602f005216", + "0x1900c4d2006146005216005141005478006006216005006012006031005", + "0x521600501e00501a00614a0052160051480054d3006148005216005146", + "0x51480061e90052160051e900503100620700521600520700514600601e", + "0x14a02d1e920701e01200514a00521600514a0054d400602d00521600502d", + "0x52160050310054d5006006216005019005101006006216005006012006", + "0x503100620700521600520700514600601e00521600501e00501a006035", + "0x52160050350054d400602d00521600502d0051480061e90052160051e9", + "0x21600501000534b0060062160050060c400603502d1e920701e012005035", + "0x620800601d0052160050062080060120052160050100054d6006010005", + "0x621600501a00547e00601e01a00c21600501200547d006019005216005", + "0x1e00547f00600500521600500500514600600600521600500600501a006", + "0x1900521600501900504e00601d00521600501d00504e00601e005216005", + "0x21600c0210054810060210201e912521600501901d01e005006012480006", + "0x2602512521600502300548300600621600500601200620d0054d7023005", + "0x517200602a02800c21600502500505200600621600520c00505100620c", + "0x20800c21600502600505200620a00521600502a005055006006216005028", + "0x50060b400602d005216005207005055006006216005208005172006207", + "0x39c00602d00521600502d00501d00620a00521600520a00501d006006216", + "0x21600500601200603114113d1254d813b02f00c21600c02d20a00c020010", + "0x2f00514600614800521600514600539e0061460052160050060bd006006", + "0x3900521600514800539f00603500521600513b00514800614a005216005", + "0x170052160050310053a10060062160050060120060064d90050061b0006", + "0x1700539f00603500521600514100514800614a00521600513d005146006", + "0x3c00521600c03a0050b000603a0052160050390053a2006039005216005", + "0x503c0054780060062160050060c400600621600500601200614b0054da", + "0x4000521600503f00521b00603f00521600503d12500c2df00603d005216", + "0x3500514800614a00521600514a0051460061e90052160051e900501a006", + "0x1200604003514a1e90100050400052160050400052cd006035005216005", + "0x52cc0060062160051250051520060062160050060c4006006216005006", + "0x521600514a0051460061e90052160051e900501a00614e00521600514b", + "0x1e901000514e00521600514e0052cd00603500521600503500514800614a", + "0x20d0052cc00600621600512500515200600621600500601200614e03514a", + "0x200052160050200051460061e90052160051e900501a006150005216005", + "0x201e90100051500052160051500052cd00600c00521600500c005148006", + "0x1000544b0060100052160050064db00600621600512500515500615000c", + "0x601d00521600501d00502600601d00521600500620d006012005216005", + "0x1e01a01912521600c01201d00c00501044c0060120052160050120054dc", + "0x600600521600500600501a0060062160050060120060210201e91254dd", + "0x514600620d02300c21600501e00600c4c700601e00521600501e00502d", + "0x521600c20d00507e00601a00521600501a005148006019005216005019", + "0x1a00620c0052160050250054c90060062160050060120060260054de025", + "0x21600501a00514800602a005216005019005146006028005216005023005", + "0x50060120060064df0050061b000620800521600520c0054ca00620a005", + "0x50064cc006207005216005006208006006216005026005051006006216", + "0x2f00521600502d20700c02f00602d00521600502d00502d00602d005216", + "0x13d00535400613d00521600502f13b00c13d00613b00521600500613b006", + "0x1900521600501900514600602300521600502300501a006141005216005", + "0x1902301000514100521600514100535300601a00521600501a005148006", + "0x600501a0060310052160050210054cd00600621600500601200614101a", + "0x20a00521600502000514800602a0052160051e9005146006028005216005", + "0x14600508f0061460052160052080052270062080052160050310054ca006", + "0x521600514800509000600621600500601200614a0054e014800521600c", + "0x501a006017005216005039005352006039005216005035005351006035", + "0x521600520a00514800602a00521600502a005146006028005216005028", + "0x21600500601200601720a02a02801000501700521600501700535300620a", + "0x514600602800521600502800501a00603a00521600514a005354006006", + "0x521600503a00535300620a00521600520a00514800602a00521600502a", + "0x1200600c0054e200500521600c0060054e100603a20a02a02801000503a", + "0x100052160051250054e40061250052160050050054e3006006216005006", + "0x613b0060062160050060120060100050050100052160050100054e5006", + "0x521600501d0054e600601d00521600500c01200c13d006012005216005", + "0x60100052160050062080060190050050190052160050190054e5006019", + "0x501d00508c0060062160050120051ab00601d01200c216005125005091", + "0x1900c21600501001d00c09200601000521600501000504e00601d005216", + "0x50064e800601e00521600500c0054e700600621600501a00505100601a", + "0x600621600502000517200602102000c2160050190050520061e9005216", + "0x502300501d0061e90052160051e900502d006023005216005021005055", + "0x20c1254ea02602520d12521600c0231e901e0050060124e9006023005216", + "0x20d00514600620a00521600502600522500600621600500601200602a028", + "0x2d00521600520a0054eb006207005216005025005148006208005216005", + "0x2f00521600502a0054ed0060062160050060120060064ec0050061b0006", + "0x2f0054eb00620700521600502800514800620800521600520c005146006", + "0x13d00521600c13b00504a00613b00521600502d0054ee00602d005216005", + "0x50060bd00600621600513d0054f00060062160050060120061410054ef", + "0x61480052160051460053a50061460052160050310053a4006031005216", + "0x51480053a6006207005216005207005148006208005216005208005146", + "0x2160051410053a7006006216005006012006148207208125005148005216", + "0x3a600620700521600520700514800620800521600520800514600614a005", + "0x536e0060062160050060c400614a20720812500514a00521600514a005", + "0x1d0052160050062080060120052160050100054f1006010005216005010", + "0x1a00547e00601e01a00c21600501200547d006019005216005006208006", + "0x600500521600500500514600600600521600500600501a006006216005", + "0x501900504e00601d00521600501d00504e00601e00521600501e00547f", + "0x54810060210201e912521600501901d01e005006012480006019005216", + "0x21600502300548300600621600500601200620d0054f202300521600c021", + "0x2a02800c21600502500505200600621600520c00505100620c026025125", + "0x502600505200620a00521600502a005055006006216005028005172006", + "0x602d00521600520700505500600621600520800517200620720800c216", + "0x521600502d00501d00620a00521600520a00501d0060062160050060b4", + "0x1200603114113d1254f313b02f00c21600c02d20a00c02001039c00602d", + "0x614800521600514600539e0061460052160050060bd006006216005006", + "0x514800539f00603500521600513b00514800614a00521600502f005146", + "0x50310053a10060062160050060120060064f40050061b0006039005216", + "0x603500521600514100514800614a00521600513d005146006017005216", + "0xc03a0050b000603a0052160050390053a200603900521600501700539f", + "0x4780060062160050060c400600621600500601200614b0054f503c005216", + "0x503f00521b00603f00521600503d12500c2df00603d00521600503c005", + "0x614a00521600514a0051460061e90052160051e900501a006040005216", + "0x3514a1e90100050400052160050400052cd006035005216005035005148", + "0x62160051250051520060062160050060c4006006216005006012006040", + "0x14a0051460061e90052160051e900501a00614e00521600514b0052cc006", + "0x14e00521600514e0052cd00603500521600503500514800614a005216005", + "0x600621600512500515200600621600500601200614e03514a1e9010005", + "0x50200051460061e90052160051e900501a00615000521600520d0052cc", + "0x51500052160051500052cd00600c00521600500c005148006020005216", + "0x521600500500514600600600521600500600501a00615000c0201e9010", + "0x515700612500521600512500514800600c00521600500c005031006005", + "0x501a00502d00601a01200c21600501200510500601901000c216005010", + "0x1a01912500c0050060191a200601d00521600501d00518d00601a005216", + "0x250054f620d00521600c0230050700060230210201e901e01221600501d", + "0x21600c02600512f00602600521600520d005196006006216005006012006", + "0x14600600621600520c0050510060062160050060120060280054f720c005", + "0x50211e900c4250060210052160050210051480061e90052160051e9005", + "0x500601200602d0054f820700521600c20800521d00620820a02a125216", + "0x42900613b00521600502f00542800602f005216005207005427006006216", + "0x20a00603d14b03c03a01703903514a14814603114113d02321600513b005", + "0x600621600514600516800600621600503100542a00600621600513d005", + "0x621600503500520a00600621600514a00520a00600621600514800520a", + "0x21600503a00516800600621600501700542a00600621600503900542b006", + "0x503d00516800600621600514b00502300600621600503c005023006006", + "0x3100602a00521600502a00514600601e00521600501e00501a006006216", + "0x21600501000515700620a00521600520a005148006020005216005020005", + "0x601200521600501200502d00614100521600514100518d00603f01000c", + "0x507000615204415014e04001221600501214103f20a02002a01e0190ba", + "0x2160050470051960060062160050060120061560054f904700521600c152", + "0x60062160050060120061620054fa04a00521600c15e00512f00615e005", + "0x21600504400514800614e00521600514e00514600600621600504a005051", + "0x521600c04e00521d00604e16804c12521600504414e00c425006044005", + "0x42800617000521600516d0054270060062160050060120060500054fb16d", + "0x178059174057055172052023216005051005429006051005216005170005", + "0x621600505500542a00600621600505200520a00606118117f05d17a05b", + "0x21600505900520a00600621600517400520a006006216005057005168006", + "0x517a00542a00600621600505b00542b00600621600517800520a006006", + "0x18100502300600621600517f00502300600621600505d005168006006216", + "0x501a0061850052160050062ef006006216005061005168006006216005", + "0x521600515000503100604c00521600504c005146006040005216005040", + "0x502d00617200521600517200518d006168005216005168005148006150", + "0x6518601221600518517201016815004c0400190ba006185005216005185", + "0x621600500601200606d0054fc18a00521600c06b00507000606b069067", + "0x60700054fd0ba00521600c18d00512f00618d00521600518a005196006", + "0x61960052160050062080060062160050ba005051006006216005006012", + "0x507219600c02f00607200521600507200502d0060720052160050064fe", + "0x607600521600519a19d00c13d00619d00521600500613b00619a005216", + "0x506500514600618600521600518600501a0061a00052160050760053a7", + "0x6069005216005069005148006067005216005067005031006065005216", + "0x62160050060120061a00690670651860120051a00052160051a00053a6", + "0x50650051460061a100521600518600501a006006216005070005051006", + "0x61a400521600506900514800607b0052160050670050310061a2005216", + "0x61a800521600506d0053a70060062160050060120060064ff0050061b0", + "0x506700503100606500521600506500514600618600521600518600501a", + "0x51a80052160051a80053a6006069005216005069005148006067005216", + "0x60062160050100051520060062160050060120061a8069067065186012", + "0x504c00514600604000521600504000501a00607e0052160050500053a7", + "0x616800521600516800514800615000521600515000503100604c005216", + "0x621600500601200607e16815004c04001200507e00521600507e0053a6", + "0x21600504000501a006006216005010005152006006216005162005051006", + "0x14800608d00521600515000503100608c00521600514e0051460061ab005", + "0x1520060062160050060120060065000050061b000608e005216005044005", + "0x521600504000501a00608f0052160051560053a7006006216005010005", + "0x514800615000521600515000503100614e00521600514e005146006040", + "0x8f04415014e04001200508f00521600508f0053a6006044005216005044", + "0x621600501200520a006006216005010005152006006216005006012006", + "0x2a00514600601e00521600501e00501a00609000521600502d0053a7006", + "0x20a00521600520a00514800602000521600502000503100602a005216005", + "0x21600500601200609020a02002a01e0120050900052160050900053a6006", + "0x501200520a006006216005010005152006006216005028005051006006", + "0x3100608c0052160051e90051460061ab00521600501e00501a006006216", + "0x2160051ab00550100608e00521600502100514800608d005216005020005", + "0x50400607b00521600508d0055030061a200521600508c0055020061a1005", + "0x52160050910053a40060910052160050060bd0061a400521600508e005", + "0x1a10120050930052160050930053a60060930052160050920053a5006092", + "0x520a0060062160050100051520060062160050060120060931a407b1a2", + "0x1e00521600501e00501a0060940052160050250053a7006006216005012", + "0x210051480060200052160050200050310061e90052160051e9005146006", + "0x60940210201e901e0120050940052160050940053a6006021005216005", + "0x521600501000550500601000521600501000537c0060062160050060c4", + "0x501200547d00601900521600500620800601d005216005006208006012", + "0x600600521600500600501a00600621600501a00547e00601e01a00c216", + "0x501d00504e00601e00521600501e00547f006005005216005005005146", + "0x501901d01e00500601248000601900521600501900504e00601d005216", + "0x500601200620d00550602300521600c0210054810060210201e9125216", + "0x600621600520c00505100620c026025125216005023005483006006216", + "0x502a00505500600621600502800517200602a02800c216005025005052", + "0x600621600520800517200620720800c21600502600505200620a005216", + "0x521600520a00501d0060062160050060b400602d005216005207005055", + "0x2f00c21600c02d20a00c02001039c00602d00521600502d00501d00620a", + "0x61460052160050060bd00600621600500601200603114113d12550713b", + "0x513b00514800614a00521600502f00514600614800521600514600539e", + "0x60120060065080050061b000603900521600514800539f006035005216", + "0x614a00521600513d0051460060170052160050310053a1006006216005", + "0x50390053a200603900521600501700539f006035005216005141005148", + "0x621600500601200614b00550903c00521600c03a0050b000603a005216", + "0x503d12500c2df00603d00521600503c0054780060062160050060c4006", + "0x61e90052160051e900501a00604000521600503f00521b00603f005216", + "0x50400052cd00603500521600503500514800614a00521600514a005146", + "0x2160050060c400600621600500601200604003514a1e9010005040005216", + "0x1e900501a00614e00521600514b0052cc006006216005125005152006006", + "0x3500521600503500514800614a00521600514a0051460061e9005216005", + "0x621600500601200614e03514a1e901000514e00521600514e0052cd006", + "0x51e900501a00615000521600520d0052cc006006216005125005152006", + "0x600c00521600500c0051480060200052160050200051460061e9005216", + "0x621600512500515800615000c0201e90100051500052160051500052cd", + "0x21600500620d00601200521600501000544b00601000521600500650a006", + "0x44c0060120052160050120054dc00601d00521600501d00502600601d005", + "0x50060120060210201e912550b01e01a01912521600c01201d00c005010", + "0xdb00601e00521600501e00502d00600600521600500600501a006006216", + "0x1a00514800601900521600501900514600620d02300c21600501e00600c", + "0x21600500601200602600550c02500521600c20d0050dd00601a005216005", + "0x514600602800521600502300501a00620c00521600502500550d006006", + "0x521600520c00550e00620a00521600501a00514800602a005216005019", + "0x621600502600505100600621600500601200600650f0050061b0006208", + "0x21600502d00502d00602d005216005006510006207005216005006208006", + "0x13d00613b00521600500613b00602f00521600502d20700c02f00602d005", + "0x502300501a00614100521600513d00551100613d00521600502f13b00c", + "0x601a00521600501a005148006019005216005019005146006023005216", + "0x600621600500601200614101a019023010005141005216005141005224", + "0x51e900514600602800521600500600501a006031005216005021005512", + "0x620800521600503100550e00620a00521600502000514800602a005216", + "0x1200614a00551414800521600c146005385006146005216005208005513", + "0x39005216005035005515006035005216005148005387006006216005006", + "0x2a00514600602800521600502800501a006017005216005039005516006", + "0x1700521600501700522400620a00521600520a00514800602a005216005", + "0x3a00521600514a00551100600621600500601200601720a02a028010005", + "0x20a00514800602a00521600502a00514600602800521600502800501a006", + "0x51700603a20a02a02801000503a00521600503a00522400620a005216005", + "0x600621600500601200601d01200c51801012500c21600c00c005006125", + "0x501900551a00601a00521600512500501a006019005216005010005519", + "0x501d00551c00600621600500601200600651b0050061b000601e005216", + "0x601e0052160051e900551a00601a00521600501200501a0061e9005216", + "0x502001e00c51e00602000521600502000502d00602000521600500651d", + "0x621600500601200620d00551f02300521600c021005385006021005216", + "0x26005516006026005216005025005515006025005216005023005387006", + "0x20c00521600520c00522400601a00521600501a00501a00620c005216005", + "0x1a00602800521600520d00551100600621600500601200620c01a00c005", + "0x50a00602801a00c00502800521600502800522400601a00521600501a005", + "0x521600501000544b0060120052160051250051bd006010005216005006", + "0x515800601e01a00c21600500c00538300601900521600500620d00601d", + "0x1d00521600501d0054dc00601900521600501900502600600621600501e", + "0x1200620d0230211255200201e900c21600c01201d019005006012474006", + "0x602600521600502500539e0060250052160050060bd006006216005006", + "0x502600539f00602800521600502000514800620c0052160051e9005146", + "0x520d0053a10060062160050060120060065210050061b000602a005216", + "0x602800521600502300514800620c00521600502100514600620a005216", + "0xc2080050b000620800521600502a0053a200602a00521600520a00539f", + "0x2f00521600520700547800600621600500601200602d005522207005216", + "0x514600613d00521600513b00552400613b00521600502f01a00c523006", + "0x521600513d00552500602800521600502800514800620c00521600520c", + "0x600621600501a00515800600621600500601200613d02820c12500513d", + "0x502800514800620c00521600520c00514600614100521600502d005526", + "0x600552700614102820c125005141005216005141005525006028005216", + "0x52160050050053a400600621600500601200600c00552800500521600c", + "0x100050050100052160050100053a60060100052160051250053a5006125", + "0x21600500c01200c13d00601200521600500613b006006216005006012006", + "0x50050190052160050190053a600601900521600501d0053a700601d005", + "0x2160050120050390060120052160050060350060062160050060c4006019", + "0x601200601e01a00c52901901d00c21600c012005006125017006012005", + "0x1d00521600501d00501a0061e901000c216005010005105006006216005", + "0x1000520a00600621600500601200602000552a00621600c1e900533f006", + "0x2300521600502100c00c52b006021005216005125005223006006216005", + "0x1900514600601d00521600501d00501a00620d00521600502300552c006", + "0x601200620d01901d12500520d00521600520d00552d006019005216005", + "0xb400602500521600500c0051e9006006216005020005343006006216005", + "0x500601200602800552e20c02600c21600c0250051b6006006216005006", + "0x1b200620a0052160050260051b400602a00521600520c0050b8006006216", + "0xbd00600621600500601200600652f0050061b000620800521600502a005", + "0x52160050280051b400602d0052160052070051ac006207005216005006", + "0x501d00602f00521600520a00505500620800521600502d0051b200620a", + "0x500601200613d00553013b00521600c2080051ae00602f00521600502f", + "0x1a0060310052160051410050c100614100521600513b0050bf006006216", + "0x503101d00c1aa00603100521600503100502d00601d00521600501d005", + "0x21600500601200603500553114a00521600c1480051a700614814600c216", + "0x500610900603900521600514a12500c5320060062160050060c4006006", + "0x14600521600514600501a00603a00521600501701000c33e006017005216", + "0x390053b200602f00521600502f00501d006019005216005019005146006", + "0x3a03902f0191460123b300603a00521600503a00502d006039005216005", + "0x601200604000553303f00521600c03d0053b400603d14b03c125216005", + "0x521600515014e00c52b00615014e00c21600503f0053b6006006216005", + "0x514600603c00521600503c00501a00615200521600504400552c006044", + "0x1200615214b03c12500515200521600515200552d00614b00521600514b", + "0x3c00521600503c00501a006047005216005040005534006006216005006", + "0x14b03c12500504700521600504700552d00614b00521600514b005146006", + "0x2160051250053ba00600621600501000520a006006216005006012006047", + "0x61b000615e00521600503500553500615600521600514600501a006006", + "0x1250053ba00600621600513d005051006006216005006012006006536005", + "0x501a00604a0052160050060bd00600621600501000520a006006216005", + "0x60062160050060c400615e00521600504a00553500615600521600501d", + "0x4c00552c00604c00521600516202f00c52b00616200521600515e005537", + "0x16800521600516800552d006019005216005019005146006168005216005", + "0x3ba00600621600501000520a006006216005006012006168019156125005", + "0x604e00521600500620800600621600500c005168006006216005125005", + "0x516d04e00c02f00616d00521600516d00502d00616d005216005006059", + "0x605100521600505017000c13d00617000521600500613b006050005216", + "0x501e00514600601a00521600501a00501a006052005216005051005534", + "0x50060c400605201e01a12500505200521600505200552d00601e005216", + "0x50062ef0060120052160050062ef006010005216005006035006006216", + "0x1a00521600501901d0121255380060190052160050062ef00601d005216", + "0xc00519900600500521600500500514600600600521600500600501a006", + "0x1a00521600501a00553900601000521600501000503900600c005216005", + "0x1021600512501a01000c00500601d53a00612500521600512500501d006", + "0x21600500601200620d00553c02300521600c02100553b0060210201e901e", + "0x545400600621600502500516800602602500c21600502300553d006006", + "0x521600501e00501a00602800521600520c00545500620c005216005026", + "0x54560060200052160050200051990061e90052160051e900514600601e", + "0x54570060062160050060120060280201e901e010005028005216005028", + "0x52160051e900514600601e00521600501e00501a00602a00521600520d", + "0x1e01000502a00521600502a0054560060200052160050200051990061e9", + "0x500653e0061e90052160050062080060062160050060c400602a0201e9", + "0x210052160050201e900c02f00602000521600502000502d006020005216", + "0x20d00620d00521600501d02300c02f00602300521600501202100c02f006", + "0x21600502600517200620c02600c21600520d005052006025005216005006", + "0x514600600600521600500600501a00602800521600520c005055006006", + "0x521600512500519900600c00521600500c00519b006005005216005005", + "0x501d006025005216005025005026006010005216005010005148006125", + "0x521600501a00501d00601900521600501900519f006028005216005028", + "0x1902802501012500c0050061e953f00601e00521600501e0050cf00601a", + "0x54013b00521600c02f0050b000602f02d20720820a02a01d21600501e01a", + "0x2160050060bd00600621600513b0050a900600621600500601200613d005", + "0x1a0061460052160050310053a50060310052160051410053a4006141005", + "0x21600520800519b00620a00521600520a00514600602a00521600502a005", + "0x3a600602d00521600502d005148006207005216005207005199006208005", + "0x621600500601200614602d20720820a02a01d005146005216005146005", + "0x20a00514600602a00521600502a00501a00614800521600513d0053a7006", + "0x20700521600520700519900620800521600520800519b00620a005216005", + "0x20a02a01d0051480052160051480053a600602d00521600502d005148006", + "0x5410060100052160050100053ca0060062160050060c400614802d207208", + "0x1900521600500620800601d005216005006208006012005216005010005", + "0x600501a00600621600501a00547e00601e01a00c21600501200547d006", + "0x1e00521600501e00547f006005005216005005005146006006005216005", + "0x601248000601900521600501900504e00601d00521600501d00504e006", + "0x554202300521600c0210054810060210201e912521600501901d01e005", + "0x505100620c02602512521600502300548300600621600500601200620d", + "0x621600502800517200602a02800c21600502500505200600621600520c", + "0x517200620720800c21600502600505200620a00521600502a005055006", + "0x1d0060062160050060b400602d005216005207005055006006216005208", + "0x20a00c02001039c00602d00521600502d00501d00620a00521600520a005", + "0x60bd00600621600500601200603114113d12554313b02f00c21600c02d", + "0x14a00521600502f00514600614800521600514600539e006146005216005", + "0x50061b000603900521600514800539f00603500521600513b005148006", + "0x13d0051460060170052160050310053a1006006216005006012006006544", + "0x3900521600501700539f00603500521600514100514800614a005216005", + "0x614b00554503c00521600c03a0050b000603a0052160050390053a2006", + "0x603d00521600503c0054780060062160050060c4006006216005006012", + "0x1e900501a00604000521600503f00521b00603f00521600503d12500c2df", + "0x3500521600503500514800614a00521600514a0051460061e9005216005", + "0x621600500601200604003514a1e90100050400052160050400052cd006", + "0x521600514b0052cc0060062160051250051520060062160050060c4006", + "0x514800614a00521600514a0051460061e90052160051e900501a00614e", + "0x614e03514a1e901000514e00521600514e0052cd006035005216005035", + "0x15000521600520d0052cc006006216005125005152006006216005006012", + "0xc0051480060200052160050200051460061e90052160051e900501a006", + "0xc400615000c0201e90100051500052160051500052cd00600c005216005", + "0x6012005216005012005039006012005216005006035006006216005006", + "0x621600500601200601e01a00c54601901d00c21600c012005006125017", + "0x55480060200052160051e90055470061e912500c216005125005222006", + "0x21600502100502100620d02300c21600500c005021006021005216005020", + "0x2500620c00521600520d00502500600621600502500502300602602500c", + "0x21600501d00501a006028005216005028005026006028005216005026005", + "0x2ef00600621600500601200600654900621600c02820c00c20c00601d005", + "0x21600502a01000c02f00602a00521600502a00502d00602a005216005006", + "0x502600601d00521600501d00501a00620800521600500638800620a005", + "0x520802301d125389006208005216005208005026006023005216005023", + "0x2f00521600c02d00538500620a00521600520a00504e00602d20700c216", + "0x501a00613d00521600502f00538700600621600500601200613b00554a", + "0x521600513d005026006019005216005019005146006207005216005207", + "0x123d200620a00521600520a00504e0061250052160051250050cf00613d", + "0x54b14800521600c1460053d300614603114112521600520a12513d019207", + "0x54c0060170390351252160051480053d700600621600500601200614a005", + "0x14100501a00603c00521600503a00554d00603a005216005017039035125", + "0x3c00521600503c00554e006031005216005031005146006141005216005", + "0x614b00521600514a00554f00600621600500601200603c031141125005", + "0x514b00554e00603100521600503100514600614100521600514100501a", + "0x21600520a00517200600621600500601200614b03114112500514b005216", + "0x20700501a00603d00521600513b00554f0060062160051250050ca006006", + "0x3d00521600503d00554e006019005216005019005146006207005216005", + "0xbd0060062160051250050ca00600621600500601200603d019207125005", + "0x504000554d00604000521600503f02301012554c00603f005216005006", + "0x601900521600501900514600601d00521600501d00501a00614e005216", + "0x2300600621600500601200614e01901d12500514e00521600514e00554e", + "0x60062160050100051720060062160051250050ca00600621600500c005", + "0x521600504400502d006044005216005006059006150005216005006208", + "0xc13d00604700521600500613b00615200521600504415000c02f006044", + "0x21600501a00501a00615e00521600515600554f006156005216005152047", + "0x12500515e00521600515e00554e00601e00521600501e00514600601a005", + "0x600501a00601d00521600500620d0060062160050060c400615e01e01a", + "0xc00521600500c005199006005005216005005005146006006005216005", + "0x1000502d00601d00521600501d005026006125005216005125005148006", + "0x1d12500c00500601955000601200521600501200502d006010005216005", + "0x555102100521600c0200050b00060201e901e01a019012216005012010", + "0x52160050060bd0060062160050210050a9006006216005006012006023", + "0x501a0060260052160050250053a500602500521600520d0053a400620d", + "0x521600501e00519900601a00521600501a005146006019005216005019", + "0x190120050260052160050260053a60061e90052160051e900514800601e", + "0x1a00620c0052160050230053a70060062160050060120060261e901e01a", + "0x21600501e00519900601a00521600501a005146006019005216005019005", + "0x1200520c00521600520c0053a60061e90052160051e900514800601e005", + "0x60100052160050100052210060062160050060c400620c1e901e01a019", + "0x521600500620800601d005216005006208006012005216005010005552", + "0x501a00600621600501a00547e00601e01a00c21600501200547d006019", + "0x521600501e00547f006005005216005005005146006006005216005006", + "0x1248000601900521600501900504e00601d00521600501d00504e00601e", + "0x55302300521600c0210054810060210201e912521600501901d01e005006", + "0x5100620c02602512521600502300548300600621600500601200620d005", + "0x21600502800517200602a02800c21600502500505200600621600520c005", + "0x17200620720800c21600502600505200620a00521600502a005055006006", + "0x60062160050060b400602d005216005207005055006006216005208005", + "0xc02001039c00602d00521600502d00501d00620a00521600520a00501d", + "0xbd00600621600500601200603114113d12555413b02f00c21600c02d20a", + "0x521600502f00514600614800521600514600539e006146005216005006", + "0x61b000603900521600514800539f00603500521600513b00514800614a", + "0x51460060170052160050310053a1006006216005006012006006555005", + "0x521600501700539f00603500521600514100514800614a00521600513d", + "0x14b00555603c00521600c03a0050b000603a0052160050390053a2006039", + "0x3d00521600503c0054780060062160050060c4006006216005006012006", + "0x501a00604000521600503f00521b00603f00521600503d12500c2df006", + "0x521600503500514800614a00521600514a0051460061e90052160051e9", + "0x21600500601200604003514a1e90100050400052160050400052cd006035", + "0x21600514b0052cc0060062160051250051520060062160050060c4006006", + "0x14800614a00521600514a0051460061e90052160051e900501a00614e005", + "0x14e03514a1e901000514e00521600514e0052cd006035005216005035005", + "0x521600520d0052cc006006216005125005152006006216005006012006", + "0x51480060200052160050200051460061e90052160051e900501a006150", + "0x615000c0201e90100051500052160051500052cd00600c00521600500c", + "0x602000521600500653e0061e90052160050062080060062160050060c4", + "0x2100c02f0060210052160050201e900c02f00602000521600502000502d", + "0x521600500620d00620d00521600501d02300c02f006023005216005012", + "0x505500600621600502600517200620c02600c21600520d005052006025", + "0x521600500500514600600600521600500600501a00602800521600520c", + "0x514800612500521600512500519900600c00521600500c00519b006005", + "0x521600502800501d006025005216005025005026006010005216005010", + "0x50cf00601a00521600501a00502600601900521600501900519f006028", + "0x21600501e01a01902802501012500c0050061e955700601e00521600501e", + "0x1200613d00555813b00521600c02f00504a00602f02d20720820a02a01d", + "0x3100521600514100505700614100521600513b005162006006216005006", + "0x20a00514600602a00521600502a00501a006146005216005031005174006", + "0x20700521600520700519900620800521600520800519b00620a005216005", + "0x20a02a01d00514600521600514600514a00602d00521600502d005148006", + "0x1a00614800521600513d00514100600621600500601200614602d207208", + "0x21600520800519b00620a00521600520a00514600602a00521600502a005", + "0x14a00602d00521600502d005148006207005216005207005199006208005", + "0x52160050060bd00614802d20720820a02a01d005148005216005148005", + "0x555a00600600521600500600501d00600c005216005005005559006005", + "0x500600c0061e90052160050060b200600c00600c00500c00521600500c", + "0x500514600600600521600500600501a0060062160050060c4006006216", + "0x10005216005010005148006125005216005125005199006005005216005", + "0x53f900602000521600502000502d00602001200c216005012005105006", + "0x20d02302101221600501d02001012500500601d40400601d00521600501d", + "0x600621600500601200602800555b20c00521600c02600504a006026025", + "0x502300514600602100521600502100501a00601e00521600520c005162", + "0x620d00521600520d00519900600c00521600500c00519b006023005216", + "0x501e00514700601200521600501200502d006025005216005025005148", + "0x1900521600501900502600602a00521600502a00501d00602a01e00c216", + "0x1e55c00601e00521600501e1e900c0b600601a00521600501a0050cf006", + "0x55d00613b02f02d20720820a01d21600501a01902a01202520d00c023021", + "0x513d00555f00600621600500601200614100555e13d00521600c13b005", + "0x1480052160051460053fc00614600521600503101e00c560006031005216", + "0x20800514600620a00521600520a00501a00614a0052160051480053fd006", + "0x2d00521600502d00519900620700521600520700519b006208005216005", + "0x20820a01d00514a00521600514a00521f00602f00521600502f005148006", + "0x53f700600621600501e00516800600621600500601200614a02f02d207", + "0x521600520800514600620a00521600520a00501a006035005216005141", + "0x514800602d00521600502d00519900620700521600520700519b006208", + "0x2f02d20720820a01d00503500521600503500521f00602f00521600502f", + "0x21600501900502300600621600501a0050ca006006216005006012006035", + "0x50280053f70060062160051e900519300600621600501200520a006006", + "0x602300521600502300514600602100521600502100501a006039005216", + "0x502500514800620d00521600520d00519900600c00521600500c00519b", + "0x603902520d00c02302101d00503900521600503900521f006025005216", + "0x21600501000556200601000c00c21600500c0055610060062160050060c4", + "0x2100601900521600501d00556400601d005216005012005563006012005", + "0x21600501e00502500600621600501a00502300601e01a00c216005019005", + "0x2f00602000521600502000502d0060200052160051e90051bd0061e9005", + "0x500600501a00602300521600500c00556200602100521600502012500c", + "0x6023005216005023005400006005005216005005005146006006005216", + "0x2602520d12521600502102300500601056500602100521600502100504e", + "0x517000600621600500601200602800556620c00521600c026005050006", + "0x520800511300620800521600520a02a00c11100620a02a00c21600520c", + "0x602500521600502500514600620d00521600520d00501a006207005216", + "0x14500600621600500601200620702520d125005207005216005207005142", + "0x21600502500514600620d00521600520d00501a00602d005216005028005", + "0x2160050060c400602d02520d12500502d00521600502d005142006025005", + "0x20800600621600500601200601900556801d00521600c012005567006006", + "0x21600501e00520a0061e901e00c2160050100052f100601a005216005006", + "0xc21a00601a00521600501a00504e0061e90052160051e900502d006006", + "0x21600501d00556900600621600502100505100602102000c21600501a1e9", + "0x600621600502500520a00602602500c2160050230052f100620d02300c", + "0x2002600c21a00602000521600502000504e00602600521600502600502d", + "0x2a00c21600520c00505200600621600502800505100602820c00c216005", + "0x600501a00620800521600520a00505500600621600502a00517200620a", + "0xc00521600500c005199006005005216005005005146006006005216005", + "0x2d20701021600520800c0050060103c400620800521600520800501d006", + "0x600621600500601200614100556a13d00521600c13b00510700613b02f", + "0x21600520700501a00614600521600500620d00603100521600513d00514f", + "0x14800602f00521600502f00519900602d00521600502d005146006207005", + "0x21600503100502d006146005216005146005026006125005216005125005", + "0x20d03114612502f02d20701956b00620d00521600520d00502d006031005", + "0x603c00556d03a00521600c01700556c00601703903514a148012216005", + "0xc21600514b00505200614b00521600503a00556e006006216005006012", + "0x501a00604000521600503f00505500600621600503d00517200603f03d", + "0x521600503500519900615000521600514a00514600614e005216005148", + "0x61b000604700521600504000501d006152005216005039005148006044", + "0x501a00615600521600503c00514100600621600500601200600656f005", + "0x521600503500519900614a00521600514a005146006148005216005148", + "0x14801200515600521600515600514a006039005216005039005148006035", + "0x514100600621600520d00520a00600621600500601200615603903514a", + "0x521600502d00514600620700521600520700501a00615e005216005141", + "0x514a00612500521600512500514800602f00521600502f00519900602d", + "0x5100600621600500601200615e12502f02d20701200515e00521600515e", + "0x61620052160050060bd00604a00521600500620d006006216005019005", + "0x500500514600600600521600500600501a00604c0052160051620053f8", + "0x612500521600512500514800600c00521600500c005199006005005216", + "0x504c0053f900601000521600501000502d00604a00521600504a005026", + "0x5016d04e16801221600504c01004a12500c00500601957000604c005216", + "0x16200600621600500601200605200557105100521600c17000504a006170", + "0x21600504e00514600614e00521600516800501a006172005216005051005", + "0x1d00615200521600505000514800604400521600516d005199006150005", + "0x216005055005174006055005216005047005057006047005216005172005", + "0x19900615000521600515000514600614e00521600514e00501a006057005", + "0x21600505700514a006152005216005152005148006044005216005044005", + "0x505200514100600621600500601200605715204415014e012005057005", + "0x604e00521600504e00514600616800521600516800501a006174005216", + "0x517400514a00605000521600505000514800616d00521600516d005199", + "0x65720060062160051250050fe00617405016d04e168012005174005216", + "0x600600521600500600501a00601200521600500620d006010005216005", + "0x501200502600600c00521600500c005148006005005216005005005146", + "0x501001200c005006012574006010005216005010005573006012005216", + "0x60120060200055761e900521600c01e00557500601e01a01901d010216", + "0x60210052160050210055780060210052160051e9005577006006216005", + "0x1200602500557a20d00521600c02300540c006023005216005021005579", + "0x20c00521600502600557b00602600521600520d005412006006216005006", + "0x1900514600601d00521600501d00501a00602800521600520c00557c006", + "0x2800521600502800557d00601a00521600501a005148006019005216005", + "0x2a00521600502500557e00600621600500601200602801a01901d010005", + "0x1a00514800601900521600501900514600601d00521600501d00501a006", + "0x1200602a01a01901d01000502a00521600502a00557d00601a005216005", + "0x1d00521600501d00501a00620a00521600502000557e006006216005006", + "0x20a00557d00601a00521600501a005148006019005216005019005146006", + "0x620d00601000521600500657200620a01a01901d01000520a005216005", + "0x5005216005005005148006006005216005006005146006012005216005", + "0x12500540f006010005216005010005573006012005216005012005026006", + "0x3a200601a01901d12521600512501001200500601257f006125005216005", + "0x60120060200055801e900521600c01e0050b000601e00521600501a005", + "0x60062160050230050fe00602302100c21600500c00540a006006216005", + "0x2500558100602500521600520d02100c22c00620d0052160051e9005478", + "0x1900521600501900514800601d00521600501d005146006026005216005", + "0x600621600500601200602601901d125005026005216005026005582006", + "0x21600501d00514600620c00521600502000558300600621600500c0050fe", + "0x12500520c00521600520c00558200601900521600501900514800601d005", + "0x55840060100052160050100054160060062160050060c400620c01901d", + "0x601900521600500620800601d005216005006208006012005216005010", + "0x500600501a00600621600501a00547e00601e01a00c21600501200547d", + "0x601e00521600501e00547f006005005216005005005146006006005216", + "0x500601248000601900521600501900504e00601d00521600501d00504e", + "0x20d00558502300521600c0210054810060210201e912521600501901d01e", + "0x20c00505100620c026025125216005023005483006006216005006012006", + "0x600621600502800517200602a02800c216005025005052006006216005", + "0x20800517200620720800c21600502600505200620a00521600502a005055", + "0x501d0060062160050060b400602d005216005207005055006006216005", + "0x2d20a00c02001039c00602d00521600502d00501d00620a00521600520a", + "0x50060bd00600621600500601200603114113d12558613b02f00c21600c", + "0x614a00521600502f00514600614800521600514600539e006146005216", + "0x5870050061b000603900521600514800539f00603500521600513b005148", + "0x513d0051460060170052160050310053a1006006216005006012006006", + "0x603900521600501700539f00603500521600514100514800614a005216", + "0x1200614b00558803c00521600c03a0050b000603a0052160050390053a2", + "0x2df00603d00521600503c0054780060062160050060c4006006216005006", + "0x51e900501a00604000521600503f00521b00603f00521600503d12500c", + "0x603500521600503500514800614a00521600514a0051460061e9005216", + "0x600621600500601200604003514a1e90100050400052160050400052cd", + "0x14e00521600514b0052cc0060062160051250051520060062160050060c4", + "0x3500514800614a00521600514a0051460061e90052160051e900501a006", + "0x1200614e03514a1e901000514e00521600514e0052cd006035005216005", + "0x615000521600520d0052cc006006216005125005152006006216005006", + "0x500c0051480060200052160050200051460061e90052160051e900501a", + "0x514600615000c0201e90100051500052160051500052cd00600c005216", + "0x21600500500600c46b006005005216005005005148006006005216005006", + "0x21600500601200601d00558901200521600c01000546c00601012500c125", + "0x547000601a00521600501900546f00601900521600501200546e006006", + "0x2000506d00600621600501e0054710060230210201e901e01221600501a", + "0x558a00600621600502300520a00600621600502100506d006006216005", + "0x521600500c00514600602500521600520d00558b00620d0052160051e9", + "0xc12500502500521600502500558c00612500521600512500514800600c", + "0xc00514600602600521600501d00558d006006216005006012006025125", + "0x2600521600502600558c00612500521600512500514800600c005216005", + "0x600521600500600539f00600500521600500658e00602612500c125005", + "0x50b000600c00521600500500600c58f00600500521600500500502d006", + "0x21600512500547800600621600500601200601000559012500521600c00c", + "0x3a600601900521600501d0053a500601d0052160050120053a4006012005", + "0x50100053a7006006216005006012006019005005019005216005019005", + "0x62160050060c400601a00500501a00521600501a0053a600601a005216", + "0x5006208006012005216005010005591006010005216005010005435006", + "0x601e01a00c21600501200547d00601900521600500620800601d005216", + "0x21600500500514600600600521600500600501a00600621600501a00547e", + "0x4e00601d00521600501d00504e00601e00521600501e00547f006005005", + "0x210201e912521600501901d01e005006012480006019005216005019005", + "0x548300600621600500601200620d00559202300521600c021005481006", + "0x21600502500505200600621600520c00505100620c026025125216005023", + "0x5200620a00521600502a00505500600621600502800517200602a02800c", + "0x21600520700505500600621600520800517200620720800c216005026005", + "0x2d00501d00620a00521600520a00501d0060062160050060b400602d005", + "0x14113d12559313b02f00c21600c02d20a00c02001039c00602d005216005", + "0x21600514600539e0061460052160050060bd006006216005006012006031", + "0x39f00603500521600513b00514800614a00521600502f005146006148005", + "0x3a10060062160050060120060065940050061b0006039005216005148005", + "0x21600514100514800614a00521600513d005146006017005216005031005", + "0xb000603a0052160050390053a200603900521600501700539f006035005", + "0x2160050060c400600621600500601200614b00559503c00521600c03a005", + "0x21b00603f00521600503d12500c2df00603d00521600503c005478006006", + "0x21600514a0051460061e90052160051e900501a00604000521600503f005", + "0x100050400052160050400052cd00603500521600503500514800614a005", + "0x1250051520060062160050060c400600621600500601200604003514a1e9", + "0x61e90052160051e900501a00614e00521600514b0052cc006006216005", + "0x514e0052cd00603500521600503500514800614a00521600514a005146", + "0x512500515200600621600500601200614e03514a1e901000514e005216", + "0x1460061e90052160051e900501a00615000521600520d0052cc006006216", + "0x2160051500052cd00600c00521600500c005148006020005216005020005", + "0x512500533d0060100052160050064db00615000c0201e9010005150005", + "0x35600601900521600500620d00601d00521600501000544b006012005216", + "0x21600501900502600600621600501e00515500601e01a00c21600500c005", + "0x21600c01201d01900500601247400601d00521600501d0054dc006019005", + "0x52160050060bd00600621600500601200620d0230211255960201e900c", + "0x514800620c0052160051e900514600602600521600502500539e006025", + "0x60065970050061b000602a00521600502600539f006028005216005020", + "0x521600502100514600620a00521600520d0053a1006006216005006012", + "0x53a200602a00521600520a00539f00602800521600502300514800620c", + "0x500601200602d00559820700521600c2080050b000620800521600502a", + "0x613b00521600502f01a00c59900602f005216005207005478006006216", + "0x502800514800620c00521600520c00514600613d00521600513b00559a", + "0x500601200613d02820c12500513d00521600513d00559b006028005216", + "0x514600614100521600502d00559c00600621600501a005155006006216", + "0x521600514100559b00602800521600502800514800620c00521600520c", + "0x21600500500514800600600521600500600514600614102820c125005141", + "0x521600c01000546c00601012500c12521600500500600c46b006005005", + "0x46f00601900521600501200546e00600621600500601200601d00559d012", + "0x4710060230210201e901e01221600501a00547000601a005216005019005", + "0x600621600502000506d0060062160051e900547200600621600501e005", + "0x21600520d00541c00620d00521600502100541b00600621600502300520a", + "0x41d00612500521600512500514800600c00521600500c005146006025005", + "0x541e00600621600500601200602512500c125005025005216005025005", + "0x521600512500514800600c00521600500c00514600602600521600501d", + "0x62160050060c400602612500c12500502600521600502600541d006125", + "0x500620800601200521600501000559e006010005216005010005443006", + "0x601e01a00c21600501200547d00601900521600500620800601d005216", + "0x21600500500514600600600521600500600501a00600621600501a00547e", + "0x4e00601d00521600501d00504e00601e00521600501e00547f006005005", + "0x210201e912521600501901d01e005006012480006019005216005019005", + "0x548300600621600500601200620d00559f02300521600c021005481006", + "0x21600502500505200600621600520c00505100620c026025125216005023", + "0x5200620a00521600502a00505500600621600502800517200602a02800c", + "0x21600520700505500600621600520800517200620720800c216005026005", + "0x2d00501d00620a00521600520a00501d0060062160050060b400602d005", + "0x14113d1255a013b02f00c21600c02d20a00c02001039c00602d005216005", + "0x21600514600539e0061460052160050060bd006006216005006012006031", + "0x39f00603500521600513b00514800614a00521600502f005146006148005", + "0x3a10060062160050060120060065a10050061b0006039005216005148005", + "0x21600514100514800614a00521600513d005146006017005216005031005", + "0xb000603a0052160050390053a200603900521600501700539f006035005", + "0x2160050060c400600621600500601200614b0055a203c00521600c03a005", + "0x21b00603f00521600503d12500c2df00603d00521600503c005478006006", + "0x21600514a0051460061e90052160051e900501a00604000521600503f005", + "0x100050400052160050400052cd00603500521600503500514800614a005", + "0x1250051520060062160050060c400600621600500601200604003514a1e9", + "0x61e90052160051e900501a00614e00521600514b0052cc006006216005", + "0x514e0052cd00603500521600503500514800614a00521600514a005146", + "0x512500515200600621600500601200614e03514a1e901000514e005216", + "0x1460061e90052160051e900501a00615000521600520d0052cc006006216", + "0x2160051500052cd00600c00521600500c005148006020005216005020005", + "0x2160050065a300600621600500c0051f200615000c0201e9010005150005", + "0x2d00601d0052160050120055a50060120052160050100055a4006010005", + "0x55a400601a01900c21600512501d0051255a600601d00521600501d005", + "0x52160051e900502d0061e900521600501e0055a500601e00521600501a", + "0x602000521600502000501a00602102000c2160051e900600c5a70061e9", + "0x21019020125005021005216005021005573006019005216005019005031", + "0x545400600621600500601200600c0055a900500521600c0060055a8006", + "0x5216005010005456006010005216005125005455006125005216005005", + "0xc13d00601200521600500613b006006216005006012006010005005010", + "0x21600501900545600601900521600501d00545700601d00521600500c012", + "0x1d0121255ab01012500c12521600c00500600c5aa006019005005019005", + "0x500c00514600601a0052160050100055ac006006216005006012006019", + "0x602000521600501a0055ad0061e900521600512500514800601e005216", + "0x60210052160050190055af0060062160050060120060065ae0050061b0", + "0x50210055ad0061e900521600501d00514800601e005216005012005146", + "0x5b120d00521600c02300546c0060230052160050200055b0006020005216", + "0x260055b200602600521600520d00546e006006216005006012006025005", + "0x1e00521600501e00514600602800521600520c0055b300620c005216005", + "0x1e901e1250050280052160050280055b40061e90052160051e9005148006", + "0x501e00514600602a0052160050250055b5006006216005006012006028", + "0x502a00521600502a0055b40061e90052160051e900514800601e005216", + "0x500521600500500547f0060050052160050060055b600602a1e901e125", + "0x1d0055b801200521602000c0055b70060062160050060c4006005005005", + "0x55bf0210055be0200055bd1e90055bc01e0055bb01a0055ba0190055b9", + "0x260052160050065c20060062160050060120060250055c120d0055c0023", + "0x544300620c00521600502612500c02f00602600521600502600502d006", + "0x521600501000504e00620c00521600520c00504e006012005216005012", + "0x621600520a00505100620a02a02812521600501020c01212522e006010", + "0x2800504e00620700521600500500514600620800521600500600501a006", + "0x120060065c30050061b000602f00521600502a00504e00602d005216005", + "0x613b00521600513b00502d00613b0052160050065c4006006216005006", + "0x13d00504e00601d00521600501d00536e00613d00521600513b12500c02f", + "0x21600501013d01d1255c500601000521600501000504e00613d005216005", + "0x620800521600500600501a006006216005146005051006146031141125", + "0x503100504e00602d00521600514100504e006207005216005005005146", + "0x2160050065c60060062160050060120060065c30050061b000602f005216", + "0x614a00521600514812500c02f00614800521600514800502d006148005", + "0x501000504e00614a00521600514a00504e00601900521600501900537c", + "0x501700505100601703903512521600501014a0191255c7006010005216", + "0x4e00620700521600500500514600620800521600500600501a006006216", + "0x65c30050061b000602f00521600503900504e00602d005216005035005", + "0x521600503a00502d00603a0052160050065c8006006216005006012006", + "0x4e00601a00521600501a00543500603c00521600503a12500c02f00603a", + "0x1003c01a1255c900601000521600501000504e00603c00521600503c005", + "0x521600500600501a00600621600503f00505100603f03d14b125216005", + "0x504e00602d00521600514b00504e006207005216005005005146006208", + "0x65ca0060062160050060120060065c30050061b000602f00521600503d", + "0x521600504012500c02f00604000521600504000502d006040005216005", + "0x52d700600500521600500500514600600600521600500600501a00614e", + "0x521600501000504e00614e00521600514e00504e00601e00521600501e", + "0xc15200548100615204415012521600501014e01e00500601222d006010", + "0x15e1252160050470054830060062160050060120061560055cb047005216", + "0x514600620800521600515000501a00600621600516200505100616204a", + "0x521600504a00504e00602d00521600515e00504e006207005216005044", + "0x52160051560055cc0060062160050060120060065c30050061b000602f", + "0x55cd00604400521600504400514600615000521600515000501a00604c", + "0x50065ce00600621600500601200604c04415012500504c00521600504c", + "0x4e00521600516812500c02f00616800521600516800502d006168005216", + "0x1000504e00604e00521600504e00504e0061e90052160051e900534b006", + "0x17000505100617005016d12521600501004e1e91255cf006010005216005", + "0x620700521600500500514600620800521600500600501a006006216005", + "0x5c30050061b000602f00521600505000504e00602d00521600516d00504e", + "0x21600505100502d0060510052160050065d0006006216005006012006006", + "0x600600521600500600501a00605200521600505112500c02f006051005", + "0x505200504e0060200052160050200053ca006005005216005005005146", + "0x50100520200050060125d100601000521600501000504e006052005216", + "0x50060120060590055d217400521600c057005481006057055172125216", + "0x600621600517a00505100617a05b178125216005174005483006006216", + "0x517800504e00620700521600505500514600620800521600517200501a", + "0x60120060065c30050061b000602f00521600505b00504e00602d005216", + "0x617200521600517200501a00605d0052160050590055cc006006216005", + "0x5d05517212500505d00521600505d0055cd006055005216005055005146", + "0x521600517f00502d00617f0052160050065d3006006216005006012006", + "0x14600600600521600500600501a00618100521600517f12500c02f00617f", + "0x21600518100504e006021005216005021005221006005005216005005005", + "0x2160050101810210050060125d400601000521600501000504e006181005", + "0x2160050060120060670055d506500521600c186005481006186185061125", + "0x1a00600621600518a00505100618a06b069125216005065005483006006", + "0x21600506900504e006207005216005185005146006208005216005061005", + "0x50060120060065c30050061b000602f00521600506b00504e00602d005", + "0x14600606100521600506100501a00606d0052160050670055cc006006216", + "0x606d18506112500506d00521600506d0055cd006185005216005185005", + "0x18d00521600518d00502d00618d0052160050065d6006006216005006012", + "0x504e0060230052160050230052190060ba00521600518d12500c02f006", + "0x50100ba0231255d700601000521600501000504e0060ba0052160050ba", + "0x20800521600500600501a006006216005072005051006072196070125216", + "0x19600504e00602d00521600507000504e006207005216005005005146006", + "0x50065d80060062160050060120060065c30050061b000602f005216005", + "0x19d00521600519a12500c02f00619a00521600519a00502d00619a005216", + "0x1000504e00619d00521600519d00504e00620d00521600520d005300006", + "0x1a10050510061a11a007612521600501019d20d1255d9006010005216005", + "0x620700521600500500514600620800521600500600501a006006216005", + "0x5c30050061b000602f0052160051a000504e00602d00521600507600504e", + "0x2160051a200502d0061a20052160050065da006006216005006012006006", + "0x602500521600502500541600607b0052160051a212500c02f0061a2005", + "0x7b0251255db00601000521600501000504e00607b00521600507b00504e", + "0x21600500600501a00600621600507e00505100607e1a81a4125216005010", + "0x4e00602d0052160051a400504e006207005216005005005146006208005", + "0x51ab02f02d1255dc0061ab0052160050060bd00602f0052160051a8005", + "0x620800521600520800501a00608d00521600508c00522b00608c005216", + "0x8d20720812500508d00521600508d0055cd006207005216005207005146", + "0x50065de00601201000c2160051250055dd00600621600500c005103006", + "0x601a0052160050190055a500601900521600501d0055a400601d005216", + "0x36a0061e901e00c21600501001a0051255a600601a00521600501a00502d", + "0x2160050210055a50060210052160051e90055a4006020005216005012005", + "0x20d00c21600502002301e1255a600602300521600502300502d006023005", + "0x502d00620c0052160050260055a50060260052160050250055a4006025", + "0x502800501a00602a02800c21600520c00600c5a700620c00521600520c", + "0x502a00521600502a00557300620d00521600520d005031006028005216", + "0x21600500601200600c0055e000500521600c0060055df00602a20d028125", + "0x52eb0060100052160051250052ea00612500521600500500517c006006", + "0x521600500613b006006216005006012006010005005010005216005010", + "0x2eb00601900521600501d0052ec00601d00521600500c01200c13d006012", + "0x547f0060050052160050060055e1006019005005019005216005019005", + "0x51250055dd00600621600500c005153006005005005005005216005005", + "0x601900521600501d0055a400601d0052160050065e200601201000c216", + "0x1a0051255a600601a00521600501a00502d00601a0052160050190055a5", + "0x2160051e90055a400602000521600501200536a0061e901e00c216005010", + "0x5a600602300521600502300502d0060230052160050210055a5006021005", + "0x55a50060260052160050250055a400602520d00c21600502002301e125", + "0x21600520c00600c5a700620c00521600520c00502d00620c005216005026", + "0x620d00521600520d00503100602800521600502800501a00602a02800c", + "0x50052160050060055e300602a20d02812500502a00521600502a005573", + "0xc00601a00521600500600500600500500500500521600500500547f006", + "0x509100601e0052160050062080060062160050060c4006006216005006", + "0x521600502000508c0060062160051e90051ab0060201e900c216005010", + "0x602302100c21600501e02000c09200601e00521600501e00504e006020", + "0x520d00520a00602520d00c2160050120052f1006006216005023005051", + "0x21a00602100521600502100504e00602500521600502500502d006006216", + "0x501d00504c00600621600520c00505100620c02600c21600502102500c", + "0x600600521600500600501a00600621600502800516800602a02800c216", + "0x502600504e00602a00521600502a00501d006005005216005005005146", + "0x20700505000620720820a12521600502602a00500601016d006026005216", + "0xc21600502d00517000600621600500601200602f0055e402d00521600c", + "0x65e500614100521600512500541300600621600513d00505100613d13b", + "0x621600514600517200614814600c21600513b005052006031005216005", + "0x21600503100502d0060062160050060b400614a005216005148005055006", + "0x21600c14a03114100c2080124e900614a00521600514a00501d006031005", + "0x501700522500600621600500601200614b03c03a1255e6017039035125", + "0x601900521600503900514800603f00521600503500514600603d005216", + "0x60062160050060120060065e70050061b000604000521600503d0054eb", + "0x503c00514800603f00521600503a00514600614e00521600514b0054ed", + "0x61500052160050400054ee00604000521600514e0054eb006019005216", + "0x61520055e804400521600c15000504a00601900521600501901a00c15e", + "0x60470052160050440051620060062160050060c4006006216005006012", + "0x504700501d00603f00521600503f00514600620a00521600520a00501a", + "0xc04a00517f00604a15e15612521600504703f20a12505d006047005216", + "0x16800c21600516200518100600621600500601200604c0055e9162005216", + "0x60500055ea16d00521600c04e00506100600621600516800516800604e", + "0x521600517000517400617000521600516d005057006006216005006012", + "0x514800615e00521600515e00514600615600521600515600501a006051", + "0x605101915e15601000505100521600505100514a006019005216005019", + "0x6052005216005006208006006216005050005051006006216005006012", + "0x517205200c02f00617200521600517200502d0061720052160050065eb", + "0x617400521600505505700c13d00605700521600500613b006055005216", + "0x515e00514600615600521600515600501a006059005216005174005141", + "0x505900521600505900514a00601900521600501900514800615e005216", + "0x617800521600504c00514100600621600500601200605901915e156010", + "0x501900514800615e00521600515e00514600615600521600515600501a", + "0x601200617801915e15601000517800521600517800514a006019005216", + "0x501a00605b0052160051520051410060062160050060c4006006216005", + "0x521600501900514800603f00521600503f00514600620a00521600520a", + "0x21600500601200605b01903f20a01000505b00521600505b00514a006019", + "0x502f0051410060062160051250055ec00600621600501a00502a006006", + "0x620800521600520800514600620a00521600520a00501a00617a005216", + "0xc20820a01000517a00521600517a00514a00600c00521600500c005148", + "0x50100055a40060100052160050065ed00600621600500c00510100617a", + "0x601d00521600501d00502d00601d0052160050120055a5006012005216", + "0x5a500601e00521600501a0055a400601a01900c21600512501d0051255a6", + "0x51e900600c5a70061e90052160051e900502d0061e900521600501e005", + "0x1900521600501900503100602000521600502000501a00602102000c216", + "0x21600c00500600c328006021019020125005021005216005021005573006", + "0x1200521600512500532a0060062160050060120060100055ee12500c00c", + "0x50061b000601900521600501200532b00601d00521600500c00501a006", + "0x501a00532c00601a0052160050060bd0060062160050060120060065ef", + "0x501900521600501e00532b00601d00521600501000501a00601e005216", + "0x621600500601200600c0055f100500521600c0060055f000601901d00c", + "0x10005353006010005216005125005352006125005216005005005351006", + "0x1200521600500613b006006216005006012006010005005010005216005", + "0x535300601900521600501d00535400601d00521600500c01200c13d006", + "0x500547f0060050052160050060055f2006019005005019005216005019", + "0x1200600c0055f400500521600c0060055f3006005005005005005216005", + "0x10005216005125005174006125005216005005005057006006216005006", + "0x613b00600621600500601200601000500501000521600501000514a006", + "0x521600501d00514100601d00521600500c01200c13d006012005216005", + "0x50052160050060055f500601900500501900521600501900514a006019", + "0x60050052160050060055f600600500500500500521600500500547f006", + "0x55f800500521600c0060055f700600500500500500521600500500547f", + "0x512500551600612500521600500500551500600621600500601200600c", + "0x6216005006012006010005005010005216005010005224006010005216", + "0x1d00551100601d00521600500c01200c13d00601200521600500613b006", + "0xc00600522a006019005005019005216005019005224006019005216005", + "0x600621600500500520a0060062160050060120061250055f900c005216", + "0x501200522400601200521600501000551600601000521600500c005515", + "0x6006216005125005023006006216005006012006012005005012005216", + "0x21600500613b00601900521600500501d00c02f00601d005216005006208", + "0x61e900521600501e00551100601e00521600501901a00c13d00601a005", + "0x50060350060062160050060c40061e90050051e90052160051e9005224", + "0xc21600c01d00500612501700601d00521600501d00503900601d005216", + "0x201252160050100055fb0060062160050060120061e901e00c5fa01a019", + "0x1900501a0060062160050060b400620d0052160050120051e9006023021", + "0x500601200620c0055fc02602500c21600c20d0051b6006019005216005", + "0x1b200602a0052160050250051b40060280052160050260050b8006006216", + "0xbd0060062160050060120060065fd0050061b000620a005216005028005", + "0x521600520c0051b40062070052160052080051ac006208005216005006", + "0x501d00602d00521600502a00505500620a0052160052070051b200602a", + "0x500601200613b0055fe02f00521600c20a0051ae00602d00521600502d", + "0x1e900614100521600513d0050c100613d00521600502f0050bf006006216", + "0x21600c0310051b600614100521600514100502d00603100521600502d005", + "0x350052160051480050b800600621600500601200614a0055ff14814600c", + "0x50061b00060170052160050350051b20060390052160051460051b4006", + "0x503a0051ac00603a0052160050060bd006006216005006012006006600", + "0x601700521600503c0051b200603900521600514a0051b400603c005216", + "0xc0170051ae00614b00521600514b00501d00614b005216005039005055", + "0x4000521600503d0050bf00600621600500601200603f00560103d005216", + "0x502d0061500052160050400050c100614e00521600514102000c14d006", + "0x21600514e00502d00604400521600515002100c14d006150005216005150", + "0x1021600502304414e00c01060200604400521600504400502d00614e005", + "0x521600515200519900604a12500c21600512500560300615e156047152", + "0x502d00615600521600515600502d00604700521600504700502d006152", + "0x4e16800c60404c16200c21600c04a01a01912501700615e00521600515e", + "0x21600515e1560471255380060062160050060c4006006216005006012006", + "0x19900604c00521600504c00514600616200521600516200501a00616d005", + "0x21600516d005539006125005216005125005039006152005216005152005", + "0x514b16d12515204c16201d53a00614b00521600514b00501d00616d005", + "0x601200605500560517200521600c05200553b006052051170050010216", + "0x521600517405700c60600617405700c21600517200553d006006216005", + "0x514600605000521600505000501a006178005216005059005607006059", + "0x5216005178005608006051005216005051005199006170005216005170", + "0x5216005055005609006006216005006012006178051170050010005178", + "0x519900617000521600517000514600605000521600505000501a00605b", + "0x605b05117005001000505b00521600505b005608006051005216005051", + "0x20a00600621600514b0051680060062160050060c4006006216005006012", + "0x600621600515600520a00600621600512500560a006006216005047005", + "0x5d00521600500605900617a00521600500620800600621600515e00520a", + "0x613b00617f00521600505d17a00c02f00605d00521600505d00502d006", + "0x521600506100560900606100521600517f18100c13d006181005216005", + "0x519900604e00521600504e00514600616800521600516800501a006185", + "0x618515204e168010005185005216005185005608006152005216005152", + "0x600621600512500560a00600621600503f005051006006216005006012", + "0x50650052f90060650052160050060bd00618600521600514102000c14d", + "0x21600506900560c00606900521600506702302118601060b006067005216", + "0x521600506b00502d00618d00521600518d00519d00618d06d18a06b010", + "0x512f00606d00521600506d00502d00618a00521600518a00502d00606b", + "0x2160050ba00505100600621600500601200607000560d0ba00521600c18d", + "0x502d00607200521600519606b00c14d006196005216005006109006006", + "0x61a007619d19a01021600506d18a07200c010602006072005216005072", + "0x521600519a0051990060062160051a000520a00600621600507600520a", + "0x21600500601200600660e0050061b00061a200521600519d00502d0061a1", + "0x7b18a00c14d00607b005216005006109006006216005070005051006006", + "0x506d1a406b00c0106020061a40052160051a400502d0061a4005216005", + "0x621600508c00520a0060062160051ab00520a00608c1ab07e1a8010216", + "0x50060c40061a200521600507e00502d0061a10052160051a8005199006", + "0x608e00521600508d00560700608d0052160051a214b00c606006006216", + "0x51a100519900601a00521600501a00514600601900521600501900501a", + "0x601200608e1a101a01901000508e00521600508e0056080061a1005216", + "0x60bd00600621600512500560a00600621600513b005051006006216005", + "0x509002302102001060b00609000521600508f00530900608f005216005", + "0x21600509500519d00609509409309201021600509100560c006091005216", + "0x2d00609300521600509300502d00609200521600509200502d006095005", + "0x60120061b500560f09600521600c09500512f006094005216005094005", + "0xc14d00609b005216005006109006006216005096005051006006216005", + "0x9309c00c01060200609c00521600509c00502d00609c00521600509b092", + "0x50a100520a00600621600509700520a0060a109709f05f010216005094", + "0x1b00061be00521600509f00502d0061bd00521600505f005199006006216", + "0x61090060062160051b5005051006006216005006012006006610005006", + "0x52160050a600502d0060a60052160051c109300c14d0061c1005216005", + "0x50aa00520a0060ac0aa1bc0a80102160050940a609200c0106020060a6", + "0x502d0061bd0052160050a80051990060062160050ac00520a006006216", + "0xb00052160051be02d00c6060060062160050060c40061be0052160051bc", + "0x1a00514600601900521600501900501a0060a90052160050b0005607006", + "0xa90052160050a90056080061bd0052160051bd00519900601a005216005", + "0x60062160050120051680060062160050060120060a91bd01a019010005", + "0x9800521600500620800600621600501000561100600621600512500560a", + "0xb209800c02f0060b20052160050b200502d0060b2005216005006059006", + "0xb60052160051b90b400c13d0060b400521600500613b0061b9005216005", + "0x1e900514600601e00521600501e00501a0061b60052160050b6005609006", + "0x1b60052160051b600560800600c00521600500c0051990061e9005216005", + "0x230052160050060d90060200052160050060d70061b600c1e901e010005", + "0x60062160050060c400600621600500600c006025005216005006612006", + "0x512500519900600500521600500500514600600600521600500600501a", + "0x21600501d1250050060103c400601d00521600501d00501d006125005216", + "0x21600c0280051070061e90052160051e902000c0e30060281e920c026010", + "0x620800521600502a00514f00600621600500601200620a00561302a005", + "0x20700501a00602d00521600500620800620d20700c21600520802600c5a7", + "0xc00521600500c00519b00620c00521600520c005146006207005216005", + "0x1e0050cf00601a00521600501a00501d00602d00521600502d00504e006", + "0x2d00c20c20701d61500620d00521600520d02500c61400601e005216005", + "0x61600602100521600502102300c18200613d02113b02f01021600501e01a", + "0x514100522900600621600500601200603100561714100521600c13d005", + "0x621600514a0050ca00600621600514800516800603514a148146010216", + "0x513b00514600602f00521600502f00501a006006216005035005051006", + "0x614600521600514600504e00601000521600501000514800613b005216", + "0x501900519f00620d00521600520d005573006012005216005012005026", + "0x3c03a01703901021600501920d01214601013b02f019618006019005216", + "0x561b00600621600500601200603d00561a14b00521600c03c005619006", + "0x604000521600503f0053a400603f0052160050060bd00600621600514b", + "0x501700514600603900521600503900501a00614e0052160050400053a5", + "0x61e90052160051e900519900602100521600502100519b006017005216", + "0x2101703901d00514e00521600514e0053a600603a00521600503a005148", + "0x501a00615000521600503d0053a700600621600500601200614e03a1e9", + "0x521600502100519b006017005216005017005146006039005216005039", + "0x53a600603a00521600503a0051480061e90052160051e9005199006021", + "0x600621600500601200615003a1e902101703901d005150005216005150", + "0x621600501200502300600621600520d00561c0060062160050190050cc", + "0x13b00514600602f00521600502f00501a0060440052160050310053a7006", + "0x1e90052160051e900519900602100521600502100519b00613b005216005", + "0x13b02f01d0050440052160050440053a6006010005216005010005148006", + "0x50230060062160050190050cc0060062160050060120060440101e9021", + "0x16800600621600501e0050ca006006216005023005184006006216005012", + "0x15200521600520a0053a700600621600502500561d00600621600501a005", + "0xc00519b00620c00521600520c00514600602600521600502600501a006", + "0x100052160050100051480061e90052160051e900519900600c005216005", + "0x600561e0061520101e900c20c02601d0051520052160051520053a6006", + "0x21600500605b00600500500500500521600500500547f006005005216005", + "0x50060b20060210052160050060b20061e900521600500605b00601a005", + "0x500600501a0060062160050060c400600621600500600c00620d005216", + "0x600c00521600500c005199006005005216005005005146006006005216", + "0x2500502600602501000c2160050100052cf006125005216005125005148", + "0x521600502600502d00602601200c216005012005105006025005216005", + "0x61f00620c00521600520c00502d00620c01d00c21600501d005105006026", + "0x20700507000620720820a02a02801221600520c02602512500c005006019", + "0x521600502d00519600600621600500601200602f00562002d00521600c", + "0x5100600621600500601200614100562113d00521600c13b00512f00613b", + "0x600621600501200520a00600621600501a00506900600621600513d005", + "0x621600520d00519300600621600501d00520a006006216005010005023", + "0x52160050060bd0060062160050210051930060062160051e9005069006", + "0x501a0061480052160051460053a50061460052160050310053a4006031", + "0x521600520a00519900602a00521600502a005146006028005216005028", + "0x280120051480052160051480053a600620800521600520800514800620a", + "0x510500600621600514100505100600621600500601200614820820a02a", + "0x21600514a00562200614a00521600514a00502d00614a01200c216005012", + "0x19900602a00521600502a00514600602800521600502800501a006020005", + "0x2160050100052cf00620800521600520800514800620a00521600520a005", + "0x3902000c21600502000514700603500521600503500502600603501000c", + "0x1d62300602000521600502002100c0b600603900521600503900501d006", + "0x21600c03d00510700603d14b03c03a01701221600503903520820a02a028", + "0x614e00521600503f00514f00600621600500601200604000562403f005", + "0x501200510500601e00521600515014e00c33e006150005216005006109", + "0x1d00521600501d00502d00604400521600504400502d00604401200c216", + "0x514600601700521600501700501a00602300521600501d04400c625006", + "0x521600514b00514800603c00521600503c00519900603a00521600503a", + "0x14700615200521600515200502600615201000c2160050100052cf00614b", + "0x1e1e900c17a00604700521600504700501d00604702300c216005023005", + "0x14b03c03a01701d62300602300521600502320d00c0b600601e005216005", + "0x562616800521600c04c00510700604c16204a15e156012216005047152", + "0x21600500610900616d00521600516800514f00600621600500601200604e", + "0x1a0061700052160050062ef00601900521600505016d00c33e006050005", + "0x21600504a00519900615e00521600515e005146006156005216005156005", + "0x605101000c2160050100052cf00616200521600516200514800604a005", + "0x517000502d00602300521600502300501d006051005216005051005026", + "0x5116204a15e15601962700601900521600501901a00c17a006170005216", + "0x562805900521600c1740050b0006174057055172052012216005170023", + "0x21600505200501a0060062160050590050a9006006216005006012006178", + "0x148006055005216005055005199006172005216005172005146006052005", + "0x505b00502600605b01000c2160050100052cf006057005216005057005", + "0x17a01e00c21600501e00510500602000521600502000501d00605b005216", + "0x21600517a02005b05705517205201962700617a00521600517a00502d006", + "0x601200606500562918600521600c1850050b000618506118117f05d012", + "0x606701200c2160050120051050060062160051860050a9006006216005", + "0x1e06700c62a00601e00521600501e00502d00606700521600506700502d", + "0x17f00521600517f00514600605d00521600505d00501a006069005216005", + "0x100052cf006061005216005061005148006181005216005181005199006", + "0x521600506900501d00606b00521600506b00502600606b01000c216005", + "0x1070060700ba18d06d18a01221600506906b06118117f05d01d623006069", + "0x501200502d00600621600500601200607200562b19600521600c070005", + "0x19a00521600501901200c62a00601900521600501900502d006012005216", + "0x6d00514600618a00521600518a00501a00619d00521600519600514f006", + "0xba0052160050ba00514800618d00521600518d00519900606d005216005", + "0x19d00502d00619a00521600519a00501d006010005216005010005026006", + "0x1a11a007601221600519d19a0100ba18d06d18a01962700619d005216005", + "0x60062160050060120061a800562c1a400521600c07b0050b000607b1a2", + "0x521600507e0053a400607e0052160050060bd0060062160051a40050a9", + "0x514600607600521600507600501a00608c0052160051ab0053a50061ab", + "0x52160051a20051480061a10052160051a10051990061a00052160051a0", + "0x500601200608c1a21a11a007601200508c00521600508c0053a60061a2", + "0x14600607600521600507600501a00608d0052160051a80053a7006006216", + "0x2160051a20051480061a10052160051a10051990061a00052160051a0005", + "0x601200608d1a21a11a007601200508d00521600508d0053a60061a2005", + "0x520a00600621600501000502300600621600501200520a006006216005", + "0x18a00521600518a00501a00608e0052160050720053a7006006216005019", + "0xba00514800618d00521600518d00519900606d00521600506d005146006", + "0x608e0ba18d06d18a01200508e00521600508e0053a60060ba005216005", + "0x600621600501200520a00600621600501900520a006006216005006012", + "0x52160050650053a700600621600501e00520a006006216005010005023", + "0x519900617f00521600517f00514600605d00521600505d00501a00608f", + "0x521600508f0053a6006061005216005061005148006181005216005181", + "0x21600501900520a00600621600500601200608f06118117f05d01200508f", + "0x501e00520a00600621600501000502300600621600501200520a006006", + "0x501a0060900052160051780053a7006006216005020005168006006216", + "0x5216005055005199006172005216005172005146006052005216005052", + "0x520120050900052160050900053a6006057005216005057005148006055", + "0x502300600621600501200520a006006216005006012006090057055172", + "0x16800600621600502000516800600621600501e00520a006006216005010", + "0x9100521600504e0053a700600621600501a005069006006216005023005", + "0x4a00519900615e00521600515e00514600615600521600515600501a006", + "0x910052160050910053a600616200521600516200514800604a005216005", + "0x621600501a00506900600621600500601200609116204a15e156012005", + "0x21600501d00520a00600621600501000502300600621600501200520a006", + "0x51e900506900600621600520d005193006006216005020005168006006", + "0x14600601700521600501700501a0060920052160050400053a7006006216", + "0x21600514b00514800603c00521600503c00519900603a00521600503a005", + "0x601200609214b03c03a0170120050920052160050920053a600614b005", + "0x502300600621600501200520a00600621600501a005069006006216005", + "0x6900600621600520d00519300600621600501d00520a006006216005010", + "0x9300521600502f0053a70060062160050210051930060062160051e9005", + "0x20a00519900602a00521600502a00514600602800521600502800501a006", + "0x930052160050930053a600620800521600520800514800620a005216005", + "0x500500547f00600500521600500600562d00609320820a02a028012005", + "0x230052160050060050060200052160050060d7006005005005005005216", + "0x600521600500600501a0060062160050060c400600621600500600c006", + "0x1d00501d006125005216005125005199006005005216005005005146006", + "0xe30060261e902520d01021600501d1250050060103c400601d005216005", + "0x1200602800562e20c00521600c0260051070061e90052160051e902000c", + "0xc21600502a20d00c5a700602a00521600520c00514f006006216005006", + "0x514600620a00521600520a00501a00620700521600500620800620820a", + "0x521600501a005026006010005216005010005148006025005216005025", + "0x502600620700521600520700504e00601900521600501900519f00601a", + "0x1a01002520a01a62f006208005216005208005573006012005216005012", + "0x2100521600502102300c15e00613b02102f02d010216005208012207019", + "0x620800600621600500601200614100563013d00521600c13b005619006", + "0x2160051480050cc00614a14814612521600513d005631006031005216005", + "0x517200603903500c21600514600505200600621600514a005051006006", + "0x2d00521600502d00501a006017005216005039005055006006216005035", + "0x3100504e00600c00521600500c00519b00602f00521600502f005146006", + "0x1e00521600501e0050cf00601700521600501700501d006031005216005", + "0x3d00561600603d14b03c03a01021600501e01703100c02f02d01d632006", + "0x1021600503f00522900600621600500601200604000563303f00521600c", + "0x510060062160050440050ca00600621600515000516800615204415014e", + "0x21600504700517200615604700c21600514e005052006006216005152005", + "0x517400604a00521600515e00505700615e005216005156005055006006", + "0x521600503c00514600603a00521600503a00501a00616200521600504a", + "0x51480061e90052160051e900519900614b00521600514b00519b00603c", + "0x211e914b03c03a01d00516200521600516200514a006021005216005021", + "0x503a00501a00604c005216005040005141006006216005006012006162", + "0x614b00521600514b00519b00603c00521600503c00514600603a005216", + "0x504c00514a0060210052160050210051480061e90052160051e9005199", + "0x50ca00600621600500601200604c0211e914b03c03a01d00504c005216", + "0x2d00521600502d00501a00616800521600514100514100600621600501e", + "0x1e900519900600c00521600500c00519b00602f00521600502f005146006", + "0x16800521600516800514a0060210052160050210051480061e9005216005", + "0x21600501e0050ca0060062160050060120061680211e900c02f02d01d005", + "0x50190050cc00600621600501200502300600621600502300502a006006", + "0x501a00604e00521600502800514100600621600501a005023006006216", + "0x521600500c00519b00602500521600502500514600620d00521600520d", + "0x514a0060100052160050100051480061e90052160051e900519900600c", + "0x60062160050060c400604e0101e900c02520d01d00504e00521600504e", + "0x21600500500514600600600521600500600501a00601e005216005006634", + "0x14800612500521600512500519900600c00521600500c00519b006005005", + "0x21600501e00563500601d00521600501d00501d006010005216005010005", + "0x2600601a00521600501a0050cf00601200521600501200502d00601e005", + "0x501901a01201e01d01012500c0050061e9636006019005216005019005", + "0x620c00563802600521600c02500563700602520d0230210201e901d216", + "0x502800516800620a02a028125216005026005639006006216005006012", + "0x563c00620800521600520a00563b00600621600502a00563a006006216", + "0x52160050200051460061e90052160051e900501a006207005216005208", + "0x514800602300521600502300519900602100521600502100519b006020", + "0x20d0230210201e901d00520700521600520700563d00620d00521600520d", + "0x51e900501a00602d00521600520c00563e006006216005006012006207", + "0x602100521600502100519b0060200052160050200051460061e9005216", + "0x502d00563d00620d00521600520d005148006023005216005023005199", + "0xc00601200521600500663f00602d20d0230210201e901d00502d005216", + "0x503900601d0052160050060350060062160050060c4006006216005006", + "0x1e901e00c64001a01900c21600c01d00500612501700601d00521600501d", + "0x62160050060b400602000521600500c005563006006216005006012006", + "0x20d00564202302100c21600c02000564100601900521600501900501a006", + "0x216005021005644006025005216005023005643006006216005006012006", + "0x50060120060066460050061b0006026005216005025005645006010005", + "0x564400602800521600520c00564700620c0052160050060bd006006216", + "0x21600501001200c64800602600521600502800564500601000521600520d", + "0x600621600500601200620a00564a02a00521600c026005649006010005", + "0x521600501900501a00620800521600502a00564b0060062160050060c4", + "0x504e00620800521600520800501d00601a00521600501a005146006019", + "0x5000602f02d20712521600512520801a01901016d006125005216005125", + "0x501000564d00600621600500601200613d00564c13b00521600c02f005", + "0x600621600514600505100614603100c21600513b005170006141005216", + "0x514100540000602d00521600502d00514600620700521600520700501a", + "0x21600503114102d20701056500603100521600503100504e006141005216", + "0x21600500601200601700564e03900521600c03500505000603514a148125", + "0x501a00600621600503c00505100603c03a00c216005039005170006006", + "0x521600503a00504e00603d00521600514a00514600614b005216005148", + "0x521600501700514500600621600500601200600664f0050061b000603f", + "0x514200614a00521600514a00514600614800521600514800501a006040", + "0x1000565000600621600500601200604014a148125005040005216005040", + "0x620700521600520700501a00614e00521600513d005145006006216005", + "0x14e02d20712500514e00521600514e00514200602d00521600502d005146", + "0x600621600520a0050510060062160050060c4006006216005006012006", + "0x21600501a00514600614b00521600501900501a006006216005010005650", + "0xc1110061500052160050060bd00603f00521600512500504e00603d005", + "0x21600514b00501a00615200521600504400511300604400521600515003f", + "0x12500515200521600515200514200603d00521600503d00514600614b005", + "0x12500517200600621600501200565100600621600500601200615203d14b", + "0x605900604700521600500620800600621600500c005403006006216005", + "0x521600515604700c02f00615600521600515600502d006156005216005", + "0x514500616200521600515e04a00c13d00604a00521600500613b00615e", + "0x52160051e900514600601e00521600501e00501a00604c005216005162", + "0x52160050061be00604c1e901e12500504c00521600504c0051420061e9", + "0x190052160050062080060062160050060c400600621600500600c00601a", + "0x510500601e00521600501e00502d00601e01200c216005012005105006", + "0x51e901e00c6520061e90052160051e900502d0061e901d00c21600501d", + "0x600500521600500500514600600600521600500600501a006020005216", + "0x50100052cf00612500521600512500514800600c00521600500c005199", + "0x2000521600502000501d00602100521600502100502600602101000c216", + "0x21600502002112500c00500601d62300601900521600501901a00c0aa006", + "0x601200602a00565302800521600c20c00510700620c02602520d023012", + "0x1a0062080052160050062ef00620a00521600502800514f006006216005", + "0x21600502500519900620d00521600520d005146006023005216005023005", + "0x2d00620800521600520800502d006026005216005026005148006025005", + "0x21600501d00502d00601200521600501200502d00620a00521600520a005", + "0x65400601900521600501900504e00601000521600501000502600601d005", + "0x613d13b02f02d20701221600501901001d01220a20802602520d0231e9", + "0x14100514900600621600500601200603100565514100521600c13d00510c", + "0x621600514a00505100600621600514800520a00614a148146125216005", + "0x20700501a006039005216005035005657006035005216005146005656006", + "0x2f00521600502f00519900602d00521600502d005146006207005216005", + "0x2d20701200503900521600503900565800613b00521600513b005148006", + "0x501a00601700521600503100565900600621600500601200603913b02f", + "0x521600502f00519900602d00521600502d005146006207005216005207", + "0x20701200501700521600501700565800613b00521600513b00514800602f", + "0x502300600621600501900517200600621600500601200601713b02f02d", + "0x65900600621600501200520a00600621600501d00520a006006216005010", + "0x21600520d00514600602300521600502300501a00603a00521600502a005", + "0x65800602600521600502600514800602500521600502500519900620d005", + "0x1a0052160050061be00603a02602520d02301200503a00521600503a005", + "0x60062160050060c400600621600500600c0061e900521600500605b006", + "0xc01d00556700601900521600501901a00c0aa006019005216005006208", + "0x602300521600500620800600621600500601200602100565a020005216", + "0x502500502d00600621600520d00520a00602520d00c2160050120052f1", + "0x2600c21600502302500c21a00602300521600502300504e006025005216", + "0x520a00602a02800c21600502000556900600621600520c00505100620c", + "0x621600520a00520a00620820a00c2160050280052f100600621600502a", + "0x20800c21a00602600521600502600504e00620800521600520800502d006", + "0xc21600520700505200600621600502d00505100602d20700c216005026", + "0x501a00613d00521600513b00505500600621600502f00517200613b02f", + "0x521600500c005199006005005216005005005146006006005216005006", + "0x14101021600513d00c0050060103c400613d00521600513d00501d00600c", + "0x621600500601200603500565b14a00521600c148005107006148146031", + "0x502d00603901e00c21600501e00510500601e00521600514a00514f006", + "0x521600514100501a006017005216005039005622006039005216005039", + "0x5148006146005216005146005199006031005216005031005146006141", + "0x21600503a00502600603a01000c2160050100052cf006125005216005125", + "0x601e00521600501e1e900c17a00601700521600501700501d00603a005", + "0x4000510700604003f03d14b03c01221600501703a12514603114101d623", + "0x521600514e00514f00600621600500601200615000565c14e00521600c", + "0x14b00514600603c00521600503c00501a0061520052160050062ef006044", + "0x3f00521600503f00514800603d00521600503d00519900614b005216005", + "0x1000502600604400521600504400502d00615200521600515200502d006", + "0x1900521600501900504e00601e00521600501e00502d006010005216005", + "0x16204a15e15604701221600501901e01004415203f03d14b03c01e65d006", + "0x517000600621600500601200616800565e04c00521600c162005050006", + "0x521600504700501a00600621600516d00505100616d04e00c21600504c", + "0x514800605100521600515e005199006170005216005156005146006050", + "0x600665f0050061b000617200521600504e00504e00605200521600504a", + "0x521600504700501a006055005216005168005141006006216005006012", + "0x514800615e00521600515e005199006156005216005156005146006047", + "0x5504a15e15604701200505500521600505500514a00604a00521600504a", + "0x621600501e00520a006006216005019005172006006216005006012006", + "0x503c00501a006057005216005150005141006006216005010005023006", + "0x603d00521600503d00519900614b00521600514b00514600603c005216", + "0x3d14b03c01200505700521600505700514a00603f00521600503f005148", + "0x501000502300600621600501900517200600621600500601200605703f", + "0x501a0061740052160050350051410060062160051e9005069006006216", + "0x5216005146005199006031005216005031005146006141005216005141", + "0x14101200517400521600517400514a006125005216005125005148006146", + "0x5069006006216005021005051006006216005006012006174125146031", + "0x521600505900502d00605901200c2160050120051050060062160051e9", + "0x514600600600521600500600501a006178005216005059005622006059", + "0x521600512500514800600c00521600500c005199006005005216005005", + "0x1d00605b00521600505b00502600605b01000c2160050100052cf006125", + "0x5d17a01221600517805b12500c00500601d623006178005216005178005", + "0x621600500601200618600566018500521600c06100510700606118117f", + "0x517a00501a0060670052160050062ef00606500521600518500514f006", + "0x617f00521600517f00519900605d00521600505d00514600617a005216", + "0x506500502d00606700521600506700502d006181005216005181005148", + "0x601000521600501000502600601900521600501900504e006065005216", + "0x501201001906506718117f05d17a01e66100601200521600501200502d", + "0x120060700056620ba00521600c18d00510c00618d06d18a06b069012216", + "0x21600507200520a00619a0721961252160050ba005149006006216005006", + "0x6b00514600605000521600506900501a00600621600519a005051006006", + "0x5200521600506d00514800605100521600518a005199006170005216005", + "0x517200607619d00c21600517200505200617200521600519600504e006", + "0x1a10052160051a00050570061a000521600507600505500600621600519d", + "0x17000514600605000521600505000501a0061a20052160051a1005174006", + "0x52005216005052005148006051005216005051005199006170005216005", + "0x2160050060120061a20520511700500120051a20052160051a200514a006", + "0x514600606900521600506900501a00607b005216005070005141006006", + "0x521600506d00514800618a00521600518a00519900606b00521600506b", + "0x500601200607b06d18a06b06901200507b00521600507b00514a00606d", + "0x1900517200600621600501000502300600621600501200520a006006216", + "0x617a00521600517a00501a0061a4005216005186005141006006216005", + "0x518100514800617f00521600517f00519900605d00521600505d005146", + "0x44b0061a418117f05d17a0120051a40052160051a400514a006181005216", + "0x66301a01901d12521600c01212500c00501044c006012005216005010005", + "0x2d00600600521600500600501a0060062160050060120060201e901e125", + "0x1d00514600602302100c21600501a00600c66400601a00521600501a005", + "0x20d00521600c02300518a00601900521600501900514800601d005216005", + "0x566600602600521600520d00540e006006216005006012006025005665", + "0x521600502800566800602800521600520c00566700620c005216005026", + "0x514800601d00521600501d00514600602100521600502100501a00602a", + "0x602a01901d02101000502a00521600502a005669006019005216005019", + "0x620a005216005006208006006216005025005051006006216005006012", + "0x520820a00c02f00620800521600520800502d00620800521600500666a", + "0x602f00521600520702d00c13d00602d00521600500613b006207005216", + "0x501d00514600602100521600502100501a00613b00521600502f00566b", + "0x513b00521600513b00566900601900521600501900514800601d005216", + "0x613d00521600502000566c00600621600500601200613b01901d021010", + "0x500600501a00603100521600514100566800614100521600513d005667", + "0x61e90052160051e900514800601e00521600501e005146006006005216", + "0x521600c0060052320060311e901e006010005031005216005031005669", + "0x57c00612500521600500500557b00600621600500601200600c00566d005", + "0x601200601000500501000521600501000557d006010005216005125005", + "0x601d00521600500c01200c13d00601200521600500613b006006216005", + "0x41300601900500501900521600501900557d00601900521600501d00557e", + "0x21600512500544b00601d00521600501200536a006012005216005010005", + "0x210201e912566e01e01a00c21600c01d01900c005006012474006019005", + "0x521600502300539e0060230052160050060bd006006216005006012006", + "0x539f00601e00521600501e00514800601a00521600501a00514600620d", + "0x210053a100600621600500601200620d01e01a12500520d00521600520d", + "0x200052160050200051480061e90052160051e9005146006025005216005", + "0x521600500600566f0060250201e912500502500521600502500539f006", + "0xc00521600c00600552700600500500500500521600500500547f006005", + "0xc0053a400600621600500500520a006006216005006012006125005670", + "0x120052160050120053a60060120052160050100053a5006010005216005", + "0x5006208006006216005125005172006006216005006012006012005005", + "0x601a00521600500613b00601900521600500501d00c02f00601d005216", + "0x1e90053a60061e900521600501e0053a700601e00521600501901a00c13d", + "0x500500547f0060050052160050060056710061e90050051e9005216005", + "0x21600500500547f006005005216005006005672006005005005005005216", + "0x500601200600c00567400500521600c006005673006005005005005005", + "0x5b40060100052160051250055b30061250052160050050055b2006006216", + "0x21600500613b006006216005006012006010005005010005216005010005", + "0x601900521600501d0055b500601d00521600500c01200c13d006012005", + "0x612500600c2160050060056750060190050050190052160050190055b4", + "0x501000518d00600621600501200506d00601201000c216005125005676", + "0x1d00c21600500c01000c1b500600c00521600500c00504e006010005216", + "0x506d00601e01a00c216005006005676006006216005019005051006019", + "0x1d00521600501d00504e00601e00521600501e00518d00600621600501a", + "0x60bd0060062160050200050510060201e900c21600501d01e00c1b5006", + "0x1e90052160051e900504e00600500521600500500504e006021005216005", + "0x21600512500567800612500600c2160050060056770060211e9005125005", + "0x2d00600621600501d00506d0060062160050120051ab00601d012010125", + "0x500c01000c21a00600c00521600500c00504e006010005216005010005", + "0x1e00600c21600500600567700600621600501a00505100601a01900c216", + "0x506d0060062160051e900520a0060210201e912521600501e005678006", + "0x1900521600501900504e00602000521600502000508c006006216005021", + "0x567800600621600520d00505100620d02300c21600501902000c092006", + "0x2160050260051ab00600621600502500520a00620c026025125216005006", + "0xc1b500602300521600502300504e00620c00521600520c00518d006006", + "0x52160050060bd00600621600502a00505100602a02800c21600502320c", + "0x512500502800521600502800504e00600500521600500500504e00620a", + "0x1201000c21600512500567a00612500600c21600500600567900620a028", + "0x500c00504e00601000521600501000508c00600621600501200506d006", + "0x621600501900505100601901d00c21600500c01000c09200600c005216", + "0x1e00518d00600621600501a0051ab00601e01a00c21600500600567a006", + "0xc21600501d01e00c1b500601d00521600501d00504e00601e005216005", + "0x500504e0060210052160050060bd0060062160050200050510060201e9", + "0x567b0060211e90051250051e90052160051e900504e006005005216005", + "0x521600500c00504e00612500521600512500508c006125005216005006", + "0xbd00600621600501200505100601201000c21600500c12500c09200600c", + "0x521600501000504e00600500521600500500504e00601d005216005006", + "0xc00c21600500c00567c0060062160050060c400601d010005125005010", + "0x502d00600621600501900516800601901d00c21600501200567d006012", + "0x21600501001d00c21a00601000521600501000504e00601d00521600501d", + "0x60201e900c21600500c00567d00600621600501e00505100601e01a00c", + "0x21600500500514600600600521600500600501a0060062160051e900520a", + "0x16d00601a00521600501a00504e00602000521600502000501d006005005", + "0x67e02500521600c20d00505000620d02302112521600501a020005006010", + "0x505100602820c00c216005025005170006006216005006012006026005", + "0x521600502a20c1251255dc00602a0052160050060bd006006216005028", + "0x514600602100521600502100501a00620800521600520a00522b00620a", + "0x120062080230211250052080052160052080055cd006023005216005023", + "0x62070052160050260055cc006006216005125005172006006216005006", + "0x52070055cd00602300521600502300514600602100521600502100501a", + "0x568000612500600c21600500600567f006207023021125005207005216", + "0x21600501d0051ab0060062160050120051ab00601d012010125216005125", + "0xc21a00600c00521600500c00504e00601000521600501000502d006006", + "0x21600500600567f00600621600501a00505100601a01900c21600500c010", + "0x62160051e900520a0060210201e912521600501e00568000601e00600c", + "0x501900504e00602000521600502000508c0060062160050210051ab006", + "0x621600520d00505100620d02300c21600501902000c092006019005216", + "0x51ab00600621600502500520a00620c026025125216005006005680006", + "0x2300521600502300504e00620c00521600520c00508c006006216005026", + "0x60bd00600621600502a00505100602a02800c21600502320c00c092006", + "0x2800521600502800504e00600500521600500500504e00620a005216005", + "0x1200c00c21600500c0056810060062160050060c400620a028005125005", + "0xcc00600621600501900516800601e01a01901d010216005012005682006", + "0x1d00521600501d00502d00600621600501e00516800600621600501a005", + "0x510060201e900c21600501001d00c21a00601000521600501000504e006", + "0x21600502100568200602100c00c21600500c005681006006216005020005", + "0x60062160050250050cc00600621600502300520a00602602520d023010", + "0x21600500500514600600600521600500600501a006006216005026005168", + "0x16d0061e90052160051e900504e00620d00521600520d00501d006005005", + "0x68320a00521600c02a00505000602a02820c1252160051e920d005006010", + "0x568200620700c00c21600500c005681006006216005006012006208005", + "0x502f00516800600621600502d00520a00613d13b02f02d010216005207", + "0x568500614100521600513b00568400600621600513d005168006006216", + "0x21600514800505100614814600c21600520a005170006031005216005141", + "0x1703903501021600500c00568200614a00521600503114600c02f006006", + "0x50170050cc00600621600503900516800600621600503500520a00603a", + "0x1d00602800521600502800514600620c00521600520c00501a006006216", + "0x3a02820c01016d00614a00521600514a00504e00603a00521600503a005", + "0x1200604000568603f00521600c03d00505000603d14b03c12521600514a", + "0x621600515000505100615014e00c21600503f005170006006216005006", + "0x522b00615200521600504414e1251255dc0060440052160050060bd006", + "0x521600514b00514600603c00521600503c00501a006047005216005152", + "0x621600500601200604714b03c1250050470052160050470055cd00614b", + "0x503c00501a0061560052160050400055cc006006216005125005172006", + "0x51560052160051560055cd00614b00521600514b00514600603c005216", + "0x568700600621600512500517200600621600500601200615614b03c125", + "0x20c00521600520c00501a00615e0052160052080055cc00600621600500c", + "0x2820c12500515e00521600515e0055cd006028005216005028005146006", + "0x1200568900601200c00c21600500c0056880060062160050060c400615e", + "0x1d00521600501d00502d00600621600501900516800601901d00c216005", + "0x5100601e01a00c21600501001d00c21a00601000521600501000504e006", + "0x2160051e900520a0060201e900c21600500c00568900600621600501e005", + "0x501d00600500521600500500514600600600521600500600501a006006", + "0x1a02000500601016d00601a00521600501a00504e006020005216005020", + "0x601200602600568a02500521600c20d00505000620d023021125216005", + "0x600621600502800505100602820c00c216005025005170006006216005", + "0x20a00522b00620a00521600502a20c1251255dc00602a0052160050060bd", + "0x2300521600502300514600602100521600502100501a006208005216005", + "0x60062160050060120062080230211250052080052160052080055cd006", + "0x21600502100501a0062070052160050260055cc006006216005125005172", + "0x1250052070052160052070055cd006023005216005023005146006021005", + "0x1012521600512500568c00612500600c21600500600568b006207023021", + "0x1000502d00600621600501d00519a00600621600501200506d00601d012", + "0xc21600500c01000c21a00600c00521600500c00504e006010005216005", + "0x68c00601e00600c21600500600568b00600621600501a00505100601a019", + "0x502100519a0060062160051e900520a0060210201e912521600501e005", + "0x1b500601900521600501900504e00602000521600502000518d006006216", + "0x500600568c00600621600520d00505100620d02300c21600501902000c", + "0x600621600502600506d00600621600502500520a00620c026025125216", + "0x2320c00c07600602300521600502300504e00620c00521600520c00519d", + "0x620a0052160050060bd00600621600502a00505100602a02800c216005", + "0x20a02800512500502800521600502800504e00600500521600500500504e", + "0x601d01201012521600512500568e00612500600c21600500600568d006", + "0x521600501000518d00600621600501d00519a00600621600501200520a", + "0x601a01900c21600500c01000c1b500600c00521600500c00504e006010", + "0x501e00568e00601e00600c21600500600568d00600621600501a005051", + "0x600621600502100519a0060062160051e900506d0060210201e9125216", + "0x1902000c21a00601900521600501900504e00602000521600502000502d", + "0x2512521600500600568e00600621600520d00505100620d02300c216005", + "0x20c00519d00600621600502600520a00600621600502500506d00620c026", + "0xc21600502320c00c07600602300521600502300504e00620c005216005", + "0x500504e00620a0052160050060bd00600621600502a00505100602a028", + "0x568f00620a02800512500502800521600502800504e006005005216005", + "0x501200506d00601201000c21600512500569000612500600c216005006", + "0x1b500600c00521600500c00504e00601000521600501000518d006006216", + "0x500600569000600621600501900505100601901d00c21600500c01000c", + "0x601e00521600501e00518d00600621600501a00506d00601e01a00c216", + "0x50510060201e900c21600501d01e00c1b500601d00521600501d00504e", + "0x600500521600500500504e0060210052160050060bd006006216005020", + "0x1470060062160050060c40060211e90051250051e90052160051e900504e", + "0x501900502000601900521600501d0051e900601d01000c216005010005", + "0x1e900521600501e00554700601e01200c21600501200522200601a005216", + "0x502300602302100c21600501a0050210060200052160051e9005548006", + "0x621600520d00502300602520d00c216005020005021006006216005021", + "0x2600502600620c005216005025005025006026005216005023005025006", + "0x621600c20c02600c20c00620c00521600520c005026006026005216005", + "0x51250051720060062160050120050ca006006216005006012006006691", + "0x5006692006028005216005006208006006216005010005168006006216", + "0x20a00521600502a02800c02f00602a00521600502a00502d00602a005216", + "0x20700569300620700521600520a20800c13d00620800521600500613b006", + "0x500521600500500514600600600521600500600501a00602d005216005", + "0x500601000502d00521600502d00569400600c00521600500c00519b006", + "0x2160050063d800602f0052160050062ef00600621600500601200602d00c", + "0x19b00600500521600500500514600600600521600500600501a00613b005", + "0x21600512500504e00601000521600501000501d00600c00521600500c005", + "0x19f00602f00521600502f00502d0060120052160050120050cf006125005", + "0x1021600513b02f01212501000c00500601a69500613b00521600513b005", + "0x21600500601200614a00569714800521600c14600569600614603114113d", + "0x21600503a0050cc00614b03c03a01703903501d216005148005698006006", + "0x60bd00603d00521600501703c00c02f00600621600514b005051006006", + "0x504000569a00604000521600503f03903503d01069900603f005216005", + "0x614100521600514100514600613d00521600513d00501a00614e005216", + "0x3114113d01000514e00521600514e00569400603100521600503100519b", + "0x513d00501a00615000521600514a00569300600621600500601200614e", + "0x603100521600503100519b00614100521600514100514600613d005216", + "0x60062160050060c400615003114113d010005150005216005150005694", + "0x19005006125017006019005216005019005039006019005216005006035", + "0x2160050060b40060062160050060120060201e900c69b01e01a00c21600c", + "0x569d02302100c21600c12500569c00601a00521600501a00501a006006", + "0x50250051640060250052160050230050bf00600621600500601200620d", + "0x60280052160050260050e900620c00521600502100504e006026005216", + "0xfa00602a0052160050060bd00600621600500601200600669e0050061b0", + "0x21600520a0050e900620c00521600520d00504e00620a00521600502a005", + "0x600621600500601200620700569f20800521600c02800501e006028005", + "0xc6a100602f01d00c21600501d0053c600602d01200c2160050120056a0", + "0x513b0054dc00613d01000c2160050100052cf00613b00521600502f02d", + "0x1481461256a203114100c21600c20813b13d00c01e01247400613b005216", + "0x503100514800603500521600514100514600600621600500601200614a", + "0x514a0051720060062160050060120060066a30050061b0006039005216", + "0x6a4006039005216005148005148006035005216005146005146006006216", + "0x521600501d00519f00601a00521600501a00501a006017005216005006", + "0x3c03a00c21600501701d01a1256a500601700521600501700519f00601d", + "0x60c400600621600500601200603d0056a714b00521600c03c0056a6006", + "0x603a00521600503a00501a00603f00521600514b005234006006216005", + "0x520c00504e006039005216005039005148006035005216005035005146", + "0x601200521600501200557300601000521600501000502600620c005216", + "0x1021600503f01201020c03903503a01961800603f00521600503f00519f", + "0x2160050060120060470056a815200521600c04400561900604415014e040", + "0x521600504a15e1561256a900604a15e156125216005152005631006006", + "0x514600604000521600504000501a00604c0052160051620056aa006162", + "0x521600504c0056ab00615000521600515000514800614e00521600514e", + "0x52160050470056ac00600621600500601200604c15014e04001000504c", + "0x514800614e00521600514e00514600604000521600504000501a006168", + "0x616815014e0400100051680052160051680056ab006150005216005150", + "0x2300600621600501200561c0060062160050060c4006006216005006012", + "0x4e00521600503d0056ac00600621600520c005172006006216005010005", + "0x3900514800603500521600503500514600603a00521600503a00501a006", + "0x1200604e03903503a01000504e00521600504e0056ab006039005216005", + "0x561c0060062160052070050510060062160050060c4006006216005006", + "0x6a900616d0052160050060bd006006216005010005023006006216005012", + "0x1a00501a0061700052160050500056aa00605000521600516d01d20c125", + "0xc00521600500c00514800601e00521600501e00514600601a005216005", + "0x621600500601200617000c01e01a0100051700052160051700056ab006", + "0x21600501000502300600621600501200561c006006216005125005172006", + "0x21600500605900605100521600500620800600621600501d0050cc006006", + "0x617200521600505205100c02f00605200521600505200502d006052005", + "0x50570056ac00605700521600517205500c13d00605500521600500613b", + "0x60200052160050200051460061e90052160051e900501a006174005216", + "0xc0201e90100051740052160051740056ab00600c00521600500c005148", + "0x501d00502d00601200521600501200502d0060062160050060c4006174", + "0x600521600500600501a00601900521600501d01200c62500601d005216", + "0x12500514800600c00521600500c005199006005005216005005005146006", + "0x1900521600501900501d006010005216005010005026006125005216005", + "0x51070060210201e901e01a01221600501901012500c00500601d623006", + "0x21600502300514f00600621600500601200620d0056ad02300521600c021", + "0x2ef00600621600502600520a00620c02600c2160050250052f1006025005", + "0x21600502a00520a00620a02a00c2160050280052f1006028005216005006", + "0x20a00602d20700c2160052080052f100620800521600520c0050c1006006", + "0xc21600502f0052f100602f00521600520a0050c1006006216005207005", + "0x50c100614100521600502d0050c100600621600513b00520a00613d13b", + "0x62160050060b400614600521600503114100c33e00603100521600513d", + "0x120061480056ae00621600c14600533f00614600521600514600502d006", + "0x603500521600514a0052f900614a0052160050060bd006006216005006", + "0x60062160050060120060066af0050061b000603900521600503500519d", + "0x52160050170053090060170052160050060bd006006216005148005343", + "0x50390054220060062160050060c400603900521600503a00519d00603a", + "0x603d00521600514b0052ea00614b00521600503c00517c00603c005216", + "0x51e900519900601e00521600501e00514600601a00521600501a00501a", + "0x503d00521600503d0052eb0060200052160050200051480061e9005216", + "0x3f00521600520d0052ec00600621600500601200603d0201e901e01a012", + "0x1e900519900601e00521600501e00514600601a00521600501a00501a006", + "0x3f00521600503f0052eb0060200052160050200051480061e9005216005", + "0x52160050066b000600500521600500620800603f0201e901e01a012005", + "0x2f00612500521600500c00500c02f00600c00521600500c00502d00600c", + "0x1200517200601d01200c21600501000505200601000521600500612500c", + "0x501900521600501900501d00601900521600501d005055006006216005", + "0x500514600600600521600500600501a0060062160050060c4006019005", + "0x1200521600501200501d00600c00521600500c005199006005005216005", + "0x21600c01e00510700601e01a01901d01021600501200c0050060103c4006", + "0x60210052160051e900514f0060062160050060120060200056b11e9005", + "0x60b400602500521600520d00544b00620d02300c21600502101d00c5a7", + "0x21600c02501012501901044c00602300521600502300501a006006216005", + "0x502800544e00600621600500601200620820a02a1256b202820c026125", + "0x602f00521600520c00514800602d005216005026005146006207005216", + "0x60062160050060120060066b30050061b000613b00521600520700544f", + "0x520a00514800602d00521600502a00514600613d005216005208005451", + "0x614100521600513b00545200613b00521600513d00544f00602f005216", + "0x50060c40060062160050060120061460056b403100521600c141005107", + "0x45500614a00521600514800545400614800521600503100514f006006216", + "0x21600502d00514600602300521600502300501a00603500521600514a005", + "0x45600602f00521600502f00514800601a00521600501a00519900602d005", + "0x600621600500601200603502f01a02d023012005035005216005035005", + "0x521600502300501a0060390052160051460054570060062160050060c4", + "0x514800601a00521600501a00519900602d00521600502d005146006023", + "0x3902f01a02d02301200503900521600503900545600602f00521600502f", + "0x5216005020005457006006216005010005023006006216005006012006", + "0x519900601900521600501900514600601d00521600501d00501a006017", + "0x521600501700545600612500521600512500514800601a00521600501a", + "0x2160050066b500600c00521600500620800601712501a01901d012005017", + "0x601000521600512500c00c02f00612500521600512500502d006125005", + "0x505200601d00521600500501200c02f00601200521600500601000c02f", + "0x521600501a00505500600621600501900517200601a01900c21600501d", + "0x1a0060062160050060c400601e00500501e00521600501e00501d00601e", + "0x21600500c005199006005005216005005005146006006005216005006005", + "0x1021600501200c0050060103c400601200521600501200501d00600c005", + "0x2160050060120060210056b602000521600c1e90051070061e901e01a019", + "0x602520d00c21600502301900c5a700602300521600502000514f006006", + "0x521600520d00501a0060062160050060b400602600521600502500544b", + "0x620820a02a1256b702820c00c21600c01d02601012501a01247400620d", + "0x521600502800514800620700521600520c005146006006216005006012", + "0x62160052080051720060062160050060120060066b80050061b000602d", + "0x50060c400602d00521600520a00514800620700521600502a005146006", + "0x53a500613b00521600502f0053a400602f0052160050060bd006006216", + "0x521600520700514600620d00521600520d00501a00613d00521600513b", + "0x53a600602d00521600502d00514800601e00521600501e005199006207", + "0x20a00600621600500601200613d02d01e20720d01200513d00521600513d", + "0x1410052160050210053a700600621600501000502300600621600501d005", + "0x1e00519900601a00521600501a00514600601900521600501900501a006", + "0x1410052160051410053a600612500521600512500514800601e005216005", + "0x52160050066b900600c00521600500620800614112501e01a019012005", + "0x2f00601000521600512500c00c02f00612500521600512500502d006125", + "0x1d00505200601d00521600500501200c02f00601200521600500601000c", + "0x1e00521600501a00505500600621600501900517200601a01900c216005", + "0x60350060062160050060c400601e00500501e00521600501e00501d006", + "0x21600c01a00500612501700601a00521600501a00503900601a005216005", + "0xc2160050100053c600600621600500601200602102000c6ba1e901e00c", + "0x602602500c21600512500502100620d005216005023005233006023010", + "0x502600502500600621600520c00502300602820c00c21600520d005021", + "0x601e00521600501e00501a00620a00521600502800502500602a005216", + "0x50190056a00060062160050060120060066bb00621600c20a02a00c20c", + "0x21600520720800c6a100620701000c2160050100053c600620801900c216", + "0x54dc00602f01d00c21600501d0052cf0060062160050060b400602d005", + "0x1256bc14113d13b12521600c02d02f00c1e901044c00602d00521600502d", + "0x514600614a00521600514100544e006006216005006012006148146031", + "0x521600514a00544f00603900521600513d00514800603500521600513b", + "0x52160051480054510060062160050060120060066bd0050061b0006017", + "0x544f00603900521600514600514800603500521600503100514600603a", + "0x521600c03c00510700603c00521600501700545200601700521600503a", + "0x14b00514f0060062160050060c400600621600500601200603d0056be14b", + "0x14e0052160050066a400604000521600503f01200c02f00603f005216005", + "0x14e00519f00601000521600501000519f00601e00521600501e00501a006", + "0x504000504e00604415000c21600514e01001e1256a500614e005216005", + "0x62160050060120060470056bf15200521600c0440056a6006040005216", + "0x3500514600615000521600515000501a006156005216005152005234006", + "0x25005216005025005026006039005216005039005148006035005216005", + "0x1d00502600604000521600504000504e00615600521600515600519f006", + "0x15602503903515001a62f00601900521600501900557300601d005216005", + "0x56c016800521600c04c00561900604c16204a15e01021600501901d040", + "0x1256a900617005016d12521600516800563100600621600500601200604e", + "0x515e00501a0060520052160050510056aa00605100521600517005016d", + "0x616200521600516200514800604a00521600504a00514600615e005216", + "0x600621600500601200605216204a15e0100050520052160050520056ab", + "0x504a00514600615e00521600515e00501a00617200521600504e0056ac", + "0x51720052160051720056ab00616200521600516200514800604a005216", + "0x2300600621600501900561c00600621600500601200617216204a15e010", + "0x600621600502500502300600621600504000517200600621600501d005", + "0x503500514600615000521600515000501a0060550052160050470056ac", + "0x50550052160050550056ab006039005216005039005148006035005216", + "0x561c0060062160050060c4006006216005006012006055039035150010", + "0x230060062160050100050cc00600621600501d005023006006216005019", + "0x5700521600503d0056ac006006216005012005172006006216005025005", + "0x3900514800603500521600503500514600601e00521600501e00501a006", + "0x1200605703903501e0100050570052160050570056ab006039005216005", + "0x2300600621600501d00502300600621600501900561c006006216005006", + "0x2160051740100121256a90061740052160050060bd006006216005025005", + "0x14600601e00521600501e00501a0061780052160050590056aa006059005", + "0x2160051780056ab00600c00521600500c0051480061e90052160051e9005", + "0x21600501900561c00600621600500601200617800c1e901e010005178005", + "0x50120051720060062160050100050cc00600621600501d005023006006", + "0x500605900605b005216005006208006006216005125005023006006216", + "0x5d00521600517a05b00c02f00617a00521600517a00502d00617a005216", + "0x1810056ac00618100521600505d17f00c13d00617f00521600500613b006", + "0x2100521600502100514600602000521600502000501a006061005216005", + "0x210200100050610052160050610056ab00600c00521600500c005148006", + "0x2160050066c100601d0052160050062ef0060062160050060c400606100c", + "0x19b00600500521600500500514600600600521600500600501a006019005", + "0x21600512500504e0060120052160050120050cf00600c00521600500c005", + "0x19f00601d00521600501d00502d00601000521600501000501d006125005", + "0x1021600501901d01012501200c00500601a6c2006019005216005019005", + "0x2160050060120060230056c402100521600c0200056c30060201e901e01a", + "0x21600502600520a00602a02820c02602520d01d2160050210056c5006006", + "0x620a00521600502a20d02502801069900600621600520c0050cc006006", + "0x501e00514600601a00521600501a00501a00620800521600520a00569a", + "0x52080052160052080056940061e90052160051e900519b00601e005216", + "0x62070052160050230056930060062160050060120062081e901e01a010", + "0x51e900519b00601e00521600501e00514600601a00521600501a00501a", + "0x60b20062071e901e01a0100052070052160052070056940061e9005216", + "0x50060350060062160050060c400600621600500600c006020005216005", + "0xc21600c021005006125017006021005216005021005039006021005216", + "0x20c0052160050120051e900600621600500601200602602500c6c620d023", + "0x21600c20c0051b600602300521600502300501a0060062160050060b4006", + "0x20800521600502a0050b800600621600500601200620a0056c702a02800c", + "0x50061b000602d0052160052080051b20062070052160050280051b4006", + "0x502f0051ac00602f0052160050060bd0060062160050060120060066c8", + "0x602d00521600513b0051b200620700521600520a0051b400613b005216", + "0x2d0051ae0061e90052160051e902000c0b60061e9005216005207005055", + "0x60062160050060c40060062160050060120061410056c913d00521600c", + "0x521600500653e00614600521600500620800603100521600513d0050bf", + "0x10500614a00521600514814600c02f00614800521600514800502d006148", + "0x310050c100603900521600503514a00c02f00603501900c216005019005", + "0x521600501703900c02f00601700521600501700502d006017005216005", + "0x517200603d14b00c21600503a00505200603c00521600500620d00603a", + "0x60400052160050063d800603f00521600503d00505500600621600514b", + "0x500c00519b00620d00521600520d00514600602300521600502300501a", + "0x601000521600501000514800612500521600512500519900600c005216", + "0x504000519f00603f00521600503f00501d00603c00521600503c005026", + "0x14e00521600514e00502600614e01e00c21600501e0052cf006040005216", + "0x1e95570061500052160051500050cf00615001a00c21600501a005222006", + "0x604a15e15604715204401d21600515014e04003f03c01012500c20d023", + "0x16200516200600621600500601200604c0056ca16200521600c04a00504a", + "0x521600504400501a00604e00521600516801d00c6cb006168005216005", + "0x519900604700521600504700519b006152005216005152005146006044", + "0x52160051e900501d00615e00521600515e005148006156005216005156", + "0x50cf00601900521600501900502d00604e00521600504e0056350061e9", + "0x1560471520441e963600601e00521600501e00502600601a00521600501a", + "0xc17200563700617205205117005016d01d21600501e01a01904e1e915e", + "0x1741252160050550056390060062160050060120060570056cc055005216", + "0x17a00521600505b0056ce00605b0052160051780591741256cd006178059", + "0x17000519b00605000521600505000514600616d00521600516d00501a006", + "0x52005216005052005148006051005216005051005199006170005216005", + "0x500601200617a05205117005016d01d00517a00521600517a0056cf006", + "0x14600616d00521600516d00501a00605d0052160050570056d0006006216", + "0x21600505100519900617000521600517000519b006050005216005050005", + "0x1d00505d00521600505d0056cf006052005216005052005148006051005", + "0x600621600501e00502300600621600500601200605d05205117005016d", + "0x62160051e900516800600621600501900520a00600621600501a0050ca", + "0x504400501a00617f00521600504c0056d000600621600501d00563a006", + "0x604700521600504700519b006152005216005152005146006044005216", + "0x517f0056cf00615e00521600515e005148006156005216005156005199", + "0x60c400600621600500601200617f15e15604715204401d00517f005216", + "0x50ca00600621600501e005023006006216005141005051006006216005", + "0x6118100c21600501d0056d100600621600501900520a00600621600501a", + "0x6ce0061860052160051851811e91256cd00618500521600506100564d006", + "0x21600520d00514600602300521600502300501a006065005216005186005", + "0x14800612500521600512500519900600c00521600500c00519b00620d005", + "0x12500c20d02301d0050650052160050650056cf006010005216005010005", + "0x501a0050ca00600621600501e005023006006216005006012006065010", + "0x2000519300600621600501d00563a00600621600501900520a006006216", + "0x6059006067005216005006208006006216005012005168006006216005", + "0x521600506906700c02f00606900521600506900502d006069005216005", + "0x56d000606d00521600506b18a00c13d00618a00521600500613b00606b", + "0x521600502600514600602500521600502500501a00618d00521600506d", + "0x514800612500521600512500519900600c00521600500c00519b006026", + "0x1012500c02602501d00518d00521600518d0056cf006010005216005010", + "0x512500502d0061250052160050066d200600c00521600500620800618d", + "0x521600500601000c02f00601000521600512500c00c02f006125005216", + "0x601a01900c21600501d00505200601d00521600500501200c02f006012", + "0x21600501e00501d00601e00521600501a005055006006216005019005172", + "0x390061e90052160050060350060062160050060c400601e00500501e005", + "0x2300c6d302102000c21600c1e90050061250170061e90052160051e9005", + "0x1200510500602501000c21600501000510500600621600500601200620d", + "0x21600520c00502d00620c00521600502602500c33e00602601200c216005", + "0x280056d400621600c20c00533f00602000521600502000501a00620c005", + "0x621600501900520a00600621600501a005023006006216005006012006", + "0x52160050060bd00600621600501200520a00600621600501d00520a006", + "0x620800521600520a00545b00620a00521600502a01001e12545a00602a", + "0x500c00519900602100521600502100514600602000521600502000501a", + "0x520800521600520800545c00612500521600512500514800600c005216", + "0x600621600502800534300600621600500601200620812500c021020012", + "0x1900510500620700521600520700502d00620701d00c21600501d005105", + "0xc21600501000510500602d00521600502d00502d00602d01900c216005", + "0x13b00521600502f02d2071256d500602f00521600502f00502d00602f010", + "0xc00519900602100521600502100514600602000521600502000501a006", + "0x1a00c21600501a0052cf00612500521600512500514800600c005216005", + "0x1d62300613b00521600513b00501d00613d00521600513d00502600613d", + "0x21600c14a00510700614a14814603114101221600513b13d12500c021020", + "0x601700521600503500514f0060062160050060120060390056d6035005", + "0x3c01000c14d00603c00521600500610900603a00521600501701e00c02f", + "0x3100521600503100514600614100521600514100501a00614b005216005", + "0x14b00502d006148005216005148005148006146005216005146005199006", + "0x1d00521600501d00502d00601200521600501200502d00614b005216005", + "0x3a00504e00601a00521600501a00502600601900521600501900502d006", + "0x1221600503a01a01901d01214b1481460311411e965400603a005216005", + "0x50060120061520056d704400521600c15000510c00615014e04003f03d", + "0x21600515e15604712545a00615e156047125216005044005149006006216", + "0x14600603d00521600503d00501a00616200521600504a00545b00604a005", + "0x21600514e00514800604000521600504000519900603f00521600503f005", + "0x601200616214e04003f03d01200516200521600516200545c00614e005", + "0x603d00521600503d00501a00604c00521600515200545f006006216005", + "0x514e00514800604000521600504000519900603f00521600503f005146", + "0x1200604c14e04003f03d01200504c00521600504c00545c00614e005216", + "0x20a00600621600501a00502300600621600501000520a006006216005006", + "0x600621600501200520a00600621600501d00520a006006216005019005", + "0x21600514100501a00616800521600503900545f00600621600501e005172", + "0x148006146005216005146005199006031005216005031005146006141005", + "0x14814603114101200516800521600516800545c006148005216005148005", + "0x21600501d00520a00600621600501200520a006006216005006012006168", + "0x501a00502300600621600501000520a00600621600501e005172006006", + "0x500605900604e00521600500620800600621600501900520a006006216", + "0x5000521600516d04e00c02f00616d00521600516d00502d00616d005216", + "0x5100545f00605100521600505017000c13d00617000521600500613b006", + "0x20d00521600520d00514600602300521600502300501a006052005216005", + "0x5200545c00612500521600512500514800600c00521600500c005199006", + "0x60350060062160050060c400605212500c20d023012005052005216005", + "0x21600c01e00500612501700601e00521600501e00503900601e005216005", + "0xc21600501000510500600621600500601200602302100c6d80201e900c", + "0x2600521600502520d00c33e00602501200c21600501200510500620d010", + "0x2600533f0061e90052160051e900501a00602600521600502600502d006", + "0x600621600501900520a00600621600500601200620c0056d900621600c", + "0x621600501000520a00600621600501200520a00600621600501d005023", + "0x2a00511300602a00521600502801a00c1110060280052160050060bd006", + "0x200052160050200051460061e90052160051e900501a00620a005216005", + "0x20a00514200612500521600512500514800600c00521600500c005199006", + "0x534300600621600500601200620a12500c0201e901200520a005216005", + "0x521600520800502d00620801900c21600501900510500600621600520c", + "0x62a00620700521600520700502d00620701000c216005010005105006208", + "0x50200051460061e90052160051e900501a00602d00521600520720800c", + "0x612500521600512500514800600c00521600500c005199006020005216", + "0x2d00501d00602f00521600502f00502600602f01d00c21600501d0052cf", + "0x3114113d13b01221600502d02f12500c0201e901d62300602d005216005", + "0x14f00600621600500601200614a0056da14800521600c146005107006146", + "0x513b00501a00603900521600503501a00c02f006035005216005148005", + "0x614100521600514100519900613d00521600513d00514600613b005216", + "0x501200502d00601000521600501000502d006031005216005031005148", + "0x601900521600501900502d00601d00521600501d005026006012005216", + "0x503901901d01201003114113d13b01e65d00603900521600503900504e", + "0x120060400056db03f00521600c03d00505000603d14b03c03a017012216", + "0x21600515014e00c11100615014e00c21600503f005170006006216005006", + "0x14600601700521600501700501a006152005216005044005113006044005", + "0x21600514b00514800603c00521600503c00519900603a00521600503a005", + "0x601200615214b03c03a01701200515200521600515200514200614b005", + "0x601700521600501700501a006047005216005040005145006006216005", + "0x514b00514800603c00521600503c00519900603a00521600503a005146", + "0x1200604714b03c03a01701200504700521600504700514200614b005216", + "0x20a00600621600501d00502300600621600501900520a006006216005006", + "0x600621600501a00517200600621600501000520a006006216005012005", + "0x513d00514600613b00521600513b00501a00615600521600514a005145", + "0x603100521600503100514800614100521600514100519900613d005216", + "0x621600500601200615603114113d13b012005156005216005156005142", + "0x21600501a00517200600621600501200520a00600621600501000520a006", + "0x21600500620800600621600501d00502300600621600501900520a006006", + "0xc02f00604a00521600504a00502d00604a00521600500605900615e005", + "0x21600516204c00c13d00604c00521600500613b00616200521600504a15e", + "0x14600602100521600502100501a00604e005216005168005145006168005", + "0x21600512500514800600c00521600500c005199006023005216005023005", + "0x60c400604e12500c02302101200504e00521600504e005142006125005", + "0x1700601e00521600501e00503900601e005216005006035006006216005", + "0x600621600500601200602302100c6dc0201e900c21600c01e005006125", + "0xc33e00602501200c21600501200510500620d01000c216005010005105", + "0x2160051e900501a00602600521600502600502d00602600521600502520d", + "0x20a00600621600500601200620c0056dd00621600c02600533f0061e9005", + "0x600621600501200520a00600621600501900502300600621600501a005", + "0x2a00545b00602a00521600502801001d12545a0060280052160050060bd", + "0x200052160050200051460061e90052160051e900501a00620a005216005", + "0x20a00545c00612500521600512500514800600c00521600500c005199006", + "0x534300600621600500601200620a12500c0201e901200520a005216005", + "0x521600520800502d00620801a00c21600501a00510500600621600520c", + "0x62a00620700521600520700502d00620701000c216005010005105006208", + "0x50200051460061e90052160051e900501a00602d00521600520720800c", + "0x612500521600512500514800600c00521600500c005199006020005216", + "0x2d00501d00602f00521600502f00502600602f01900c2160050190052cf", + "0x3114113d13b01221600502d02f12500c0201e901d62300602d005216005", + "0x14f00600621600500601200614a0056de14800521600c146005107006146", + "0x21600500610900603900521600503501d00c02f006035005216005148005", + "0x613b00521600513b00501a00603a00521600501701000c14d006017005", + "0x503100514800614100521600514100519900613d00521600513d005146", + "0x601200521600501200502d00603a00521600503a00502d006031005216", + "0x501a00502d00601900521600501900502600603900521600503900504e", + "0x14b03c01221600501a01903901203a03114113d13b01e66100601a005216", + "0x62160050060120061500056df14e00521600c04000510c00604003f03d", + "0x15600521600504715204412545a00604715204412521600514e005149006", + "0x14b00514600603c00521600503c00501a00615e00521600515600545b006", + "0x3f00521600503f00514800603d00521600503d00519900614b005216005", + "0x21600500601200615e03f03d14b03c01200515e00521600515e00545c006", + "0x514600603c00521600503c00501a00604a00521600515000545f006006", + "0x521600503f00514800603d00521600503d00519900614b00521600514b", + "0x500601200604a03f03d14b03c01200504a00521600504a00545c00603f", + "0x1000520a00600621600501900502300600621600501a00520a006006216", + "0x545f00600621600501d00517200600621600501200520a006006216005", + "0x521600513d00514600613b00521600513b00501a00616200521600514a", + "0x545c00603100521600503100514800614100521600514100519900613d", + "0x20a00600621600500601200616203114113d13b012005162005216005162", + "0x600621600501d005172006006216005019005023006006216005012005", + "0x4c00521600500620800600621600501a00520a00600621600501000520a", + "0x16804c00c02f00616800521600516800502d006168005216005006059006", + "0x5000521600504e16d00c13d00616d00521600500613b00604e005216005", + "0x2300514600602100521600502100501a00617000521600505000545f006", + "0x12500521600512500514800600c00521600500c005199006023005216005", + "0x500600c2e100617012500c02302101200517000521600517000545c006", + "0x2160051250052e30060062160050060120060100056e012500c00c21600c", + "0x1b00060190052160050120052e400601d00521600500c00501a006012005", + "0x52e500601a0052160050060bd0060062160050060120060066e1005006", + "0x521600501e0052e400601d00521600501000501a00601e00521600501a", + "0x60200052160050066e200601e0052160050060b200601901d00c005019", + "0x390060210052160050060350060062160050060c400600621600500600c", + "0x2500c6e320d02300c21600c021005006125017006021005216005021005", + "0x2160050060b400620c0052160051250051e9006006216005006012006026", + "0x56e402a02800c21600c20c0051b600602300521600502300501a006006", + "0x50280051b400620800521600502a0050b800600621600500601200620a", + "0x60120060066e50050061b000602d0052160052080051b2006207005216", + "0x1b400613b00521600502f0051ac00602f0052160050060bd006006216005", + "0x21600520700505500602d00521600513b0051b200620700521600520a005", + "0x6e613d00521600c02d0051ae00601a00521600501a01e00c0b600601a005", + "0x1200554700603100521600513d0050bf006006216005006012006141005", + "0x14800c21600c1460056e700603100521600503100502d006146005216005", + "0x23100603900521600514a0056e90060062160050060120060350056e814a", + "0x66eb0050061b00060170052160050390056ea0061e9005216005148005", + "0x521600503a0056ec00603a0052160050060bd006006216005006012006", + "0xc6ed00601700521600503c0056ea0061e900521600503500523100603c", + "0x601200603d0056ef14b00521600c0170056ee0061e90052160051e9020", + "0x568400603f00521600514b0056f00060062160050060c4006006216005", + "0x521600520d00514600602300521600502300501a00604000521600503f", + "0x519f00603100521600503100502d00600c00521600500c00519b00620d", + "0x521600501900519f00601d00521600501d00502d006040005216005040", + "0x1001901d04003100c20d02301a6f100601000521600501000504e006019", + "0x120061560056f304700521600c1520056f200615204415014e010216005", + "0x4a0102160050470056f400615e0052160051e90053bb006006216005006", + "0x14600614e00521600514e00501a00600621600516800505100616804c162", + "0x21600501a00501d00604400521600504400519b006150005216005150005", + "0x2d00615e00521600515e0050cf00604c00521600504c00504e00601a005", + "0x4415014e01a69500616200521600516200519f00604a00521600504a005", + "0x5100521600c17000569600617005016d04e01021600516204a15e04c01a", + "0x17405705517201d2160050510056980060062160050060120060520056f5", + "0x505b0056f700605b00521600517805917405705517201d6f6006178059", + "0x616d00521600516d00514600604e00521600504e00501a00617a005216", + "0x5016d04e01000517a00521600517a0056f800605000521600505000519b", + "0x504e00501a00605d0052160050520056f900600621600500601200617a", + "0x605000521600505000519b00616d00521600516d00514600604e005216", + "0x600621600500601200605d05016d04e01000505d00521600505d0056f8", + "0x52160051560056f900600621600501a0051680060062160051e90056fa", + "0x519b00615000521600515000514600614e00521600514e00501a00617f", + "0x617f04415014e01000517f00521600517f0056f8006044005216005044", + "0x16800600621600503d0050510060062160050060c4006006216005006012", + "0x60062160050100051720060062160051e90056fa00600621600501a005", + "0x621600503100520a00600621600501d00520a0060062160050190050cc", + "0x21600506100502d0060610052160050066fb006181005216005006208006", + "0x13d00618600521600500613b00618500521600506118100c02f006061005", + "0x502300501a0060670052160050650056f900606500521600518518600c", + "0x600c00521600500c00519b00620d00521600520d005146006023005216", + "0x600621600500601200606700c20d0230100050670052160050670056f8", + "0x60062160050200056fc0060062160051410050510060062160050060c4", + "0x606b00521600506901001901d01201a01d6f60060690052160050060bd", + "0x520d00514600602300521600502300501a00618a00521600506b0056f7", + "0x518a00521600518a0056f800600c00521600500c00519b00620d005216", + "0x6fc00600621600501e00519300600621600500601200618a00c20d023010", + "0x60062160050190050cc006006216005010005172006006216005020005", + "0x62160050120050ca00600621600512500516800600621600501d00520a", + "0x21600518d00502d00618d00521600500605900606d005216005006208006", + "0x13d00607000521600500613b0060ba00521600518d06d00c02f00618d005", + "0x502500501a0060720052160051960056f90061960052160050ba07000c", + "0x600c00521600500c00519b006026005216005026005146006025005216", + "0xc00c0050061256fd00607200c0260250100050720052160050720056f8", + "0x21600501000523000600621600500601200601d01200c6fe01012500c216", + "0x1b000601e0052160050190056ff00601a00521600512500501a006019005", + "0x1a0061e900521600501d005701006006216005006012006006700005006", + "0x521600500670200601e0052160051e90056ff00601a005216005012005", + "0x6a600602100521600502001e00c70300602000521600502000502d006020", + "0x502300523400600621600500601200620d00570402300521600c021005", + "0x620c005216005026005706006026005216005025005705006025005216", + "0x620c01a00c00520c00521600520c00570700601a00521600501a00501a", + "0x521600501a00501a00602800521600520d005708006006216005006012", + "0x1e00521600500670900602801a00c00502800521600502800570700601a", + "0x61e90052160050060350060062160050060c400600621600500600c006", + "0xc70a02102000c21600c1e90050061250170061e90052160051e9005039", + "0x50060b400602500521600512500554700600621600500601200620d023", + "0x70b20c02600c21600c0250056e700602000521600502000501a006006216", + "0x2600523100602a00521600520c0056e9006006216005006012006028005", + "0x1200600670c0050061b000620800521600502a0056ea00620a005216005", + "0x602d0052160052070056ec0062070052160050060bd006006216005006", + "0x520a0053bb00620800521600502d0056ea00620a005216005028005231", + "0x2f00521600c2080056ee00601a00521600501a01e00c70d00601a005216", + "0x502f0056f00060062160050060c400600621600500601200613b00570e", + "0x602000521600502000501a00614100521600513d00568400613d005216", + "0x514100519f00600c00521600500c00519b006021005216005021005146", + "0x601d00521600501d00502d00601200521600501200501d006141005216", + "0x1021600501901d01214100c02102001970f00601900521600501900519f", + "0x21600500601200603900571103500521600c14a00571000614a148146031", + "0x3d00521600c14b00501e00614b03c03a017010216005035005712006006", + "0x1a00604000521600503d01000c02f00600621600500601200603f005713", + "0x21600514800519b006146005216005146005146006031005216005031005", + "0x1d00604000521600504000504e00601a00521600501a0050cf006148005", + "0x21600503c00519f00603a00521600503a00502d006017005216005017005", + "0x15204415014e01021600503c03a01704001a14814603101a6c200603c005", + "0x56c500600621600500601200615600571404700521600c1520056c3006", + "0x504e16804c16204a15e01d71500604e16804c16204a15e01d216005047", + "0x614e00521600514e00501a00605000521600516d00571600616d005216", + "0x505000522f00604400521600504400519b006150005216005150005146", + "0x515600571700600621600500601200605004415014e010005050005216", + "0x615000521600515000514600614e00521600514e00501a006170005216", + "0x4415014e01000517000521600517000522f00604400521600504400519b", + "0x52160050060bd00600621600503f005051006006216005006012006170", + "0x21600505200571600605200521600505101003c03a01701a01d715006051", + "0x19b00614600521600514600514600603100521600503100501a006172005", + "0x17214814603101000517200521600517200522f006148005216005148005", + "0x621600501a0050ca006006216005010005172006006216005006012006", + "0x14600514600603100521600503100501a006055005216005039005717006", + "0x5500521600505500522f00614800521600514800519b006146005216005", + "0x510060062160050060c4006006216005006012006055148146031010005", + "0x1001901d01201a01d7150060570052160050060bd00600621600513b005", + "0x521600502000501a006059005216005174005716006174005216005057", + "0x522f00600c00521600500c00519b006021005216005021005146006020", + "0x571800600621600500601200605900c021020010005059005216005059", + "0x20a0060062160050190050cc00600621600501000517200600621600501e", + "0x60062160051250050ca00600621600501200516800600621600501d005", + "0x521600505b00502d00605b005216005006059006178005216005006208", + "0xc13d00605d00521600500613b00617a00521600505b17800c02f00605b", + "0x21600502300501a00618100521600517f00571700617f00521600517a05d", + "0x22f00600c00521600500c00519b00620d00521600520d005146006023005", + "0x612500521600500620800618100c20d023010005181005216005181005", + "0x501012500c02f00601000521600501000502d006010005216005006719", + "0x521600500501d00c02f00601d00521600500601200c02f006012005216", + "0x61e901e00c21600501a00505200601a00521600500c01900c02f006019", + "0x21600502000501d0060200052160051e900505500600621600501e005172", + "0xc400600621600500600c00601e00521600500671a006020005005020005", + "0x600600521600500600501a0061e90052160050066c1006006216005006", + "0x2000519f00602001d00c21600501d0053c60061e90052160051e900519f", + "0xc0230056a600602302100c2160050201e900612571b006020005216005", + "0x2600521600520d00523400600621600500601200602500571c20d005216", + "0x100053c600620c00521600502600571d00602600521600502600519f006", + "0x20720800c71f20a02a00c21600c02820c02112571e00602801000c216005", + "0x52160051250050c100600621600520a0050cc006006216005006012006", + "0xc72000602d00521600502d00502d00602a00521600502a00501a00602d", + "0x501200502d00602f00521600502f00501a00613b02f00c21600502d02a", + "0x521600513d00501a00601a13d00c21600501202f00c720006012005216", + "0x53c600613b00521600513b00572100600500521600500500514600613d", + "0x501a01e00c72200614100521600514100519f00614101d00c21600501d", + "0x14800572400614814603112521600514113b00513d01072300601a005216", + "0xc21600501a00572600600621600500601200603500572514a00521600c", + "0x614b03c00c21600503a00572600603a00521600514a005727006017039", + "0x600621600503f00542a00614e04003f03d01021600503c03900c125728", + "0x604715204415001021600514b01703d12572800600621600504000542a", + "0x21600504714e00c72900600621600515200542a00600621600504400542a", + "0x72a00615600521600515600572100603100521600503100501a006156005", + "0x4a00501e00615000521600515000519b00604a15e00c21600515603100c", + "0x521600515e00501a00600621600500601200604c00572b16200521600c", + "0x1256a500601000521600501000519f00601d00521600501d00519f00615e", + "0x605000572c16d00521600c04e0056a600604e16800c21600501001d15e", + "0x510052160050060bd00617000521600516d005234006006216005006012", + "0x617200521600505200572e00605200521600505101917016201072d006", + "0x515000519b00614600521600514600514600616800521600516800501a", + "0x601200617215014616801000517200521600517200572f006150005216", + "0x573000600621600501900517200600621600516200520a006006216005", + "0x521600514600514600616800521600516800501a006055005216005050", + "0x16801000505500521600505500572f00615000521600515000519b006146", + "0x1900517200600621600504c005051006006216005006012006055150146", + "0x620800600621600501d0050cc0060062160050100050cc006006216005", + "0x617400521600517400502d0061740052160050066fb006057005216005", + "0x5917800c13d00617800521600500613b00605900521600517405700c02f", + "0x15e00521600515e00501a00617a00521600505b00573000605b005216005", + "0x17a00572f00615000521600515000519b006146005216005146005146006", + "0x1900517200600621600500601200617a15014615e01000517a005216005", + "0x57310060062160050100050cc00600621600501d0050cc006006216005", + "0x3100521600503100501a00605d00521600503500573000600621600501a", + "0x5d00572f00600c00521600500c00519b006146005216005146005146006", + "0x2070050cc00600621600500601200605d00c14603101000505d005216005", + "0xc02f00600621600501e00573200600621600501d0050cc006006216005", + "0x52160050060bd0061810052160051250050c100617f005216005012019", + "0x18600521600518500572e00618500521600506117f01018101072d006061", + "0xc00519b00600500521600500500514600620800521600520800501a006", + "0x1200618600c00520801000518600521600518600572f00600c005216005", + "0xcc00600621600501d0050cc006006216005019005172006006216005006", + "0x600621600501e00573200600621600501200520a006006216005010005", + "0x21600502100501a00606500521600502500573000600621600512500520a", + "0x72f00600c00521600500c00519b006005005216005005005146006021005", + "0xc00521600c00600573300606500c005021010005065005216005065005", + "0xc00570500600621600500500520a006006216005006012006125005734", + "0x12005216005012005707006012005216005010005706006010005216005", + "0x50062080060062160051250050cc006006216005006012006012005005", + "0x601a00521600500613b00601900521600500501d00c02f00601d005216", + "0x1e90057070061e900521600501e00570800601e00521600501901a00c13d", + "0x521600500671a00601a0052160050060b20061e90050051e9005216005", + "0x21600500671a00620d00521600500673500602100521600500605b0061e9", + "0x52160050066c10060062160050060c400600621600500600c006026005", + "0x53c600620c00521600520c00519f00600600521600500600501a00620c", + "0x2820c00612571b00602800521600502800519f00602801d00c21600501d", + "0x500601200620700573620800521600c20a0056a600620a02a00c216005", + "0x71d00602d00521600502d00519f00602d005216005208005234006006216", + "0x2f02a12571e00613b12500c2160051250053c600602f00521600502d005", + "0x1410050cc00600621600500601200614603100c73714113d00c21600c13b", + "0x50690060062160051e900573200600621600501a005193006006216005", + "0x1200c21600501200510500613d00521600513d00501a006006216005021", + "0x602514a00c21600514813d00c72000614800521600514800502d006148", + "0x21600503903500c729006039005216005006739006035005216005006738", + "0x72100600500521600500500514600614a00521600514a00501a006017005", + "0x503a00519f00603a12500c2160051250053c6006017005216005017005", + "0x503a01700514a01072300602500521600502502600c72200603a005216", + "0x500601200604000573a03f00521600c03d00572400603d14b03c125216", + "0x673900615000521600500673800614e00521600503f005727006006216", + "0x521600503c00501a00615200521600504415000c729006044005216005", + "0x12573b00615200521600515200572100614e00521600514e00572100603c", + "0x615e00573c02300521600c15600572400615604700c21600515214e03c", + "0x521600514b00514600604700521600504700501a006006216005006012", + "0x19f00604a01d00c21600501d0053c600602500521600502500572100614b", + "0x14b04701073e00602300521600502320d00c73d00604a00521600504a005", + "0x616d00573f04e00521600c16800572400616804c16212521600504a025", + "0xc216005050005726006050005216005023005727006006216005006012", + "0x605517200c21600505200572600605200521600504e005727006051170", + "0x600621600505900542a00617805917405701021600517217000c125728", + "0x617f05d17a05b01021600505505105712572800600621600517800542a", + "0x521600516200501a00600621600517f00542a00600621600505d00542a", + "0x1256a500612500521600512500519f00601d00521600501d00519f006162", + "0x5b00519b00617400521600517400574000606118100c21600512501d162", + "0x18500521600c0610056a600617a00521600517a00574000605b005216005", + "0x1a00606500521600517a17400c729006006216005006012006186005741", + "0x506518100c72a006065005216005065005721006181005216005181005", + "0x506906b01201001074200606b00521600518500523400606906700c216", + "0x606700521600506700501a00606d00521600518a00574300618a005216", + "0x506d00574400605b00521600505b00519b00604c00521600504c005146", + "0x517400542a00600621600500601200606d05b04c06701000506d005216", + "0x17a00542a00600621600501000516800600621600501200520a006006216", + "0x618100521600518100501a00618d005216005186005745006006216005", + "0x518d00574400605b00521600505b00519b00604c00521600504c005146", + "0x501200520a00600621600500601200618d05b04c18101000518d005216", + "0x1250050cc00600621600501d0050cc006006216005010005168006006216", + "0x1a0060ba00521600516d005745006006216005023005746006006216005", + "0x21600500c00519b00604c00521600504c005146006162005216005162005", + "0x50060120060ba00c04c1620100050ba0052160050ba00574400600c005", + "0x1000516800600621600501200520a0060062160051250050cc006006216", + "0x574700600621600502500573100600621600501d0050cc006006216005", + "0x4700521600504700501a00607000521600515e00574500600621600520d", + "0x7000574400600c00521600500c00519b00614b00521600514b005146006", + "0x1250050cc00600621600500601200607000c14b047010005070005216005", + "0x516800600621600501200520a00600621600520d005747006006216005", + "0x74500600621600502500573100600621600501d0050cc006006216005010", + "0x21600514b00514600603c00521600503c00501a006196005216005040005", + "0x1000519600521600519600574400600c00521600500c00519b00614b005", + "0x57470060062160051460050cc00600621600500601200619600c14b03c", + "0x60720052160050100051e900600621600502600573200600621600520d", + "0xc21600c0720051b600603100521600503100501a0060062160050060b4", + "0x61a000521600519d0050b800600621600500601200607600574819d19a", + "0x7490050061b00061a20052160051a00051b20061a100521600519a0051b4", + "0x21600507b0051ac00607b0052160050060bd006006216005006012006006", + "0x550061a20052160051a40051b20061a10052160050760051b40061a4005", + "0xc1a20051ae00601900521600501901a00c0b60060190052160051a1005", + "0x600621600501d0050cc00600621600500601200607e00574a1a8005216", + "0x2160051250053c60060200052160051a80050bf00600621600501200520a", + "0x521600502002100c17a00608d08c00c2160051ab00574b0061ab12500c", + "0x6c100608f00521600508e0050c100608e02000c216005020005105006020", + "0x2160050910050cc00609209100c21600509000574b006090005216005006", + "0xc74c00609400521600509200568400609300521600508d005684006006", + "0x60062160050060c400600621600500601200600674d00621600c094093", + "0x509500502d00603100521600503100501a0060950052160050200050c1", + "0x1b500521600500673800601e09600c21600509503100c720006095005216", + "0x9600501a00609c00521600509b1b500c72900609b005216005006739006", + "0x9c00521600509c005721006005005216005005005146006096005216005", + "0x1072300601e00521600501e1e900c72200608c00521600508c00519f006", + "0x574e0a100521600c09700572400609709f05f12521600508c09c005096", + "0x2160050067380061be0052160050a10057270060062160050060120061bd", + "0x1a0060a80052160050a61c100c7290060a60052160050067390061c1005", + "0x2160050a80057210061be0052160051be00572100605f00521600505f005", + "0x521600c0aa0057240060aa1bc00c2160050a81be05f12573b0060a8005", + "0x60980a900c21600501e0057260060062160050060120060b000574f0ac", + "0xc1257280060b41b900c2160050b20057260060b20052160050ac005727", + "0x1b400542a0060062160050b800542a0061b40b81b60b60102160051b90a9", + "0xbd00542a0061ac0bd1b01b20102160050b40980b6125728006006216005", + "0x61ae0052160051b01b600c7290060062160051ac00542a006006216005", + "0x1ae1bc00c72a0061ae0052160051ae0057210061bc0052160051bc00501a", + "0x1aa0057430061aa0052160050c112508f0190107420060c10bf00c216005", + "0x9f00521600509f0051460060bf0052160050bf00501a0061a7005216005", + "0x9f0bf0100051a70052160051a70057440061b20052160051b200519b006", + "0x508f00520a0060062160050190051680060062160050060120061a71b2", + "0xb000574500600621600501e0057310060062160051250050cc006006216", + "0x9f00521600509f0051460061bc0052160051bc00501a0060c4005216005", + "0x9f1bc0100050c40052160050c400574400600c00521600500c00519b006", + "0x508f00520a0060062160050190051680060062160050060120060c400c", + "0x1bd00574500600621600501e0057310060062160051250050cc006006216", + "0x9f00521600509f00514600605f00521600505f00501a0060c6005216005", + "0x9f05f0100050c60052160050c600574400600c00521600500c00519b006", + "0x21600508c0050cc0060062160050060c40060062160050060120060c600c", + "0x508f00510500600621600502000520a0060062160051e9005732006006", + "0x50c812508f0190107420060c80052160051a50051640061a508f00c216", + "0x603100521600503100501a00619c0052160051a30057430061a3005216", + "0x519c00574400600c00521600500c00519b006005005216005005005146", + "0x2160050060c400600621600500601200619c00c00503101000519c005216", + "0x51e90057320060062160051250050cc00600621600507e005051006006", + "0xca0050fa0060ca0052160050060bd006006216005021005069006006216", + "0x519b00574300619b0052160050cc01d0120190107420060cc005216005", + "0x600500521600500500514600603100521600503100501a006199005216", + "0xc00503101000519900521600519900574400600c00521600500c00519b", + "0x21600520d0057470060062160051250050cc006006216005006012006199", + "0x501d0050cc00600621600501000516800600621600501200520a006006", + "0x1e900573200600621600501a005193006006216005026005732006006216", + "0x1a00619f005216005207005745006006216005021005069006006216005", + "0x21600500c00519b00600500521600500500514600602a00521600502a005", + "0x612571e00619f00c00502a01000519f00521600519f00574400600c005", + "0x523000600621600500601200601d01200c75001012500c21600c00c005", + "0x52160050190056ff00601a00521600512500501a006019005216005010", + "0x521600501d0057010060062160050060120060067510050061b000601e", + "0x675200601e0052160051e90056ff00601a00521600501200501a0061e9", + "0x521600502001e00c70300602000521600502000502d006020005216005", + "0x23400600621600500601200620d00575302300521600c0210056a6006021", + "0x216005026005706006026005216005025005705006025005216005023005", + "0xc00520c00521600520c00570700601a00521600501a00501a00620c005", + "0x1a00501a00602800521600520d00570800600621600500601200620c01a", + "0x600519f00602801a00c00502800521600502800570700601a005216005", + "0x1012575512500c00c21600c00500600c754006006005005006005216005", + "0x1912500c72900601900521600500673900600621600500601200601d012", + "0x1e900521600501a00572100601e00521600500c00501a00601a005216005", + "0x521600501201d00c7290060062160050060120060067560050061b0006", + "0x1e00c0051e900521600502000572100601e00521600501000501a006020", + "0x52160050067390060100052160050067570060062160050060c40061e9", + "0x14600600600521600500600501a00601d00521600501201000c729006012", + "0x21600512500519f00601d00521600501d005721006005005216005005005", + "0xc01e00572400601e01a01912521600512501d005006010758006125005", + "0x210052160051e90057270060062160050060120060200057591e9005216", + "0x2100572100600c00521600500c00572100601900521600501900501a006", + "0xc20d00572400620d02300c21600502100c01912575a006021005216005", + "0x20c00521600502500572700600621600500601200602600575b025005216", + "0x2300501a00602a00521600502800575d00602800521600520c00575c006", + "0x2a00521600502a00575e00601a00521600501a005146006023005216005", + "0x620a00521600502600575f00600621600500601200602a01a023125005", + "0x520a00575e00601a00521600501a00514600602300521600502300501a", + "0x21600500c00573100600621600500601200620a01a02312500520a005216", + "0x514600601900521600501900501a00620800521600502000575f006006", + "0x72600620801a01912500520800521600520800575e00601a00521600501a", + "0x21600501000576100601000521600500676000612500c00c216005005005", + "0x1200521600501200574000601d12500c21600512500576100601201000c", + "0x2160050060120061e901e00c76301a01900c21600c01d012006125762006", + "0x576400602102000c21600512500576400600621600501a00542a006006", + "0x521600502100576500600621600502300542a00620d02300c216005010", + "0xc76600601900521600501900501a00602600521600520d005765006025", + "0x521600500c00574000600621600500601200600676700621600c026025", + "0xc21600500c0057640060062160050060120060067680050061b000620c", + "0x42a00620720800c21600520a00576400620a00521600500673900602a028", + "0xc21600502d00576400602d00521600502a005765006006216005208005", + "0x576400613d00521600520700576500600621600502f00542a00613b02f", + "0x521600513b00576500600621600514100542a00603114100c21600513d", + "0x600676900621600c14814600c766006148005216005031005765006146", + "0x600621600502800542a00600621600502000542a006006216005006012", + "0x21600501900501a00603500521600514a0050fa00614a0052160050060bd", + "0x621600500601200603501900c0050350052160050350050e9006019005", + "0x500676a00603900521600502000523800620c005216005028005740006", + "0x3c00521600520c00523800603a00521600501703900c76b006017005216", + "0x516400614b00521600503c03a00c14d00603a00521600503a00502d006", + "0x521600503d0050e900601900521600501900501a00603d00521600514b", + "0x42a0060062160051e900542a00600621600500601200603d01900c00503d", + "0x600621600500c00542a00600621600501000542a006006216005125005", + "0x21600501e00501a00604000521600503f0050fa00603f0052160050060bd", + "0x21600500600501a00604001e00c0050400052160050400050e900601e005", + "0x76c00600c00521600500c005721006005005216005005005721006006005", + "0x1d00576e01200521600c01000576d00601012500c21600500c005006125", + "0x21600501900575d00601900521600501200575c006006216005006012006", + "0xc00501a00521600501a00575e00612500521600512500501a00601a005", + "0x21600500620800600621600501d00505100600621600500601200601a125", + "0xc02f0061e90052160051e900502d0061e900521600500676f00601e005", + "0x21600502002100c13d00602100521600500613b0060200052160051e901e", + "0x75e00612500521600512500501a00620d00521600502300575f006023005", + "0x50067570060062160050060c400620d12500c00520d00521600520d005", + "0x601d00521600501201000c729006012005216005006739006010005216", + "0x501d00572100600500521600500500514600600600521600500600501a", + "0x21600512501d00500601075800612500521600512500519f00601d005216", + "0x2160050060120060200057701e900521600c01e00572400601e01a019125", + "0x572100601900521600501900501a0060210052160051e9005727006006", + "0x502100c01912577100602100521600502100572100600c00521600500c", + "0x21600500601200602600577202500521600c20d00572400620d02300c216", + "0x575d00602800521600520c00575c00620c005216005025005727006006", + "0x521600501a00514600602300521600502300501a00602a005216005028", + "0x621600500601200602a01a02312500502a00521600502a00575e00601a", + "0x1a00514600602300521600502300501a00620a00521600502600575f006", + "0x601200620a01a02312500520a00521600520a00575e00601a005216005", + "0x1a00620800521600502000575f00600621600500c005731006006216005", + "0x21600520800575e00601a00521600501a005146006019005216005019005", + "0x100052160050060350060062160050060c400620801a019125005208005", + "0x77301d01200c21600c010005006125017006010005216005010005039006", + "0x3d80061e901e00c21600512500574b00600621600500601200601a01900c", + "0x2160050210050cc00602302100c21600502000574b006020005216005006", + "0x501a00602500521600502300568400620d0052160051e9005684006006", + "0x21600500601200600677400621600c02520d00c74c006012005216005012", + "0x574b0060280052160050066a400620c02600c21600501e00574b006006", + "0x521600520c00568400600621600502a0050cc00620a02a00c216005028", + "0x600677500621600c20720800c74c00620700521600520a005684006208", + "0xc21600500c00577600601200521600501200501a006006216005006012", + "0x602f00c00c21600500c00577600602d00521600502d00572100602d00c", + "0x72400613d13b00c21600502f02d01212575a00602f00521600502f005721", + "0x21600500677800600621600500601200603100577714100521600c13d005", + "0x614802600c2160050260053c600613b00521600513b00501a006146005", + "0x14813b12577900614600521600514600519f00614800521600514800519f", + "0x601200601700577a03900521600c0350056a600603514a00c216005146", + "0x603c00521600503900523400603a005216005141005727006006216005", + "0x503a00572100601d00521600501d00514600614a00521600514a00501a", + "0x21600503c03a01d14a01075800603c00521600503c00519f00603a005216", + "0x21600500601200614e00577b04000521600c03f00572400603f03d14b125", + "0x2600519f00614b00521600514b00501a006150005216005006778006006", + "0x21600515002614b12577c00615000521600515000519f006026005216005", + "0x621600500601200615600577d04700521600c1520056a600615204400c", + "0x4a00574b00604a00521600504700523400615e005216005040005727006", + "0x61680052160050066a40060062160051620050cc00604c16200c216005", + "0x504c00568400600621600504e0050cc00616d04e00c21600516800574b", + "0x77e00621600c17005000c74c00617000521600516d005684006050005216", + "0x21600515e00575c00600621600500c005731006006216005006012006006", + "0x14600604400521600504400501a00605200521600505100575d006051005", + "0x605203d04412500505200521600505200575e00603d00521600503d005", + "0x521600500c00572100604400521600504400501a006006216005006012", + "0x5517200c21600515e00c04412575a00615e00521600515e00572100600c", + "0x572700600621600500601200617400577f05700521600c055005724006", + "0x521600517800575d00617800521600505900575c006059005216005057", + "0x575e00603d00521600503d00514600617200521600517200501a00605b", + "0x17400575f00600621600500601200605b03d17212500505b00521600505b", + "0x3d00521600503d00514600617200521600517200501a00617a005216005", + "0x600621600500601200617a03d17212500517a00521600517a00575e006", + "0x521600515600575f00600621600500c005731006006216005040005746", + "0x575e00603d00521600503d00514600604400521600504400501a00605d", + "0xc00573100600621600500601200605d03d04412500505d00521600505d", + "0x1a00617f00521600514e00575f0060062160050260050cc006006216005", + "0x21600517f00575e00603d00521600503d00514600614b00521600514b005", + "0x621600500c00573100600621600500601200617f03d14b12500517f005", + "0x21600501700575f0060062160051410057460060062160050260050cc006", + "0x75e00601d00521600501d00514600614a00521600514a00501a006181005", + "0x573100600621600500601200618101d14a125005181005216005181005", + "0x606100521600503100575f0060062160050260050cc00600621600500c", + "0x506100575e00601d00521600501d00514600613b00521600513b00501a", + "0x2160050260050cc00600621600500601200606101d13b125005061005216", + "0x501a00618600521600518500575d00618500521600500c00575c006006", + "0x521600518600575e00601d00521600501d005146006012005216005012", + "0x600621600500c00573100600621600500601200618601d012125005186", + "0x6700521600500673900606500521600500673800600621600501e0050cc", + "0x575d00606b00521600506900575c00606900521600506706500c729006", + "0x521600501d00514600601200521600501200501a00618a00521600506b", + "0x621600500601200618a01d01212500518a00521600518a00575e00601d", + "0x52160050062080060062160051250050cc00600621600500c005731006", + "0x6d00c02f00618d00521600518d00502d00618d00521600500605900606d", + "0x52160050ba07000c13d00607000521600500613b0060ba00521600518d", + "0x514600601900521600501900501a00607200521600519600575f006196", + "0x1a00607201a01912500507200521600507200575e00601a00521600501a", + "0x21600500c005721006005005216005005005721006006005216005006005", + "0x521600c01000576d00601012500c21600500c00500612578000600c005", + "0x75d00601900521600501200575c00600621600500601200601d005781012", + "0x21600501a00575e00612500521600512500501a00601a005216005019005", + "0x600621600501d00505100600621600500601200601a12500c00501a005", + "0x52160051e900502d0061e900521600500678200601e005216005006208", + "0xc13d00602100521600500613b0060200052160051e901e00c02f0061e9", + "0x21600512500501a00620d00521600502300575f006023005216005020021", + "0x21600500600501a00620d12500c00520d00521600520d00575e006125005", + "0x78300600c00521600500c005721006005005216005005005721006006005", + "0x12f00601d01200c21600501000578400601012500c21600500c005006125", + "0x501900505100600621600500601200601a00578501900521600c01d005", + "0x1b00061e900521600501e00578700601e005216005012005786006006216", + "0x573100600621600501a005051006006216005006012006006788005006", + "0x60210052160050200057890060200052160050060bd006006216005012", + "0x51e900578700612500521600512500501a0061e9005216005021005787", + "0x500c00578a00600c00521600500c0057210061e912500c0051e9005216", + "0x621600500601200601200578c01000521600c12500578b006125005216", + "0x601a00578f01900521600c01d00578e00601d00521600501000578d006", + "0x1a0060210201e901e010216005019005006125790006006216005006012", + "0x502101e00c79200602100521600502100579100601e00521600501e005", + "0x250052160050201e900c79300600621600520d00505100620d02300c216", + "0x2600575c00600621600520c00573100620c02600c216005025005794006", + "0x2a00521600502a00575e00602a00521600502800575d006028005216005", + "0x573100600621600501a00505100600621600500601200602a02300c005", + "0x2d00620800521600500679500620a005216005006208006006216005005", + "0x21600500613b00620700521600520820a00c02f006208005216005208005", + "0x613b00521600502f00575f00602f00521600520702d00c13d00602d005", + "0x613b00600c00513b00521600513b00575e00600600521600500600501a", + "0x13d00521600501200575f006006216005005005731006006216005006012", + "0x13d00600c00513d00521600513d00575e00600600521600500600501a006", + "0x12500579700612500521600500c00579600600c00521600500c00519f006", + "0x521600501000579900600621600500601200601200579801000521600c", + "0x79c00600621600500601200601a00579b01900521600c01d00579a00601d", + "0x57050060062160050200050cc0060201e901e125216005019005006125", + "0x521600501e00501a0060230052160050210057060060210052160051e9", + "0x600621600500601200602301e00c00502300521600502300570700601e", + "0x20d0052160050062080060062160050050050cc00600621600501a005051", + "0x2520d00c02f00602500521600502500502d006025005216005006795006", + "0x2800521600502620c00c13d00620c00521600500613b006026005216005", + "0x2a00570700600600521600500600501a00602a005216005028005708006", + "0x2160050050050cc00600621600500601200602a00600c00502a005216005", + "0x570700600600521600500600501a00620a005216005012005708006006", + "0x579600600c00521600500c00519f00620a00600c00520a00521600520a", + "0x500601200601200579d01000521600c12500579700612500521600500c", + "0x579e01900521600c01d00579a00601d005216005010005799006006216", + "0x60201e901e12521600501900500612579c00600621600500601200601a", + "0x2160050210057060060210052160050200057050060062160051e90050cc", + "0xc00502300521600502300570700601e00521600501e00501a006023005", + "0x50050050cc00600621600501a00505100600621600500601200602301e", + "0x2500502d00602500521600500679500620d005216005006208006006216", + "0x20c00521600500613b00602600521600502520d00c02f006025005216005", + "0x501a00602a00521600502800570800602800521600502620c00c13d006", + "0x601200602a00600c00502a00521600502a005707006006005216005006", + "0x1a00620a0052160050120057080060062160050050050cc006006216005", + "0x1a00620a00600c00520a00521600520a005707006006005216005006005", + "0x21600500c005721006005005216005005005721006006005216005006005", + "0xc21600501000578400601012500c21600500c00500612579f00600c005", + "0x600621600500601200601a0057a001900521600c01d00512f00601d012", + "0x21600501e00578700601e005216005012005786006006216005019005051", + "0x21600501a0050510060062160050060120060067a10050061b00061e9005", + "0x50200057890060200052160050060bd006006216005012005731006006", + "0x612500521600512500501a0061e9005216005021005787006021005216", + "0x1012500c2160050050057260061e912500c0051e90052160051e9005787", + "0x1a01900c21600c01d01000612576200601d01200c21600500c005726006", + "0x53090060200052160050060bd0060062160050060120061e901e00c7a2", + "0x21600501900501a00602300521600502101a00c7a3006021005216005020", + "0x50060120060067a40050061b000602500521600502300523a00620d005", + "0xc7a300620c0052160050260052f90060260052160050060bd006006216", + "0x21600502800523a00620d00521600501e00501a00602800521600520c1e9", + "0xc21600c01212520d12576200620a02a00c2160050250057a5006025005", + "0x521600502a20700c72900600621600500601200602f02d00c7a6207208", + "0x7a800614100521600520800501a00613d00521600520a13b00c7a700613b", + "0x7380060062160050060120060067a90050061b000603100521600513d005", + "0xc14602a02d125762006146005216005146005740006146005216005006", + "0x514a02f00c72900600621600500601200603903500c7aa14a14800c216", + "0x3c00521600514800501a00603a00521600520a01700c7a7006017005216", + "0x62160050060120060067ab0050061b000614b00521600503a0057a8006", + "0x50060bd00603d00521600503902f00c72900600621600520a00519a006", + "0x14e00521600504003d00c7a700604000521600503f0052f900603f005216", + "0x3c00550100614b00521600514e0057a800603c00521600503500501a006", + "0x600572100603114100c00503100521600514b0057ac006141005216005", + "0xc00521600c0050057ae0060050052160050060057ad006006005216005", + "0x523900601000521600500c0057b00060062160050060120061250057af", + "0x521600501d0057b200601d0052160050120057b1006012005216005010", + "0x7b40060062160050060120060190050050190052160050190057b3006019", + "0xc7b500601a00500501a00521600501a0057b300601a005216005125005", + "0x521600500c00501a0061250052160050060bd00600c005216005005006", + "0x52160050060057b600600600521600500600519f00612500c00c00500c", + "0x7b90060062160050060120061250057b800c00521600c0050057b7006005", + "0x2160050120057bb0060120052160050100057ba00601000521600500c005", + "0x50050190052160050190057bd00601900521600501d0057bc00601d005", + "0x501a0057bd00601a0052160051250057be006006216005006012006019", + "0x500c00572600601012500c21600500500572600601a00500501a005216", + "0xc21600501200576100601912500c21600512500576100601d01200c216", + "0x521600500600501a0060201e901e12521600501a01900c7bf00601a012", + "0x602302100c21600502000600c792006020005216005020005791006006", + "0x20d12500c7bf00620d01d00c21600501d005761006006216005023005051", + "0x21600520c00579100602100521600502100501a00620c026025125216005", + "0x600621600502a00505100602a02800c21600520c02100c79200620c005", + "0x576100620720800c21600520a00523700620a00521600502602500c7c0", + "0x501a00613d13b02f12521600501202d00c7bf00602d01000c216005010", + "0x21600513d02800c79200613d00521600513d005791006028005216005028", + "0x614600521600513b02f00c7c000600621600503100505100603114100c", + "0x52370060350052160051e901e00c7c000614a14800c216005146005237", + "0x21600520700574000603900521600503900574000601703900c216005035", + "0x740006148005216005148005740006208005216005208005740006207005", + "0x2070391411257c100601700521600501700574000614a00521600514a005", + "0x520800576400600621600500601200603d14b00c7c203c03a00c21600c", + "0x76400614e00521600500673900600621600503f00542a00604003f00c216", + "0x21600504000576500600621600515000542a00604415000c21600514e005", + "0x76500600621600504700542a00615604700c216005152005764006152005", + "0x504a00542a00616204a00c21600515e00576400615e005216005044005", + "0x1a00616800521600516200576500604c005216005156005765006006216", + "0x50060120060067c300621600c16804c00c76600603a00521600503a005", + "0x14800542a00600621600501000542a00600621600501d00542a006006216", + "0x51480057640060062160050060120060067c40050061b0006006216005", + "0x76400605000521600500673900600621600504e00542a00616d04e00c216", + "0x21600516d00576500600621600517000542a00605117000c216005050005", + "0x76500600621600517200542a00605517200c216005052005764006052005", + "0x517400542a00605917400c216005057005764006057005216005051005", + "0x76600605b005216005059005765006178005216005055005765006006216", + "0x52160050060bd0060062160050060120060067c500621600c05b17800c", + "0x61b000617f00521600505d00519d00605d00521600517a00530900617a", + "0x1810052f90061810052160050060bd0060062160050060120060067c6005", + "0x18500521600517f00542200617f00521600506100519d006061005216005", + "0x60650057c718600521600c18500512f00618500521600518500519d006", + "0x6067005216005006739006006216005186005051006006216005006012", + "0xc7c806b06900c21600c01006703a125762006067005216005067005740", + "0x501d00542a00600621600506b00542a00600621600500601200606d18a", + "0x501a0060ba00521600518d00530900618d0052160050060bd006006216", + "0x60067c90050061b00061960052160050ba00519d006070005216005069", + "0x607200521600500673900600621600506d00542a006006216005006012", + "0xc7ca19d19a00c21600c01d07218a125762006072005216005072005740", + "0x2160050060bd00600621600519d00542a0060062160050060120061a0076", + "0x19d00607b00521600519a00501a0061a20052160051a10053090061a1005", + "0x42a0060062160050060120060067cb0050061b00061a40052160051a2005", + "0x7e0052160051a80052f90061a80052160050060bd0060062160051a0005", + "0x7b0055010061a400521600507e00519d00607b00521600507600501a006", + "0x1ab0052160050700055010061960052160051a40052ed006070005216005", + "0x62160050060120060067cc0050061b000608c0052160051960052ed006", + "0x21600501000542a00600621600501d00542a006006216005065005051006", + "0x3a00501a00608e00521600508d0052f900608d0052160050060bd006006", + "0x521600508c03c00c7a300608c00521600508e00519d0061ab005216005", + "0x61b000609100521600508f00523a0060900052160051ab00501a00608f", + "0x14800542a00600621600520800542a0060062160050060120060067cd005", + "0x60bd00600621600501000542a00600621600501d00542a006006216005", + "0x521600509303d00c7a30060930052160050920052f9006092005216005", + "0x57a500609100521600509400523a00609000521600514b00501a006094", + "0x9c00c7ce09b1b500c21600c14a0950901257c100609609500c216005091", + "0x1b500501a00609f00521600509609b00c7a300600621600500601200605f", + "0x120060067cf0050061b00060a100521600509f00523a006097005216005", + "0x2f90061bd0052160050060bd00600621600509600519a006006216005006", + "0x509c00501a0061c10052160051be05f00c7a30061be0052160051bd005", + "0xa80a600c2160050a10057a50060a10052160051c100523a006097005216", + "0x1a0060aa0052160050a81bc00c7a70061bc0052160050a601700c729006", + "0x7210060aa09700c0050aa0052160050aa0057a8006097005216005097005", + "0x21600c00500578e0060050052160050060057d0006006005216005006005", + "0x601000521600500c0057d20060062160050060120061250057d100c005", + "0x120060120050050120052160050120057d40060120052160050100057d3", + "0x7d500601d005216005006208006006216005125005051006006216005006", + "0x21600501901d00c02f00601900521600501900502d006019005216005006", + "0x7d60061e900521600501a01e00c13d00601e00521600500613b00601a005", + "0x519f0060200050050200052160050200057d40060200052160051e9005", + "0x521600c00500579a0060050052160050060057d7006006005216005006", + "0x7da00601000521600500c0057d90060062160050060120061250057d800c", + "0x60120060120050050120052160050120057db006012005216005010005", + "0x67dc00601d005216005006208006006216005125005051006006216005", + "0x521600501901d00c02f00601900521600501900502d006019005216005", + "0x57dd0061e900521600501a01e00c13d00601e00521600500613b00601a", + "0x60057de0060200050050200052160050200057db0060200052160051e9", + "0x600c0052160050060bd0060062160050060120060050057df00621600c", + "0x7e20050061b00060100052160051250057e100612500521600500c0057e0", + "0x50120057e1006012005216005005005239006006216005006012006006", + "0x50060120060050057e300621600c006005236006010005005010005216", + "0x57e500612500521600500c0057e400600c0052160050060bd006006216", + "0x57ba0060062160050060120060067e60050061b0006010005216005125", + "0x12600601214d0100050050100052160050120057e5006012005216005005", + "0x11c13712600601200601012500c00500613611c13712600601203911c137", + "0x1203911c13712600601218e01012500c00500613611c137126006012039", + "0x12600601203911c13712600601235d01012500c00500613611c137126006", + "0x11c13712600601203911c13712600601243f01012500c00500613611c137", + "0x613611c13712600601203911c13712600601254101012500c005006136", + "0xc00500613611c13712600601203911c13712600601263101012500c005", + "0x1012500c00500613611c13712600601203911c137126006012728010125", + "0x127e801012500c00500613611c13712600601203911c1371260060127e7", + "0x1260060127e901012500c00500613611c13712600601203911c137126006", + "0x11c1371260060127ea01012500c00500613611c13712600601203911c137", + "0x12601003911c1371260107eb01012500c00500613611c137126006012039", + "0x500613611c13712601003911c1371260107ec12500c00500613611c137", + "0x613611c1370f10ef12600601903911c1370f10ef1260060197ed12500c", + "0xf10ef12600601903911c1370f10ef1260060197ee01d01201012500c005", + "0x12601d03911c1370f10ef12601d7ef01d01201012500c00500613611c137", + "0x1d03911c1370f10ef12601d7f001201012500c00500613611c1370f10ef", + "0x1203911c1370f11260127f101201012500c00500613611c1370f10ef126", + "0x12600601203911c1371260060127f201012500c00500613611c1370f1126", + "0x613611c13712601003911c1371260107f301012500c00500613611c137", + "0x127f512500c00500613611c13712601003911c1371260107f412500c005", + "0x1260060127f601012500c00500613611c13712600601203911c137126006", + "0x3a03900c0390057f701012500c00500613611c13712600601203911c137", + "0x1012500c00500613611c00613712601201710111c00613712601d7f8006", + "0x391371261257fa12500c00500613e13712612501a0391371260107f9012", + "0x613712601203901710111c0061371260197fb00c005006142137126125", + "0x7fd00500614703912612503912600c7fc01d01201012500c00500614311c", + "0x1201012500c00500614911c00613712601201706510111c006137126019", + "0x1201706510111c0061371260197ff00500602501a00c01a02600c7fe01d", + "0x6510111c00613712601980001d01201012500c00500614311c006137126", + "0x11c00613712601980101d01201012500c00500614311c006137126012017", + "0x13712601980201d01201012500c00500614911c006137126012065017101", + "0x1980301d01201012500c00500614311c00613712601206501710111c006", + "0x1d01201012500c00500614311c00613712601206501710111c006137126", + "0x12601207b10111c00613712601d80500500614c03912612503912600c804", + "0x12601201710111c00613712601d80601201012500c00500614311c006137", + "0x80800500602501a00c01a07b00c80701201012500c00500614d11c006137", + "0x1201012500c00500614f11c00613712601207b01710111c006137126019", + "0x1207b06510111c00613712601980a00500602501a00c01a06500c80901d", + "0x12601010111c13712601080b01d01201012500c00500615111c006137126", + "0x80d00c00500615513712612503913712612580c12500c00500615311c137", + "0xc01712600c80e01012500c00500615711c13712503901a10111c137012", + "0x13712602181000c00500616113712612503913712612580f00500615f126", + "0x500614311c0f10060ef13712601904003901003901710111c0f10060ef", + "0x1710111c0f10060ef1371261e98110201e901e01a01901d01201012500c", + "0x1e01a01901d01201012500c00500614311c0f10060ef137126019040039", + "0x1003901710111c0f10ef13712602081300500616912600c01712600c812", + "0x1e901e01a01901d01201012500c00500613611c0f10ef13712601d040076", + "0x4007603903a01710111c0f10ef13712602081500616e03900c039005814", + "0x108161e901e01a01901d01201012500c00500616f11c0f10ef13712601d", + "0x1710111c0f113712601d81712500c00500613e13712612501a0e9137126", + "0x6510111c00613712601d81801201012500c00500613611c0f1137126012", + "0x12601010111c13712601081901201012500c00500614311c006137126012", + "0x500614d11c13712601010111c13712601081a12500c00500617311c137", + "0x12500c00500614311c00613712601207b10111c00613712601d81b12500c", + "0xc00500614311c00613712601207b06510111c00613712601981c012010", + "0x500617611c0061371260120170df11c00613712601d81d01d012010125", + "0x17911c00613712601210101a01701711c00613712601a81e01201012500c", + "0x500613e13712612501a03913712601081f01901d01201012500c005006", + "0xc82101012500c00500615513712612501701a03913712601282012500c", + "0x1371260120170170df11c00613712601982200500617311c13712511c137", + "0x13712601009010111c13712601282301d01201012500c00500618011c006", + "0x61371260120170df03911c00613712601982401012500c00500614311c", + "0x1371260121840db11c00613712601d82501d01201012500c00500618211c", + "0x1982700500602501a00c01a01700c82601201012500c00500614911c006", + "0x1d01201012500c00500618711c0061371260120261840db11c006137126", + "0x12601d82901012500c00500614311c13712601009510111c137126012828", + "0x12601982a01201012500c00500614911c0061371260121840d711c006137", + "0x82b01d01201012500c00500618911c0061371260120261840d711c006137", + "0x13712601982c01012500c00500614311c13712601009410111c137126012", + "0x12612582d01d01201012500c00500613611c13712601003901707b10111c", + "0x61371260120170cf11c00613712601d82e00c00500618e12600c076035", + "0x13712601207b0170cf11c00613712601982f01201012500c00500614d11c", + "0x13712601009110111c13712601283001d01201012500c00500619511c006", + "0x500614d11c1371260100a611c13712601083101012500c00500614311c", + "0x500615711c13712507b19c11c13701083300619b00519900583212500c", + "0x83501012500c00500614311c13712601008d10111c13712601283412500c", + "0x1201012500c00500615711c00613712601206501710111c006137126019", + "0x1083701012500c00500614311c13712601008e10111c13712601283601d", + "0x12600c07607612612583812500c0050061a311c1371260100c411c137126", + "0x583a12500c0050061a511c1371250760c411c13701083900c0050061a3", + "0x1012500c0050061aa13712612501703d03913712601283b0061570051a7", + "0xef1371261e983d12500c0050061760f11371260100390f113712601083c", + "0x1201012500c00500615711c0f10ef13712601d04003901001701711c0f1", + "0x12500c00500614311c13712601009210111c13712601283e01e01a01901d", + "0x12601d84001012500c0050061ac13712612501a04007613712601283f010", + "0x12601284101201012500c00500615711c0f113712601201701711c0f1137", + "0xf10ef1371261e984201012500c00500614311c13712601009310111c137", + "0x1d01201012500c00500613611c0f10ef13712601d04007601001701711c", + "0x761b201711c0f10ef13712601e8440061b003900c03900584301e01a019", + "0x12601084501a01901d01201012500c00500616f11c0f10ef13712601d040", + "0x121b201711c0f113712601d84612500c00500613e13712612501a055137", + "0x1371260100b411c13712601084701201012500c00500613611c0f1137126", + "0x12500c0050061b611c1371250670b411c13701084812500c0050061b411c", + "0x13700c84a01012500c00500614311c13712601009610111c137126012849", + "0x8f10111c13712601284c0061570051a700584b0050061b911c13712511c", + "0x1bc11c13712507b0a611c13701084d01012500c00500614311c137126010", + "0x10111c13712601284f00500617311c13712511c13700c84e12500c005006", + "0x61261250170df00612601085001012500c00500614311c13712601008c", + "0x61bd11c13712511c13700c8520061760051be00585112500c00500605d", + "0x50061ab13712612501a01a1b51371260128540061b5005090005853005", + "0x1a800585612500c00500605d0061261251840db00612601085501012500c", + "0x605d0061261251840d70061260108580061b5005095005857006149005", + "0x12601003901707b06711c13712601985a0061b500509400585912500c005", + "0x5d0061261250170cf00612601085b01d01201012500c00500613611c137", + "0x85e00614d0051a400585d00500614c12600c01712600c85c12500c005006", + "0x8e0058610061b500508d0058600061360051a200585f0061b5005091005", + "0x12601d8640050061a30050171a000c8630061a30051a10058620061b5005", + "0x1371261e986501201012500c00500619a0f113712601003919d1390f1137", + "0x1012500c00500615711c0f10ef13712601d04003901003907611c0f10ef", + "0x1701707611c0f11371260198670061b500509200586601e01a01901d012", + "0x8690061b500509300586801d01201012500c00500615711c0f1137126012", + "0x500613611c0f10ef13712601d04007601003907611c0f10ef1371261e9", + "0x1d04007603901711c0f10ef13712601e86a01e01a01901d01201012500c", + "0x5513712601086b01a01901d01201012500c00500619611c0f10ef137126", + "0x12601201701707611c0f113712601986c12500c00500613e13712612501a", + "0x1b201707611c0f113712601986d01d01201012500c00500618d11c0f1137", + "0x5d07611c13712601286e01d01201012500c00500613611c0f1137126012", + "0x11c1370128700061b400506900586f01012500c00500618a11c137126010", + "0xc8720061b500509600587101012500c0050061a711c13712506705d076", + "0x58750061b500508c0058740061b500508f0058730050061570050171a7", + "0x1a08d12587700c00500602501a01a12501a01a08c1258760061bd005185", + "0xc00500602501a01a12501a01a08e12587800c00500602501a01a12501a", + "0x12501a01a09013712601287a00c00500602501a01a12501a01a08f125879", + "0xc00500602501a01a12501a01a09112587b01012500c0050061ab137126", + "0x13712601287d01012500c0050061ab13712612501a01a09213712601287c", + "0x1a01a12501a01a09412587e01012500c0050061ab13712612501a01a093", + "0x1a09612588000c00500602501a01a12501a01a09512587f00c005006025", + "0xef13712601004003901a0ef13712601d88100c00500602501a01a12501a", + "0x11c13712601001005d07601a11c13712601988201201012500c00500617a", + "0x13712601201701707611c0f113712601988301d01201012500c005006178", + "0x13712601d88500603900501700588401d01201012500c00500614911c0f1", + "0x1701700c88601201012500c00500617611c0f113712601203907611c0f1", + "0x615711c0f113712601201703907611c0f1137126019887005006039005", + "0x7611c13712601a88900500603900501701700c88801d01201012500c005", + "0x12601d88a01901d01201012500c00500617811c13712601005d07601a010", + "0x1371261e988b01201012500c00500617a0ef13712601004003901a0ef137", + "0x1012500c00500617411c0f10ef13712601d07604001705103911c0f10ef", + "0x1711c0f11371261e988d00500603900501701700c88c01e01a01901d012", + "0x1a01901d01201012500c00500617911c0f113712601201a076017017017", + "0x500613e11c0f113712601201a01707601701711c0f113712601e88e01e", + "0x12601201707601a01701711c0f113712601e88f01a01901d01201012500c", + "0x14712600c01712600c89001a01901d01201012500c00500617911c0f1137", + "0xc00500616d0ef13712601001001704001a0390ef13712601a891005006", + "0x13712601a89300c00500616812600c01001012612589201901d012010125", + "0x89401901d01201012500c0050061620ef13712601001001703901a0400ef", + "0x1001a0100170100170ef13712601a89500c005006039005017017017125", + "0x500616800501715000c89601901d01201012500c0050061520ef137126", + "0x1201012500c00500614b0ef1371260100100170390100ef137126019897", + "0xc89a00601000501000589900c00500616812600c01001012612589801d", + "0xc00500614813712612501002013712601089b00500602012600c017126", + "0x500614812600c02002012612589d00500603a12600c02012600c89c125", + "0x2013712601089f12500c00500614813712612501002013712601089e00c", + "0xc00500614812600c0200201261258a012500c005006148137126125010", + "0x614812600c0200201261258a200c00500614112600c0200201261258a1", + "0x12600c0100101261258a400c00500616812600c0100101261258a300c005", + "0x200201261258a600c00500614112600c0200201261258a500c005006168", + "0x602512600c20712600c8a800613b0050200058a700c00500613d12600c", + "0x58ab00c00500613d12600c0200201261258aa00620a0050100058a9005", + "0x50100058ae00602d0050200058ad0061e90050100058ac00620d005020", + "0x8af006028" + ], + "sierra_program_debug_info": { + "type_names": [ + [0, "Pedersen"], + [1, "Uninitialized"], + [2, "u128"], + [3, "Tuple"], + [4, "u8"], + [5, "NonZero"], + [6, "Tuple>"], + [7, "core::panics::Panic"], + [8, "Array"], + [9, "Tuple>"], + [ + 10, + "core::panics::PanicResult::<(core::zeroable::NonZero::,)>" + ], + [11, "core::integer::u256"], + [12, "NonZero"], + [13, "Tuple>"], + [ + 14, + "core::panics::PanicResult::<(core::zeroable::NonZero::,)>" + ], + [15, "Unit"], + [16, "core::bool"], + [17, "Tuple"], + [18, "core::option::Option::>"], + [ + 19, + "Tuple>>" + ], + [ + 20, + "core::panics::PanicResult::<(core::option::Option::>,)>" + ], + [21, "Tuple"], + [22, "U128MulGuarantee"], + [ + 23, + "core::option::Option::>" + ], + [ + 24, + "Tuple>>" + ], + [ + 25, + "core::panics::PanicResult::<(core::option::Option::>,)>" + ], + [26, "Tuple"], + [27, "core::option::Option::"], + [28, "Tuple"], + [29, "Uninitialized>"], + [30, "core::panics::PanicResult::<(core::integer::u256,)>"], + [31, "Uninitialized"], + [32, "Snapshot>"], + [33, "core::array::Span::"], + [34, "felt252"], + [35, "core::option::Option::"], + [ + 36, + "Tuple, felt252, u8, core::option::Option::>" + ], + [ + 37, + "core::panics::PanicResult::<(core::array::Span::, core::felt252, core::integer::u8, core::option::Option::)>" + ], + [38, "Array"], + [39, "Snapshot>"], + [40, "core::array::Span::"], + [41, "Uninitialized>"], + [42, "core::result::Result::"], + [43, "Tuple, Unit>"], + [ + 44, + "core::panics::PanicResult::<(core::felt252, core::integer::u8, core::array::Array::, ())>" + ], + [45, "Box"], + [46, "core::option::Option::>"], + [47, "Uninitialized>>"], + [ + 48, + "Tuple, core::array::Span::, felt252, u8, Array, Unit>" + ], + [ + 49, + "core::panics::PanicResult::<(core::array::Span::, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>" + ], + [50, "Tuple"], + [51, "core::panics::PanicResult::<(core::integer::u8,)>"], + [ + 52, + "Tuple, core::array::Span::, felt252, u8, Array, Unit>" + ], + [ + 53, + "core::panics::PanicResult::<(core::array::Span::, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>" + ], + [54, "Box>"], + [ + 55, + "core::option::Option::>>" + ], + [56, "Array>"], + [57, "Snapshot>>"], + [58, "Uninitialized>>>"], + [59, "core::array::Span::>"], + [ + 60, + "Tuple, Array>, core::array::Span::>>" + ], + [ + 61, + "core::panics::PanicResult::<(core::array::Span::, core::array::Array::>, core::array::Span::>)>" + ], + [62, "Tuple, u8, Unit>"], + [ + 63, + "core::panics::PanicResult::<(core::array::Array::, core::integer::u8, ())>" + ], + [ + 64, + "Tuple, core::array::Span::, core::array::Span::, Unit>" + ], + [ + 65, + "core::panics::PanicResult::<(core::array::Array::, core::array::Span::, core::array::Span::, ())>" + ], + [66, "StorageBaseAddress"], + [67, "Uninitialized"], + [68, "core::poseidon::HashState"], + [69, "Box"], + [ + 70, + "core::result::Result::, core::array::Array::>" + ], + [71, "core::pedersen::HashState"], + [72, "ContractAddress"], + [73, "dojo::executor::IExecutorDispatcher"], + [ + 74, + "core::result::Result::>" + ], + [ + 75, + "Tuple>>" + ], + [ + 76, + "core::panics::PanicResult::<(core::result::Result::>,)>" + ], + [77, "Tuple>"], + [78, "core::panics::PanicResult::<(core::array::Array::,)>"], + [79, "dojo::database::index::WhereCondition"], + [80, "Tuple>>"], + [ + 81, + "core::panics::PanicResult::<(core::array::Span::>,)>" + ], + [82, "Tuple, felt252>"], + [ + 83, + "core::panics::PanicResult::<(core::array::Span::, core::felt252)>" + ], + [84, "Tuple"], + [85, "u32"], + [86, "core::result::Result::"], + [ + 87, + "core::result::Result::>" + ], + [ + 88, + "core::result::Result::, core::array::Array::>" + ], + [89, "ClassHash"], + [ + 90, + "core::result::Result::>" + ], + [ + 91, + "core::result::Result::>" + ], + [92, "Tuple, Array, Unit>"], + [ + 93, + "core::panics::PanicResult::<(core::array::Array::, core::array::Array::, ())>" + ], + [94, "dojo::world::world::WorldSpawned"], + [95, "dojo::world::world::ContractDeployed"], + [96, "dojo::world::world::ContractUpgraded"], + [97, "dojo::world::world::WorldUpgraded"], + [98, "dojo::world::world::MetadataUpdate"], + [99, "dojo::world::world::ModelRegistered"], + [100, "dojo::world::world::StoreSetRecord"], + [101, "dojo::world::world::StoreDelRecord"], + [102, "dojo::world::world::WriterUpdated"], + [103, "dojo::world::world::OwnerUpdated"], + [104, "dojo::world::world::ExecutorUpdated"], + [105, "dojo::world::world::Event"], + [106, "Box"], + [107, "Box"], + [108, "core::starknet::info::v2::ExecutionInfo"], + [109, "u64"], + [110, "core::starknet::info::BlockInfo"], + [111, "Tuple>"], + [ + 112, + "core::panics::PanicResult::<(core::box::Box::,)>" + ], + [ + 113, + "core::result::Result::>" + ], + [114, "StorageAddress"], + [115, "dojo::world::world::contract_base::ContractMemberState"], + [116, "Tuple"], + [ + 117, + "core::panics::PanicResult::<(dojo::world::world::contract_base::ContractMemberState, ())>" + ], + [118, "Array"], + [119, "Snapshot>"], + [120, "core::array::Span::"], + [121, "core::starknet::info::v2::ResourceBounds"], + [122, "core::starknet::info::v2::TxInfo"], + [123, "Tuple>"], + [ + 124, + "core::panics::PanicResult::<(core::box::Box::,)>" + ], + [125, "dojo::world::world::executor_dispatcher::ContractMemberState"], + [ + 126, + "Tuple" + ], + [ + 127, + "core::panics::PanicResult::<(dojo::world::world::executor_dispatcher::ContractMemberState, ())>" + ], + [128, "Tuple"], + [129, "core::panics::PanicResult::<(dojo::executor::IExecutorDispatcher,)>"], + [130, "core::option::Option::"], + [131, "core::option::Option::<()>"], + [132, "Tuple, u32, Unit>"], + [ + 133, + "core::panics::PanicResult::<(core::array::Array::, core::integer::u32, ())>" + ], + [134, "Uninitialized, u32, Unit>>"], + [135, "core::option::Option::>"], + [ + 136, + "Tuple, core::option::Option::>>" + ], + [ + 137, + "core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>" + ], + [138, "core::result::Result::<(), core::array::Array::>"], + [139, "dojo::world::world::nonce::ContractMemberState"], + [140, "Tuple"], + [ + 141, + "core::panics::PanicResult::<(dojo::world::world::nonce::ContractMemberState, ())>" + ], + [142, "Tuple"], + [143, "core::panics::PanicResult::<(core::integer::u32,)>"], + [144, "dojo::components::upgradeable::IUpgradeableDispatcher"], + [145, "Tuple>"], + [146, "Tuple>>"], + [ + 147, + "core::panics::PanicResult::<((core::starknet::contract_address::ContractAddress, core::array::Span::),)>" + ], + [ + 148, + "core::result::Result::<(core::starknet::contract_address::ContractAddress, core::array::Span::), core::array::Array::>" + ], + [149, "Uninitialized"], + [150, "dojo::world::world::models::ContractMemberState"], + [151, "Tuple"], + [ + 152, + "core::panics::PanicResult::<(dojo::world::world::models::ContractMemberState, ())>" + ], + [153, "NonZero"], + [154, "Box"], + [155, "Tuple>"], + [156, "core::panics::PanicResult::<(core::box::Box::<@core::felt252>,)>"], + [157, "Tuple"], + [158, "Uninitialized>"], + [159, "dojo::world::world::writers::ContractMemberState"], + [160, "Tuple"], + [ + 161, + "core::panics::PanicResult::<(dojo::world::world::writers::ContractMemberState, ())>" + ], + [162, "dojo::world::world::owners::ContractMemberState"], + [163, "Tuple"], + [ + 164, + "core::panics::PanicResult::<(dojo::world::world::owners::ContractMemberState, ())>" + ], + [165, "Tuple"], + [166, "dojo::world::world::metadata_uri::ContractMemberState"], + [ + 167, + "Tuple, dojo::world::world::metadata_uri::ContractMemberState, felt252, Unit>" + ], + [ + 168, + "core::panics::PanicResult::<(core::array::Span::, dojo::world::world::metadata_uri::ContractMemberState, core::felt252, ())>" + ], + [169, "Tuple"], + [ + 170, + "core::panics::PanicResult::<(dojo::world::world::metadata_uri::ContractMemberState, ())>" + ], + [171, "Tuple, felt252, Unit>"], + [ + 172, + "core::panics::PanicResult::<(core::array::Array::, core::felt252, ())>" + ], + [173, "Tuple"], + [174, "core::panics::PanicResult::<(core::felt252,)>"], + [ + 175, + "core::panics::PanicResult::<(core::starknet::contract_address::ContractAddress,)>" + ], + [ + 176, + "Tuple, core::array::Span::>>" + ], + [ + 177, + "Tuple, core::array::Span::>>>" + ], + [ + 178, + "core::panics::PanicResult::<((core::array::Span::, core::array::Span::>),)>" + ], + [179, "core::option::Option::>"], + [180, "Uninitialized>"], + [181, "core::option::Option::"], + [182, "Uninitialized"], + [183, "Bitwise"], + [184, "Uninitialized"], + [185, "Poseidon"], + [186, "Uninitialized"], + [187, "core::option::Option::>"], + [ + 188, + "Tuple, core::option::Option::>>" + ], + [ + 189, + "core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>" + ], + [190, "core::option::Option::"], + [191, "core::option::Option::>"], + [192, "Uninitialized"], + [193, "Uninitialized>"], + [194, "Tuple"], + [195, "core::panics::PanicResult::<((),)>"], + [196, "core::option::Option::>"], + [ + 197, + "Tuple, core::option::Option::>>" + ], + [ + 198, + "core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>" + ], + [199, "Uninitialized>"], + [200, "dojo::world::world::ContractState"], + [201, "Tuple"], + [ + 202, + "core::panics::PanicResult::<(dojo::world::world::ContractState, core::integer::u32)>" + ], + [203, "Tuple"], + [ + 204, + "core::panics::PanicResult::<(dojo::world::world::ContractState, core::starknet::class_hash::ClassHash)>" + ], + [205, "Tuple"], + [ + 206, + "core::panics::PanicResult::<(dojo::world::world::ContractState, core::starknet::contract_address::ContractAddress)>" + ], + [207, "Tuple"], + [ + 208, + "core::panics::PanicResult::<(core::starknet::class_hash::ClassHash,)>" + ], + [209, "core::option::Option::"], + [210, "Tuple"], + [211, "core::panics::PanicResult::<(core::bool,)>"], + [ + 212, + "core::option::Option::" + ], + [213, "Tuple"], + [214, "core::panics::PanicResult::<(dojo::world::world::ContractState, ())>"], + [215, "core::option::Option::>"], + [ + 216, + "Tuple, core::option::Option::>>" + ], + [ + 217, + "core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>" + ], + [218, "Uninitialized"], + [219, "Tuple, Unit>"], + [ + 220, + "core::panics::PanicResult::<(core::array::Array::, ())>" + ], + [221, "Tuple>"], + [222, "BuiltinCosts"], + [223, "System"], + [224, "core::panics::PanicResult::<(core::array::Span::,)>"], + [225, "GasBuiltin"], + [226, "RangeCheck"], + [227, "Uninitialized"] + ], + "libfunc_names": [ + [0, "alloc_local"], + [1, "alloc_local"], + [2, "finalize_locals"], + [3, "revoke_ap_tracking"], + [4, "withdraw_gas"], + [5, "branch_align"], + [6, "store_temp>"], + [7, "function_call"], + [8, "store_temp"], + [9, "enum_match>"], + [10, "struct_deconstruct>"], + [11, "array_len"], + [12, "snapshot_take"], + [13, "drop"], + [14, "u32_const<0>"], + [15, "rename"], + [16, "store_temp"], + [17, "u32_eq"], + [18, "drop>"], + [19, "drop>"], + [20, "drop"], + [21, "array_new"], + [ + 22, + "felt252_const<7733229381460288120802334208475838166080759535023995805565484692595>" + ], + [23, "store_temp"], + [24, "array_append"], + [25, "struct_construct"], + [26, "struct_construct>>"], + [ + 27, + "enum_init,)>, 1>" + ], + [28, "store_temp"], + [29, "store_temp"], + [30, "store_temp"], + [ + 31, + "store_temp,)>>" + ], + [32, "get_builtin_costs"], + [33, "store_temp"], + [34, "withdraw_gas_all"], + [ + 35, + "struct_construct" + ], + [ + 36, + "struct_construct" + ], + [37, "struct_construct"], + [ + 38, + "struct_construct" + ], + [39, "struct_construct"], + [40, "struct_construct"], + [41, "struct_construct"], + [42, "struct_construct"], + [43, "snapshot_take"], + [44, "drop"], + [45, "function_call"], + [46, "store_local"], + [47, "store_local"], + [ + 48, + "enum_match,)>>" + ], + [49, "struct_deconstruct>>"], + [50, "snapshot_take>"], + [51, "drop>"], + [52, "store_temp>"], + [ + 53, + "function_call::serialize>" + ], + [ + 54, + "enum_match, ())>>" + ], + [55, "struct_deconstruct, Unit>>"], + [56, "drop"], + [57, "snapshot_take>"], + [58, "drop>"], + [59, "struct_construct>"], + [60, "struct_construct>>"], + [ + 61, + "enum_init,)>, 0>" + ], + [62, "felt252_const<375233589013918064796019>"], + [ + 63, + "felt252_const<485748461484230571791265682659113160264223489397539653310998840191492913>" + ], + [64, "alloc_local"], + [65, "store_local"], + [ + 66, + "function_call::deserialize>" + ], + [ + 67, + "enum_match, core::option::Option::>)>>" + ], + [ + 68, + "struct_deconstruct, core::option::Option::>>>" + ], + [ + 69, + "enum_match>>" + ], + [70, "function_call"], + [ + 71, + "enum_match>" + ], + [72, "drop>"], + [ + 73, + "felt252_const<485748461484230571791265682659113160264223489397539653310998840191492914>" + ], + [74, "drop>"], + [ + 75, + "function_call" + ], + [ + 76, + "enum_match>" + ], + [77, "drop"], + [78, "store_temp"], + [79, "function_call"], + [80, "enum_match>"], + [81, "struct_deconstruct>"], + [82, "snapshot_take"], + [83, "drop"], + [84, "store_temp"], + [85, "function_call"], + [86, "function_call"], + [87, "function_call"], + [88, "function_call"], + [89, "function_call"], + [90, "function_call"], + [ + 91, + "function_call" + ], + [ + 92, + "enum_match>" + ], + [93, "drop"], + [94, "store_temp"], + [95, "function_call"], + [96, "function_call"], + [ + 97, + "enum_match>" + ], + [98, "struct_deconstruct>"], + [99, "snapshot_take"], + [ + 100, + "function_call" + ], + [101, "function_call"], + [ + 102, + "enum_match>" + ], + [ + 103, + "struct_deconstruct>" + ], + [104, "snapshot_take"], + [ + 105, + "function_call" + ], + [106, "function_call"], + [ + 107, + "enum_match>" + ], + [ + 108, + "struct_deconstruct>" + ], + [109, "function_call"], + [ + 110, + "enum_match>" + ], + [111, "struct_deconstruct>"], + [112, "u32_to_felt252"], + [113, "alloc_local>"], + [ + 114, + "function_call::deserialize>" + ], + [ + 115, + "enum_match, core::option::Option::>)>>" + ], + [ + 116, + "struct_deconstruct, core::option::Option::>>>" + ], + [ + 117, + "enum_match>>" + ], + [118, "store_local>"], + [119, "function_call"], + [120, "enum_match>"], + [121, "drop>"], + [122, "drop>>"], + [123, "alloc_local>"], + [124, "alloc_local"], + [125, "enable_ap_tracking"], + [126, "store_local>"], + [127, "array_snapshot_pop_front"], + [ + 128, + "enum_init>, 0>" + ], + [129, "store_temp>>"], + [130, "store_temp>>"], + [131, "jump"], + [132, "struct_construct"], + [ + 133, + "enum_init>, 1>" + ], + [134, "enum_match>>"], + [135, "unbox"], + [136, "rename"], + [137, "function_call"], + [138, "enum_match>"], + [139, "disable_ap_tracking"], + [140, "store_local"], + [ + 141, + "function_call, core::integer::u8Drop>::deserialize>" + ], + [ + 142, + "enum_match, core::option::Option::>)>>" + ], + [ + 143, + "struct_deconstruct, core::option::Option::>>>" + ], + [ + 144, + "enum_match>>" + ], + [145, "drop>"], + [146, "drop"], + [147, "store_temp"], + [148, "store_temp"], + [149, "store_temp"], + [150, "store_temp>"], + [151, "function_call"], + [ + 152, + "felt252_const<485748461484230571791265682659113160264223489397539653310998840191492917>" + ], + [153, "drop>>"], + [ + 154, + "felt252_const<485748461484230571791265682659113160264223489397539653310998840191492916>" + ], + [155, "drop>>"], + [156, "drop>"], + [ + 157, + "felt252_const<485748461484230571791265682659113160264223489397539653310998840191492915>" + ], + [158, "function_call"], + [159, "alloc_local"], + [160, "alloc_local"], + [161, "alloc_local"], + [162, "function_call"], + [163, "enum_match>"], + [164, "store_local"], + [165, "drop>"], + [166, "drop>"], + [167, "function_call"], + [168, "store_local"], + [169, "store_local"], + [170, "drop>"], + [171, "alloc_local>"], + [ + 172, + "function_call>::deserialize>" + ], + [ + 173, + "enum_match>>" + ], + [174, "store_local>"], + [175, "drop>"], + [176, "store_temp>"], + [177, "function_call"], + [ + 178, + "enum_match, core::array::Span::>),)>>" + ], + [ + 179, + "struct_deconstruct, core::array::Span::>>>>" + ], + [ + 180, + "snapshot_take, core::array::Span::>>>" + ], + [ + 181, + "drop, core::array::Span::>>>" + ], + [ + 182, + "store_temp, core::array::Span::>>>" + ], + [ + 183, + "function_call, core::array::Span::>, core::array::SpanSerde::, core::array::SpanDrop::, core::array::SpanSerde::, core::array::SpanSerde::, core::array::SpanDrop::>, core::array::SpanDrop::>>::serialize>" + ], + [184, "drop>>"], + [185, "function_call"], + [186, "function_call"], + [187, "function_call"], + [ + 188, + "enum_match>" + ], + [189, "struct_deconstruct>"], + [190, "function_call"], + [191, "function_call"], + [192, "function_call"], + [193, "enum_init, 0>"], + [194, "enum_init, 1>"], + [195, "dup"], + [196, "struct_deconstruct"], + [197, "drop"], + [198, "drop"], + [199, "drop"], + [200, "drop"], + [201, "drop"], + [202, "drop"], + [203, "dup"], + [ + 204, + "function_call" + ], + [205, "enum_match>"], + [206, "struct_deconstruct>"], + [207, "felt252_const<1>"], + [208, "felt252_add"], + [209, "function_call"], + [ + 210, + "enum_match, core::felt252, ())>>" + ], + [211, "struct_deconstruct, felt252, Unit>>"], + [212, "dup>"], + [213, "rename>"], + [ + 214, + "function_call>" + ], + [215, "struct_construct, Unit>>"], + [ + 216, + "enum_init, ())>, 0>" + ], + [ + 217, + "store_temp, ())>>" + ], + [ + 218, + "enum_init, ())>, 1>" + ], + [ + 219, + "function_call>" + ], + [ + 220, + "enum_init>, 0>" + ], + [ + 221, + "struct_construct, core::option::Option::>>>" + ], + [ + 222, + "enum_init, core::option::Option::>)>, 0>" + ], + [ + 223, + "store_temp, core::option::Option::>)>>" + ], + [ + 224, + "enum_init>, 1>" + ], + [ + 225, + "enum_init, core::option::Option::>)>, 1>" + ], + [226, "function_call"], + [227, "enum_match"], + [228, "felt252_const<2037172927806676297074>"], + [ + 229, + "enum_init, 1>" + ], + [ + 230, + "store_temp>" + ], + [231, "u32_const<255>"], + [232, "dup"], + [233, "u32_overflowing_sub"], + [234, "felt252_const<37225634303738867606330471607143733620327>"], + [ + 235, + "function_call" + ], + [ + 236, + "enum_match>" + ], + [ + 237, + "struct_deconstruct>" + ], + [238, "struct_construct"], + [239, "store_temp"], + [ + 240, + "function_call>" + ], + [241, "struct_deconstruct>"], + [ + 242, + "function_call" + ], + [ + 243, + "enum_match, dojo::world::world::metadata_uri::ContractMemberState, core::felt252, ())>>" + ], + [ + 244, + "struct_deconstruct, dojo::world::world::metadata_uri::ContractMemberState, felt252, Unit>>" + ], + [245, "struct_construct>"], + [ + 246, + "enum_init, 0>" + ], + [247, "contract_address_try_from_felt252"], + [ + 248, + "enum_init, 0>" + ], + [ + 249, + "store_temp>" + ], + [ + 250, + "enum_init, 1>" + ], + [251, "drop"], + [252, "struct_construct>"], + [253, "store_temp>"], + [ + 254, + "function_call" + ], + [255, "struct_construct>"], + [256, "enum_init, 0>"], + [257, "store_temp>"], + [258, "enum_init, 1>"], + [259, "rename"], + [260, "felt252_const<0>"], + [261, "snapshot_take"], + [262, "function_call"], + [263, "dup"], + [264, "rename"], + [265, "enum_init"], + [ + 266, + "function_call" + ], + [ + 267, + "enum_match>" + ], + [ + 268, + "struct_deconstruct>" + ], + [269, "struct_construct"], + [270, "store_temp"], + [ + 271, + "function_call>" + ], + [272, "enum_init"], + [ + 273, + "function_call" + ], + [274, "felt252_const<2462790951445419931459807638768526940903335282>"], + [ + 275, + "function_call" + ], + [ + 276, + "enum_match>" + ], + [ + 277, + "struct_deconstruct>" + ], + [278, "struct_construct"], + [279, "store_temp"], + [ + 280, + "function_call>" + ], + [281, "class_hash_try_from_felt252"], + [ + 282, + "enum_init, 0>" + ], + [ + 283, + "store_temp>" + ], + [ + 284, + "enum_init, 1>" + ], + [285, "alloc_local>"], + [ + 286, + "felt252_const<1528802474226268325865027367859591458315299653151958663884057507666229546336>" + ], + [287, "dup"], + [288, "store_local>"], + [289, "function_call"], + [290, "rename>>"], + [291, "function_call>"], + [ + 292, + "enum_match,)>>" + ], + [293, "struct_deconstruct>>"], + [294, "class_hash_const<0>"], + [295, "snapshot_take"], + [ + 296, + "function_call" + ], + [297, "rename"], + [298, "class_hash_to_felt252"], + [299, "felt252_sub"], + [300, "felt252_is_zero"], + [301, "drop>"], + [302, "felt252_const<162857089760626085489994535756020441209910069392485>"], + [ + 303, + "function_call" + ], + [ + 304, + "enum_match>" + ], + [ + 305, + "struct_deconstruct>" + ], + [306, "struct_construct"], + [307, "store_temp"], + [ + 308, + "function_call>" + ], + [309, "drop>"], + [310, "drop>>"], + [311, "struct_construct>"], + [ + 312, + "enum_init, 0>" + ], + [ + 313, + "store_temp>" + ], + [ + 314, + "enum_init, 1>" + ], + [315, "alloc_local"], + [ + 316, + "snapshot_take" + ], + [ + 317, + "function_call" + ], + [318, "deploy_syscall"], + [ + 319, + "struct_construct>>" + ], + [ + 320, + "enum_init), core::array::Array::>, 0>" + ], + [ + 321, + "store_temp), core::array::Array::>>" + ], + [ + 322, + "enum_init), core::array::Array::>, 1>" + ], + [ + 323, + "function_call)>::unwrap_syscall>" + ], + [ + 324, + "enum_match),)>>" + ], + [ + 325, + "struct_deconstruct>>>" + ], + [ + 326, + "struct_deconstruct>>" + ], + [327, "store_local"], + [ + 328, + "struct_construct" + ], + [329, "store_temp"], + [ + 330, + "function_call" + ], + [331, "contract_address_to_felt252"], + [332, "struct_construct"], + [333, "store_temp"], + [ + 334, + "function_call>" + ], + [ + 335, + "struct_construct>" + ], + [ + 336, + "enum_init, 0>" + ], + [ + 337, + "store_temp>" + ], + [ + 338, + "enum_init, 1>" + ], + [339, "drop>"], + [340, "rename"], + [341, "function_call"], + [342, "struct_construct"], + [343, "store_temp"], + [ + 344, + "function_call>" + ], + [ + 345, + "struct_construct>" + ], + [ + 346, + "enum_init, 0>" + ], + [ + 347, + "store_temp>" + ], + [ + 348, + "enum_init, 1>" + ], + [349, "snapshot_take"], + [ + 350, + "function_call" + ], + [351, "enum_match>"], + [352, "struct_deconstruct>"], + [353, "u32_const<1>"], + [354, "function_call"], + [ + 355, + "function_call" + ], + [ + 356, + "enum_match>" + ], + [ + 357, + "struct_deconstruct>" + ], + [358, "struct_construct>"], + [ + 359, + "enum_init, 0>" + ], + [ + 360, + "store_temp>" + ], + [ + 361, + "enum_init, 1>" + ], + [ + 362, + "struct_construct, core::option::Option::>>>" + ], + [ + 363, + "enum_init, core::option::Option::>)>, 0>" + ], + [ + 364, + "store_temp, core::option::Option::>)>>" + ], + [ + 365, + "enum_init, core::option::Option::>)>, 1>" + ], + [ + 366, + "enum_init>, 1>" + ], + [367, "emit_event_syscall"], + [ + 368, + "enum_init>, 0>" + ], + [ + 369, + "store_temp>>" + ], + [ + 370, + "enum_init>, 1>" + ], + [ + 371, + "function_call::unwrap_syscall>" + ], + [372, "struct_construct>"], + [373, "enum_init, 0>"], + [374, "store_temp>"], + [375, "enum_init, 1>"], + [376, "u8_try_from_felt252"], + [377, "enum_init, 0>"], + [378, "store_temp>"], + [379, "enum_init, 1>"], + [380, "array_new"], + [381, "store_temp>"], + [ + 382, + "function_call, core::integer::u8Drop>>" + ], + [ + 383, + "enum_match, core::option::Option::>)>>" + ], + [ + 384, + "struct_deconstruct, core::option::Option::>>>" + ], + [ + 385, + "enum_match>>" + ], + [386, "snapshot_take>"], + [387, "drop>"], + [388, "struct_construct>"], + [ + 389, + "enum_init>, 0>" + ], + [ + 390, + "struct_construct, core::option::Option::>>>" + ], + [ + 391, + "enum_init, core::option::Option::>)>, 0>" + ], + [ + 392, + "store_temp, core::option::Option::>)>>" + ], + [ + 393, + "enum_init>, 1>" + ], + [ + 394, + "enum_init, core::option::Option::>)>, 1>" + ], + [395, "function_call"], + [396, "dup"], + [397, "function_call"], + [398, "struct_construct"], + [399, "store_temp"], + [ + 400, + "function_call>" + ], + [401, "alloc_local, u32, Unit>>"], + [402, "drop>"], + [403, "dup>"], + [404, "function_call"], + [ + 405, + "enum_match, core::integer::u32, ())>>" + ], + [406, "store_local, u32, Unit>>"], + [407, "struct_deconstruct, u32, Unit>>"], + [408, "u8_const<0>"], + [409, "function_call"], + [410, "struct_construct"], + [411, "store_temp"], + [ + 412, + "function_call>" + ], + [413, "drop, u32, Unit>>"], + [414, "drop, u32, Unit>>>"], + [415, "u32_try_from_felt252"], + [416, "enum_init, 0>"], + [417, "store_temp>"], + [418, "enum_init, 1>"], + [419, "function_call"], + [ + 420, + "enum_init>, 1>" + ], + [ + 421, + "store_temp>>" + ], + [422, "function_call"], + [423, "enum_match>"], + [ + 424, + "enum_init>, 0>" + ], + [ + 425, + "felt252_const<130898889959276654847086743802419577788145926319445857429975148>" + ], + [ + 426, + "enum_init, core::array::Span::>),)>, 1>" + ], + [ + 427, + "store_temp, core::array::Span::>),)>>" + ], + [ + 428, + "enum_init, 1>" + ], + [ + 429, + "store_temp>" + ], + [430, "function_call"], + [ + 431, + "struct_construct, core::array::Span::>>>>" + ], + [ + 432, + "enum_init, core::array::Span::>),)>, 0>" + ], + [ + 433, + "struct_deconstruct, core::array::Span::>>>" + ], + [434, "store_temp>>"], + [ + 435, + "function_call, core::array::SpanSerde::, core::array::SpanDrop::>::serialize>" + ], + [436, "drop>>"], + [437, "function_call"], + [ + 438, + "felt252_const<45840195547537441139197651602034552346667116566969405886212370290>" + ], + [ + 439, + "snapshot_take" + ], + [ + 440, + "function_call" + ], + [ + 441, + "enum_match>" + ], + [442, "struct_construct"], + [443, "store_temp"], + [ + 444, + "function_call" + ], + [ + 445, + "enum_match>" + ], + [446, "struct_deconstruct>"], + [447, "struct_deconstruct"], + [ + 448, + "struct_deconstruct>" + ], + [449, "struct_construct"], + [450, "store_temp"], + [ + 451, + "function_call>" + ], + [452, "drop>"], + [453, "struct_construct>"], + [ + 454, + "enum_init, 0>" + ], + [ + 455, + "store_temp>" + ], + [ + 456, + "enum_init, 1>" + ], + [457, "bool_not_impl"], + [458, "felt252_const<9184378437951277208742263346930465483354984>"], + [459, "function_call"], + [ + 460, + "enum_match,)>>" + ], + [461, "struct_deconstruct>>"], + [462, "unbox"], + [463, "struct_deconstruct"], + [464, "drop"], + [465, "drop>"], + [466, "felt252_const<41691414978720277885438601153541232949736990933345381>"], + [467, "replace_class_syscall"], + [ + 468, + "function_call>::unwrap::>>" + ], + [469, "struct_construct"], + [470, "store_temp"], + [ + 471, + "function_call>" + ], + [472, "store_temp"], + [ + 473, + "function_call" + ], + [ + 474, + "enum_match>" + ], + [475, "function_call"], + [ + 476, + "struct_deconstruct>" + ], + [477, "struct_construct"], + [478, "store_temp"], + [ + 479, + "function_call>" + ], + [ + 480, + "drop>" + ], + [ + 481, + "drop>" + ], + [482, "drop>"], + [483, "drop"], + [ + 484, + "function_call" + ], + [485, "storage_address_from_base"], + [486, "storage_read_syscall"], + [ + 487, + "enum_init>, 0>" + ], + [ + 488, + "store_temp>>" + ], + [ + 489, + "enum_init>, 1>" + ], + [ + 490, + "function_call::unwrap_syscall>" + ], + [491, "struct_construct>"], + [492, "enum_init, 0>"], + [493, "store_temp>"], + [494, "enum_init, 1>"], + [495, "struct_construct, felt252, Unit>>"], + [ + 496, + "enum_init, core::felt252, ())>, 0>" + ], + [ + 497, + "store_temp, core::felt252, ())>>" + ], + [ + 498, + "enum_init, core::felt252, ())>, 1>" + ], + [ + 499, + "enum_init>, 0>" + ], + [500, "function_call"], + [ + 501, + "enum_match,)>>" + ], + [ + 502, + "struct_deconstruct>>" + ], + [503, "unbox"], + [504, "struct_deconstruct"], + [505, "drop>"], + [506, "drop>"], + [507, "snapshot_take"], + [508, "storage_write_syscall"], + [509, "struct_deconstruct>"], + [ + 510, + "struct_construct>" + ], + [ + 511, + "enum_init, 0>" + ], + [ + 512, + "store_temp>" + ], + [ + 513, + "enum_init, 1>" + ], + [ + 514, + "function_call" + ], + [515, "snapshot_take"], + [516, "drop"], + [517, "store_temp"], + [ + 518, + "function_call" + ], + [ + 519, + "enum_match, core::array::Array::, ())>>" + ], + [520, "struct_deconstruct, Array, Unit>>"], + [ + 521, + "struct_construct, dojo::world::world::metadata_uri::ContractMemberState, felt252, Unit>>" + ], + [ + 522, + "enum_init, dojo::world::world::metadata_uri::ContractMemberState, core::felt252, ())>, 0>" + ], + [ + 523, + "store_temp, dojo::world::world::metadata_uri::ContractMemberState, core::felt252, ())>>" + ], + [ + 524, + "enum_init, dojo::world::world::metadata_uri::ContractMemberState, core::felt252, ())>, 1>" + ], + [ + 525, + "function_call" + ], + [ + 526, + "enum_init>, 0>" + ], + [ + 527, + "store_temp>>" + ], + [ + 528, + "enum_init>, 1>" + ], + [ + 529, + "function_call::unwrap_syscall>" + ], + [530, "snapshot_take"], + [531, "bool_to_felt252"], + [ + 532, + "struct_construct>" + ], + [ + 533, + "enum_init, 0>" + ], + [ + 534, + "store_temp>" + ], + [ + 535, + "enum_init, 1>" + ], + [ + 536, + "function_call" + ], + [ + 537, + "function_call" + ], + [538, "snapshot_take"], + [ + 539, + "struct_construct>" + ], + [ + 540, + "enum_init, 0>" + ], + [ + 541, + "store_temp>" + ], + [ + 542, + "enum_init, 1>" + ], + [ + 543, + "function_call" + ], + [544, "function_call"], + [545, "array_get"], + [546, "struct_construct>>"], + [ + 547, + "enum_init,)>, 0>" + ], + [ + 548, + "store_temp,)>>" + ], + [549, "felt252_const<1637570914057682275393755530660268060279989363>"], + [ + 550, + "enum_init,)>, 1>" + ], + [ + 551, + "function_call" + ], + [ + 552, + "function_call" + ], + [ + 553, + "enum_init>, 0>" + ], + [ + 554, + "store_temp>>" + ], + [555, "felt252_const<6214282646402414199069093229416>"], + [ + 556, + "enum_init>, 1>" + ], + [ + 557, + "function_call::unwrap_syscall>" + ], + [ + 558, + "struct_construct>" + ], + [ + 559, + "enum_init, 0>" + ], + [ + 560, + "store_temp>" + ], + [ + 561, + "enum_init, 1>" + ], + [ + 562, + "function_call" + ], + [ + 563, + "storage_base_address_const<1549662586524698628134511494108424664120874428270242005980325345328461123324>" + ], + [564, "store_temp"], + [ + 565, + "enum_match), core::array::Array::>>" + ], + [ + 566, + "struct_construct>>>" + ], + [ + 567, + "enum_init),)>, 0>" + ], + [ + 568, + "store_temp),)>>" + ], + [ + 569, + "enum_init),)>, 1>" + ], + [ + 570, + "struct_deconstruct" + ], + [ + 571, + "felt252_const<429286934060636239444256046255241512105662385954349596568652644383873724621>" + ], + [572, "call_contract_syscall"], + [ + 573, + "enum_init, core::array::Array::>, 0>" + ], + [ + 574, + "store_temp, core::array::Array::>>" + ], + [ + 575, + "enum_init, core::array::Array::>, 1>" + ], + [ + 576, + "function_call>::unwrap_syscall>" + ], + [577, "drop>>"], + [ + 578, + "function_call" + ], + [579, "felt252_const<521516269527283667330418>"], + [580, "rename"], + [581, "rename"], + [582, "rename"], + [583, "rename"], + [ + 584, + "function_call" + ], + [ + 585, + "storage_base_address_const<1217961213749390912347430045896694622051130986551650888538812188143166297945>" + ], + [ + 586, + "enum_init>, 0>" + ], + [ + 587, + "store_temp>>" + ], + [588, "felt252_const<7269940625183576940180048306939577043858226>"], + [589, "enum_init, 1>"], + [590, "store_temp>"], + [ + 591, + "enum_init>, 1>" + ], + [ + 592, + "function_call::unwrap_syscall>" + ], + [593, "struct_construct>"], + [594, "enum_init, 0>"], + [595, "u32_overflowing_add"], + [ + 596, + "enum_init, 0>" + ], + [ + 597, + "store_temp>" + ], + [ + 598, + "enum_init, 1>" + ], + [599, "felt252_const<155785504323917466144735657540098748279>"], + [ + 600, + "function_call::expect::>" + ], + [ + 601, + "struct_construct>" + ], + [ + 602, + "enum_init, 0>" + ], + [ + 603, + "store_temp>" + ], + [ + 604, + "enum_init, 1>" + ], + [ + 605, + "enum_match>>" + ], + [ + 606, + "enum_init>, 0>" + ], + [ + 607, + "struct_construct, core::option::Option::>>>" + ], + [ + 608, + "enum_init, core::option::Option::>)>, 0>" + ], + [ + 609, + "store_temp, core::option::Option::>)>>" + ], + [610, "array_append"], + [ + 611, + "enum_init, core::option::Option::>)>, 1>" + ], + [612, "rename"], + [ + 613, + "enum_init>, 1>" + ], + [614, "struct_construct>"], + [615, "store_temp>"], + [616, "function_call"], + [ + 617, + "enum_match, core::felt252)>>" + ], + [ + 618, + "struct_deconstruct, felt252>>" + ], + [619, "felt252_const<31083194373425476152957429605>"], + [620, "function_call"], + [ + 621, + "function_call" + ], + [622, "struct_deconstruct>"], + [623, "array_len"], + [624, "struct_construct, u32, Unit>>"], + [ + 625, + "enum_init, core::integer::u32, ())>, 0>" + ], + [ + 626, + "store_temp, core::integer::u32, ())>>" + ], + [ + 627, + "enum_init, core::integer::u32, ())>, 1>" + ], + [628, "function_call"], + [ + 629, + "function_call" + ], + [630, "function_call"], + [631, "enum_init, 0>"], + [632, "store_temp>"], + [633, "function_call"], + [ + 634, + "enum_match>,)>>" + ], + [ + 635, + "struct_deconstruct>>>" + ], + [ + 636, + "struct_construct, core::array::Span::>>>" + ], + [637, "dup>>"], + [638, "rename>>"], + [ + 639, + "struct_deconstruct>>" + ], + [640, "array_len>"], + [ + 641, + "function_call, core::array::SpanSerde::, core::array::SpanDrop::>>" + ], + [ + 642, + "enum_match>" + ], + [643, "struct_deconstruct"], + [644, "function_call"], + [ + 645, + "enum_match,)>>" + ], + [646, "struct_deconstruct>>"], + [647, "function_call"], + [ + 648, + "storage_base_address_const<850991909592324662282938535474023562280137231324620006946839595634568396994>" + ], + [649, "store_temp"], + [650, "function_call"], + [ + 651, + "enum_match>,)>>" + ], + [ + 652, + "struct_deconstruct>>>" + ], + [ + 653, + "store_temp>>" + ], + [ + 654, + "function_call::unwrap_syscall>" + ], + [655, "struct_construct>"], + [ + 656, + "enum_init, 0>" + ], + [ + 657, + "store_temp>" + ], + [ + 658, + "enum_init, 1>" + ], + [659, "function_call"], + [ + 660, + "struct_construct>" + ], + [ + 661, + "enum_init, 0>" + ], + [ + 662, + "store_temp>" + ], + [ + 663, + "enum_init, 1>" + ], + [ + 664, + "function_call" + ], + [665, "struct_construct>>"], + [ + 666, + "enum_init,)>, 0>" + ], + [ + 667, + "store_temp,)>>" + ], + [ + 668, + "enum_init,)>, 1>" + ], + [669, "felt252_const<30828113188794245257250221355944970489240709081949230>"], + [ + 670, + "function_call>::expect::>>" + ], + [ + 671, + "function_call" + ], + [ + 672, + "struct_construct>" + ], + [ + 673, + "enum_init, 0>" + ], + [ + 674, + "store_temp>" + ], + [ + 675, + "enum_init, 1>" + ], + [ + 676, + "function_call" + ], + [ + 677, + "felt252_const<815903823124453119243971298555977249487241195972064209763947138938752137060>" + ], + [678, "struct_construct"], + [679, "struct_deconstruct"], + [680, "pedersen"], + [681, "storage_base_address_from_felt252"], + [ + 682, + "enum_match>>" + ], + [683, "get_execution_info_v2_syscall"], + [ + 684, + "enum_init, core::array::Array::>, 0>" + ], + [ + 685, + "store_temp, core::array::Array::>>" + ], + [ + 686, + "enum_init, core::array::Array::>, 1>" + ], + [ + 687, + "function_call>::unwrap_syscall>" + ], + [ + 688, + "struct_construct>>" + ], + [ + 689, + "enum_init,)>, 0>" + ], + [ + 690, + "store_temp,)>>" + ], + [ + 691, + "enum_init,)>, 1>" + ], + [692, "enum_init"], + [693, "enum_match"], + [ + 694, + "felt252_const<931643411527245211529285955382961048845290794401900071034598191602821440999>" + ], + [ + 695, + "function_call" + ], + [ + 696, + "felt252_const<1093830577610461490539113735431936179703456330374563419579920790156759053133>" + ], + [ + 697, + "function_call" + ], + [ + 698, + "felt252_const<230192814789850291994621760810535338129013919481720626953423731987611497567>" + ], + [ + 699, + "function_call" + ], + [ + 700, + "felt252_const<1006403347863459601238155302934047095604124810258341309066785274196336610255>" + ], + [ + 701, + "function_call" + ], + [ + 702, + "felt252_const<1159172572126037242737035052411300333426457150519838559523379563476896254163>" + ], + [ + 703, + "function_call" + ], + [ + 704, + "enum_init, core::array::Array::, ())>, 1>" + ], + [ + 705, + "store_temp, core::array::Array::, ())>>" + ], + [ + 706, + "felt252_const<1030618457204368372767111383907020015782155770496513332882618556385908031709>" + ], + [ + 707, + "function_call" + ], + [ + 708, + "felt252_const<740220602995455187736018788443880169868965059258750296178224810252903139101>" + ], + [ + 709, + "function_call" + ], + [ + 710, + "felt252_const<181315633587806608749396046320465637423067733253841877734401949135886786816>" + ], + [ + 711, + "function_call" + ], + [ + 712, + "felt252_const<984040933967092568628707404443600392643744983021442377939648347191358829897>" + ], + [ + 713, + "function_call" + ], + [ + 714, + "felt252_const<28947657339379119812818542448122814251463852972795937477358048385548867373>" + ], + [ + 715, + "function_call" + ], + [ + 716, + "felt252_const<985944968547980417359859496386888840746920457321845064099263044834726206156>" + ], + [ + 717, + "function_call" + ], + [718, "struct_construct, Array, Unit>>"], + [ + 719, + "enum_init, core::array::Array::, ())>, 0>" + ], + [720, "struct_deconstruct>"], + [ + 721, + "felt252_const<812102049625239328877059852472148005149345189321026021198012755869152925610>" + ], + [ + 722, + "enum_match>>" + ], + [723, "enum_init"], + [ + 724, + "felt252_const<503758352667086857626778917682113906664552568267706797596983573137624924037>" + ], + [725, "enum_init"], + [ + 726, + "felt252_const<1403688409997574275391297710099088202596225268381271549688191319612926706217>" + ], + [ + 727, + "felt252_const<7891998437966260601762371672023996916393715052535837300>" + ], + [728, "drop"], + [ + 729, + "felt252_const<73818323049443828910082520332780958865486567819123588920520513298647499635>" + ], + [ + 730, + "enum_match>>" + ], + [731, "enum_init"], + [ + 732, + "enum_match, core::array::Array::>>" + ], + [733, "enum_init"], + [734, "enum_init"], + [ + 735, + "enum_match>>" + ], + [ + 736, + "enum_match>" + ], + [737, "struct_deconstruct>"], + [738, "hades_permutation"], + [739, "dup"], + [740, "struct_construct, felt252>>"], + [ + 741, + "enum_init, core::felt252)>, 0>" + ], + [ + 742, + "store_temp, core::felt252)>>" + ], + [ + 743, + "enum_init, core::felt252)>, 1>" + ], + [744, "drop"], + [745, "struct_construct"], + [746, "struct_deconstruct"], + [747, "drop>"], + [748, "alloc_local"], + [749, "store_local"], + [750, "function_call"], + [ + 751, + "enum_match, core::array::Span::, core::array::Span::, ())>>" + ], + [ + 752, + "struct_deconstruct, core::array::Span::, core::array::Span::, Unit>>" + ], + [753, "function_call"], + [ + 754, + "enum_match, core::integer::u8, ())>>" + ], + [755, "drop, u8, Unit>>"], + [756, "drop"], + [757, "drop>"], + [758, "enum_init"], + [759, "function_call"], + [760, "function_call"], + [761, "function_call"], + [762, "function_call"], + [763, "function_call"], + [764, "function_call"], + [765, "enum_init"], + [766, "function_call"], + [767, "struct_deconstruct, u8, Unit>>"], + [768, "function_call"], + [769, "array_new>"], + [770, "store_temp>>"], + [771, "function_call"], + [ + 772, + "enum_match, core::array::Array::>, core::array::Span::>)>>" + ], + [ + 773, + "struct_deconstruct, Array>, core::array::Span::>>>" + ], + [774, "drop>>"], + [ + 775, + "struct_construct>>>" + ], + [ + 776, + "enum_init>,)>, 0>" + ], + [ + 777, + "store_temp>,)>>" + ], + [ + 778, + "enum_init>,)>, 1>" + ], + [779, "alloc_local>>>"], + [780, "array_snapshot_pop_front>"], + [ + 781, + "enum_init>>, 0>" + ], + [782, "store_temp>>>"], + [ + 783, + "store_temp>>>" + ], + [ + 784, + "enum_init>>, 1>" + ], + [785, "store_local>>>"], + [ + 786, + "enum_match>>>" + ], + [787, "unbox>"], + [ + 788, + "struct_construct>>" + ], + [789, "drop>>>"], + [ + 790, + "drop>>>>" + ], + [ + 791, + "function_call" + ], + [792, "function_call"], + [793, "struct_construct>>"], + [ + 794, + "enum_init,)>, 0>" + ], + [ + 795, + "store_temp,)>>" + ], + [ + 796, + "enum_init,)>, 1>" + ], + [797, "function_call"], + [798, "function_call"], + [ + 799, + "function_call" + ], + [ + 800, + "enum_init>, 0>" + ], + [ + 801, + "struct_construct>>>" + ], + [ + 802, + "enum_init>,)>, 0>" + ], + [ + 803, + "store_temp>,)>>" + ], + [804, "felt252_const<1749165063169615148890104124711417950509560691>"], + [ + 805, + "enum_init>,)>, 1>" + ], + [ + 806, + "enum_init>, 1>" + ], + [ + 807, + "enum_match>>" + ], + [808, "enum_init"], + [809, "enum_init"], + [810, "enum_init"], + [ + 811, + "enum_match, core::array::Array::>>" + ], + [812, "dup"], + [813, "struct_deconstruct"], + [814, "dup"], + [815, "struct_deconstruct"], + [816, "dup"], + [817, "struct_deconstruct"], + [818, "struct_deconstruct"], + [819, "dup"], + [820, "struct_deconstruct"], + [821, "dup"], + [822, "struct_deconstruct"], + [823, "dup"], + [824, "struct_deconstruct"], + [825, "rename"], + [826, "u8_to_felt252"], + [827, "drop"], + [828, "dup"], + [829, "struct_deconstruct"], + [830, "dup"], + [831, "struct_deconstruct"], + [832, "dup"], + [833, "struct_deconstruct"], + [834, "dup"], + [835, "struct_deconstruct"], + [836, "felt252_const<159905696614104015011408994986197950919097459240563>"], + [ + 837, + "enum_init, core::array::Span::, core::array::Span::, ())>, 1>" + ], + [ + 838, + "store_temp, core::array::Span::, core::array::Span::, ())>>" + ], + [839, "function_call"], + [ + 840, + "enum_match, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>>" + ], + [ + 841, + "struct_deconstruct, core::array::Span::, felt252, u8, Array, Unit>>" + ], + [ + 842, + "struct_construct, core::array::Span::, core::array::Span::, Unit>>" + ], + [ + 843, + "enum_init, core::array::Span::, core::array::Span::, ())>, 0>" + ], + [844, "array_pop_front"], + [845, "dup"], + [846, "storage_address_from_base_and_offset"], + [847, "u8_const<1>"], + [848, "function_call"], + [849, "enum_match>"], + [850, "struct_deconstruct>"], + [851, "struct_construct, u8, Unit>>"], + [ + 852, + "enum_init, core::integer::u8, ())>, 0>" + ], + [ + 853, + "store_temp, core::integer::u8, ())>>" + ], + [ + 854, + "enum_init, core::integer::u8, ())>, 1>" + ], + [855, "felt252_const<521489465972896538179455241995775603>"], + [856, "felt252_const<2037068226456627102263497038849139>"], + [857, "felt252_const<31083194373422654758659319155>"], + [858, "upcast"], + [859, "u8_const<251>"], + [860, "function_call"], + [ + 861, + "enum_match, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>>" + ], + [ + 862, + "struct_deconstruct, core::array::Span::, felt252, u8, Array, Unit>>" + ], + [863, "array_append>"], + [ + 864, + "struct_construct, Array>, core::array::Span::>>>" + ], + [ + 865, + "enum_init, core::array::Array::>, core::array::Span::>)>, 0>" + ], + [ + 866, + "store_temp, core::array::Array::>, core::array::Span::>)>>" + ], + [ + 867, + "enum_init, core::array::Array::>, core::array::Span::>)>, 1>" + ], + [868, "snapshot_take>>"], + [869, "felt252_const<8749141412351935366688967357013970318550382>"], + [870, "function_call"], + [871, "alloc_local>>"], + [872, "array_snapshot_pop_front"], + [ + 873, + "enum_init>, 0>" + ], + [874, "store_temp>>"], + [ + 875, + "store_temp>>" + ], + [ + 876, + "enum_init>, 1>" + ], + [877, "store_local>>"], + [ + 878, + "enum_match>>" + ], + [879, "unbox"], + [880, "function_call"], + [ + 881, + "enum_match, ())>>" + ], + [882, "struct_deconstruct, Unit>>"], + [ + 883, + "struct_construct, core::array::Span::, felt252, u8, Array, Unit>>" + ], + [ + 884, + "enum_init, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>, 0>" + ], + [ + 885, + "store_temp, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>>" + ], + [ + 886, + "enum_init, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>, 1>" + ], + [887, "drop>>"], + [888, "felt252_const<29721761890975875353235833581453094220424382983267374>"], + [889, "drop>>>"], + [890, "u8_overflowing_add"], + [ + 891, + "enum_init, 0>" + ], + [ + 892, + "store_temp>" + ], + [ + 893, + "enum_init, 1>" + ], + [894, "felt252_const<608642104203229548495787928534675319>"], + [ + 895, + "function_call::expect::>" + ], + [896, "struct_construct>"], + [897, "enum_init, 0>"], + [898, "store_temp>"], + [899, "enum_init, 1>"], + [900, "alloc_local>"], + [901, "store_local>"], + [902, "function_call"], + [ + 903, + "enum_match, core::felt252, core::integer::u8, core::option::Option::)>>" + ], + [ + 904, + "struct_deconstruct, felt252, u8, core::option::Option::>>" + ], + [ + 905, + "struct_construct, core::array::Span::, felt252, u8, Array, Unit>>" + ], + [ + 906, + "enum_init, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>, 0>" + ], + [ + 907, + "store_temp, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>>" + ], + [ + 908, + "enum_init, core::array::Span::, core::felt252, core::integer::u8, core::array::Array::, ())>, 1>" + ], + [909, "drop>>"], + [910, "felt252_const<2037068226456627102263497038980473>"], + [911, "alloc_local"], + [912, "function_call"], + [913, "function_call::into>"], + [914, "u8_overflowing_sub"], + [915, "function_call"], + [916, "store_temp"], + [917, "store_local"], + [918, "function_call"], + [919, "enum_match>"], + [920, "struct_deconstruct"], + [921, "struct_deconstruct>"], + [922, "bitwise"], + [923, "struct_construct"], + [924, "function_call"], + [925, "struct_construct, Unit>>"], + [ + 926, + "enum_init, ())>, 0>" + ], + [ + 927, + "store_temp, ())>>" + ], + [ + 928, + "enum_init, ())>, 1>" + ], + [929, "drop"], + [930, "drop>"], + [ + 931, + "enum_match>" + ], + [932, "alloc_local>"], + [933, "u128_const<1>"], + [934, "u128_const<0>"], + [935, "function_call"], + [936, "store_local>"], + [937, "function_call"], + [938, "store_temp"], + [ + 939, + "struct_construct, felt252, u8, core::option::Option::>>" + ], + [ + 940, + "enum_init, core::felt252, core::integer::u8, core::option::Option::)>, 0>" + ], + [ + 941, + "store_temp, core::felt252, core::integer::u8, core::option::Option::)>>" + ], + [ + 942, + "enum_init, core::felt252, core::integer::u8, core::option::Option::)>, 1>" + ], + [943, "drop>"], + [944, "drop>>"], + [945, "snapshot_take"], + [946, "u8_eq"], + [947, "felt252_const<608642109794502019480482122260311927>"], + [948, "u128s_from_felt252"], + [949, "u128_const<2>"], + [950, "function_call"], + [951, "function_call"], + [952, "struct_construct>"], + [953, "enum_init, 0>"], + [954, "store_temp>"], + [955, "enum_init, 1>"], + [956, "u128_const<10633823966279327296825105735305134080>"], + [957, "dup"], + [958, "u128_overflowing_sub"], + [959, "snapshot_take"], + [960, "rename"], + [961, "u128_eq"], + [962, "u128_to_felt252"], + [963, "felt252_const<340282366920938463463374607431768211456>"], + [964, "felt252_mul"], + [965, "function_call"], + [966, "enum_match>"], + [967, "felt252_const<39879774624085075084607933104993585622903>"], + [968, "function_call"], + [969, "dup"], + [970, "u8_const<2>"], + [971, "function_call"], + [972, "function_call"], + [973, "function_call"], + [974, "felt252_const<39879774624083218221772669863277689073527>"], + [975, "function_call"], + [976, "struct_deconstruct>"], + [977, "enum_init, 0>"], + [978, "store_temp>"], + [979, "enum_init, 1>"], + [980, "function_call"], + [ + 981, + "enum_match>,)>>" + ], + [ + 982, + "struct_deconstruct>>>" + ], + [ + 983, + "enum_match>>" + ], + [984, "u256_safe_divmod"], + [985, "store_temp"], + [ + 986, + "function_call" + ], + [987, "struct_construct>"], + [988, "struct_deconstruct>"], + [989, "felt252_const<5420154128225384396790819266608>"], + [990, "function_call"], + [ + 991, + "enum_match>,)>>" + ], + [ + 992, + "struct_deconstruct>>>" + ], + [ + 993, + "enum_match>>" + ], + [994, "u8_safe_divmod"], + [995, "function_call"], + [996, "struct_construct>"], + [997, "store_temp>"], + [998, "struct_deconstruct>"], + [999, "struct_construct>"], + [1000, "store_temp>"], + [1001, "rename>"], + [1002, "function_call"], + [ + 1003, + "enum_match,)>>" + ], + [1004, "struct_deconstruct>>"], + [ + 1005, + "enum_init>, 0>" + ], + [ + 1006, + "struct_construct>>>" + ], + [ + 1007, + "enum_init>,)>, 0>" + ], + [ + 1008, + "store_temp>,)>>" + ], + [ + 1009, + "enum_init>,)>, 1>" + ], + [1010, "u128_mul_guarantee_verify"], + [1011, "function_call"], + [ + 1012, + "enum_match,)>>" + ], + [1013, "struct_deconstruct>>"], + [ + 1014, + "enum_init>, 0>" + ], + [ + 1015, + "struct_construct>>>" + ], + [ + 1016, + "enum_init>,)>, 0>" + ], + [ + 1017, + "store_temp>,)>>" + ], + [ + 1018, + "enum_init>,)>, 1>" + ], + [1019, "u128_guarantee_mul"], + [1020, "struct_construct>"], + [1021, "struct_deconstruct>"], + [1022, "u128_overflowing_add"], + [1023, "function_call"], + [1024, "struct_construct>>"], + [ + 1025, + "enum_init,)>, 0>" + ], + [ + 1026, + "store_temp,)>>" + ], + [1027, "felt252_const<2161886914012515606576>"], + [ + 1028, + "enum_init,)>, 1>" + ], + [1029, "function_call"], + [1030, "struct_construct>>"], + [ + 1031, + "enum_init,)>, 0>" + ], + [ + 1032, + "store_temp,)>>" + ], + [1033, "felt252_const<32994284134408240>"], + [ + 1034, + "enum_init,)>, 1>" + ], + [1035, "u256_is_zero"], + [ + 1036, + "enum_init>, 1>" + ], + [ + 1037, + "store_temp>>" + ], + [1038, "u8_is_zero"], + [ + 1039, + "enum_init>, 1>" + ], + [ + 1040, + "store_temp>>" + ] + ], + "user_func_names": [ + [0, "dojo::world::world::__wrapper__World__metadata_uri"], + [1, "dojo::world::world::__wrapper__World__set_metadata_uri"], + [2, "dojo::world::world::__wrapper__World__is_owner"], + [3, "dojo::world::world::__wrapper__World__grant_owner"], + [4, "dojo::world::world::__wrapper__World__revoke_owner"], + [5, "dojo::world::world::__wrapper__World__is_writer"], + [6, "dojo::world::world::__wrapper__World__grant_writer"], + [7, "dojo::world::world::__wrapper__World__revoke_writer"], + [8, "dojo::world::world::__wrapper__World__register_model"], + [9, "dojo::world::world::__wrapper__World__model"], + [10, "dojo::world::world::__wrapper__World__deploy_contract"], + [11, "dojo::world::world::__wrapper__World__upgrade_contract"], + [12, "dojo::world::world::__wrapper__World__uuid"], + [13, "dojo::world::world::__wrapper__World__emit"], + [14, "dojo::world::world::__wrapper__World__set_entity"], + [15, "dojo::world::world::__wrapper__World__delete_entity"], + [16, "dojo::world::world::__wrapper__World__entity"], + [17, "dojo::world::world::__wrapper__World__entities"], + [18, "dojo::world::world::__wrapper__World__entity_ids"], + [19, "dojo::world::world::__wrapper__World__set_executor"], + [20, "dojo::world::world::__wrapper__World__executor"], + [21, "dojo::world::world::__wrapper__World__base"], + [22, "dojo::world::world::__wrapper__UpgradeableWorld__upgrade"], + [23, "dojo::world::world::__wrapper__constructor"], + [24, "core::Felt252Serde::deserialize"], + [25, "dojo::world::world::World::metadata_uri"], + [ + 26, + "core::array::SpanSerde::::serialize" + ], + [ + 27, + "core::array::SpanSerde::::deserialize" + ], + [28, "dojo::world::world::World::set_metadata_uri"], + [29, "core::starknet::contract_address::ContractAddressSerde::deserialize"], + [30, "dojo::world::world::World::is_owner"], + [31, "core::BoolSerde::serialize"], + [32, "dojo::world::world::World::grant_owner"], + [33, "dojo::world::world::World::revoke_owner"], + [34, "dojo::world::world::World::is_writer"], + [35, "dojo::world::world::World::grant_writer"], + [36, "dojo::world::world::World::revoke_writer"], + [37, "core::starknet::class_hash::ClassHashSerde::deserialize"], + [38, "dojo::world::world::World::register_model"], + [39, "dojo::world::world::World::model"], + [40, "core::starknet::class_hash::ClassHashSerde::serialize"], + [41, "dojo::world::world::World::deploy_contract"], + [42, "core::starknet::contract_address::ContractAddressSerde::serialize"], + [43, "dojo::world::world::World::upgrade_contract"], + [44, "dojo::world::world::World::uuid"], + [ + 45, + "core::array::ArraySerde::::deserialize" + ], + [46, "dojo::world::world::World::emit"], + [47, "core::integer::Felt252TryIntoU8::try_into"], + [ + 48, + "core::array::SpanSerde::, core::integer::u8Drop>::deserialize" + ], + [49, "dojo::world::world::World::set_entity"], + [50, "dojo::world::world::World::delete_entity"], + [51, "core::integer::Felt252TryIntoU32::try_into"], + [52, "dojo::world::world::World::entity"], + [ + 53, + "core::option::OptionSerde::>::deserialize" + ], + [54, "dojo::world::world::World::entities"], + [ + 55, + "core::serde::TupleSize2Serde::, core::array::Span::>, core::array::SpanSerde::, core::array::SpanDrop::, core::array::SpanSerde::, core::array::SpanSerde::, core::array::SpanDrop::>, core::array::SpanDrop::>>::serialize" + ], + [56, "dojo::world::world::World::entity_ids"], + [57, "dojo::world::world::World::set_executor"], + [58, "dojo::world::world::World::executor"], + [59, "dojo::world::world::World::base"], + [60, "dojo::world::world::UpgradeableWorld::upgrade"], + [61, "dojo::world::world::constructor"], + [ + 62, + "dojo::world::world::metadata_uri::InternalContractMemberStateImpl::read" + ], + [63, "dojo::world::world::World::metadata_uri[expr29]"], + [ + 64, + "core::array::serialize_array_helper::" + ], + [ + 65, + "core::array::deserialize_array_helper::" + ], + [66, "core::starknet::info::get_caller_address"], + [ + 67, + "dojo::world::world::metadata_uri::InternalContractMemberStateImpl::write" + ], + [ + 68, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [69, "dojo::world::world::World::set_metadata_uri[expr42]"], + [70, "dojo::world::world::owners::InternalContractMemberStateImpl::read"], + [71, "core::Felt252Serde::serialize"], + [72, "dojo::world::world::owners::InternalContractMemberStateImpl::write"], + [ + 73, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [74, "dojo::world::world::writers::InternalContractMemberStateImpl::read"], + [75, "dojo::world::world::writers::InternalContractMemberStateImpl::write"], + [ + 76, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [77, "dojo::world::world::class_call"], + [78, "core::array::array_at::"], + [79, "dojo::world::world::models::InternalContractMemberStateImpl::read"], + [80, "dojo::world::world::models::InternalContractMemberStateImpl::write"], + [ + 81, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [ + 82, + "dojo::world::world::contract_base::InternalContractMemberStateImpl::read" + ], + [ + 83, + "core::starknet::SyscallResultTraitImpl::<(core::starknet::contract_address::ContractAddress, core::array::Span::)>::unwrap_syscall" + ], + [84, "dojo::components::upgradeable::IUpgradeableDispatcherImpl::upgrade"], + [ + 85, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [86, "dojo::world::world::assert_can_write"], + [ + 87, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [88, "dojo::world::world::nonce::InternalContractMemberStateImpl::read"], + [89, "core::integer::U32Add::add"], + [90, "dojo::world::world::nonce::InternalContractMemberStateImpl::write"], + [91, "core::starknet::SyscallResultTraitImpl::<()>::unwrap_syscall"], + [ + 92, + "core::array::deserialize_array_helper::, core::integer::u8Drop>" + ], + [93, "core::poseidon::poseidon_hash_span"], + [94, "dojo::database::set"], + [ + 95, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [96, "dojo::world::world::World::delete_entity[expr26]"], + [97, "dojo::database::del"], + [ + 98, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [99, "dojo::database::get"], + [100, "core::serde::TupleSize0Serde::deserialize"], + [101, "dojo::database::scan"], + [ + 102, + "core::array::SpanSerde::, core::array::SpanSerde::, core::array::SpanDrop::>::serialize" + ], + [103, "dojo::database::scan_ids"], + [ + 104, + "dojo::world::world::executor_dispatcher::InternalContractMemberStateImpl::read" + ], + [ + 105, + "dojo::world::world::executor_dispatcher::InternalContractMemberStateImpl::write" + ], + [ + 106, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [107, "core::starknet::info::get_tx_info"], + [ + 108, + "core::result::ResultTraitImpl::<(), core::array::Array::>::unwrap::>" + ], + [ + 109, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [ + 110, + "dojo::world::world::contract_base::InternalContractMemberStateImpl::write" + ], + [111, "core::starknet::info::get_contract_address"], + [ + 112, + "dojo::world::world::ContractStateEventEmitter::emit::" + ], + [ + 113, + "dojo::world::world::metadata_uri::InternalContractMemberStateImpl::address" + ], + [ + 114, + "core::starknet::SyscallResultTraitImpl::::unwrap_syscall" + ], + [115, "core::starknet::info::get_execution_info"], + [116, "dojo::world::world::EventMetadataUpdateIntoEvent::into"], + [117, "dojo::world::world::EventIsEvent::append_keys_and_data"], + [118, "dojo::world::world::owners::InternalContractMemberStateImpl::address"], + [119, "core::starknet::SyscallResultTraitImpl::::unwrap_syscall"], + [120, "dojo::world::world::EventOwnerUpdatedIntoEvent::into"], + [ + 121, + "dojo::world::world::writers::InternalContractMemberStateImpl::address" + ], + [122, "dojo::world::world::EventWriterUpdatedIntoEvent::into"], + [123, "dojo::executor::IExecutorDispatcherImpl::call"], + [124, "dojo::world::world::models::InternalContractMemberStateImpl::address"], + [125, "core::starknet::class_hash::Felt252TryIntoClassHash::try_into"], + [ + 126, + "core::starknet::SyscallResultTraitImpl::::unwrap_syscall" + ], + [127, "dojo::world::world::EventModelRegisteredIntoEvent::into"], + [ + 128, + "core::starknet::SyscallResultTraitImpl::>::unwrap_syscall" + ], + [129, "dojo::world::world::EventContractDeployedIntoEvent::into"], + [130, "dojo::world::world::EventContractUpgradedIntoEvent::into"], + [ + 131, + "core::starknet::SyscallResultTraitImpl::::unwrap_syscall" + ], + [ + 132, + "core::result::ResultTraitImpl::::expect::" + ], + [133, "core::poseidon::_poseidon_hash_span_inner"], + [134, "dojo::database::storage::set_many"], + [135, "dojo::world::world::EventStoreSetRecordIntoEvent::into"], + [136, "dojo::database::index::delete"], + [137, "dojo::world::world::EventStoreDelRecordIntoEvent::into"], + [138, "dojo::database::storage::get_many"], + [139, "dojo::database::get_by_ids"], + [ + 140, + "core::array::serialize_array_helper::, core::array::SpanSerde::, core::array::SpanDrop::>" + ], + [141, "dojo::database::index::get_by_key"], + [142, "dojo::database::index::query"], + [143, "dojo::executor::StoreIExecutorDispatcher::read"], + [ + 144, + "core::starknet::SyscallResultTraitImpl::::unwrap_syscall" + ], + [145, "dojo::executor::StoreIExecutorDispatcher::write"], + [146, "dojo::world::world::EventExecutorUpdatedIntoEvent::into"], + [ + 147, + "core::result::ResultTraitImpl::<(), core::array::Array::>::expect::>" + ], + [148, "dojo::world::world::EventWorldUpgradedIntoEvent::into"], + [149, "dojo::world::world::EventWorldSpawnedIntoEvent::into"], + [ + 150, + "core::starknet::SyscallResultTraitImpl::>::unwrap_syscall" + ], + [151, "dojo::world::world::WorldSpawnedIsEvent::append_keys_and_data"], + [152, "dojo::world::world::ContractDeployedIsEvent::append_keys_and_data"], + [153, "dojo::world::world::ContractUpgradedIsEvent::append_keys_and_data"], + [154, "dojo::world::world::WorldUpgradedIsEvent::append_keys_and_data"], + [155, "dojo::world::world::MetadataUpdateIsEvent::append_keys_and_data"], + [156, "dojo::world::world::ModelRegisteredIsEvent::append_keys_and_data"], + [157, "dojo::world::world::StoreSetRecordIsEvent::append_keys_and_data"], + [158, "dojo::world::world::StoreDelRecordIsEvent::append_keys_and_data"], + [159, "dojo::world::world::WriterUpdatedIsEvent::append_keys_and_data"], + [160, "dojo::world::world::OwnerUpdatedIsEvent::append_keys_and_data"], + [161, "dojo::world::world::ExecutorUpdatedIsEvent::append_keys_and_data"], + [162, "dojo::packing::pack"], + [163, "dojo::database::storage::set_many[expr24]"], + [164, "dojo::database::index::exists"], + [165, "dojo::database::index::build_index_len_key"], + [166, "dojo::database::storage::get"], + [167, "dojo::database::index::build_index_item_key"], + [168, "dojo::database::storage::set"], + [169, "dojo::database::index::build_index_key"], + [170, "dojo::database::storage::get_many[expr25]"], + [171, "dojo::packing::unpack"], + [172, "dojo::database::get_by_ids[expr32]"], + [173, "dojo::database::index::build_index_specific_key_len"], + [174, "dojo::database::index::get_by_key[expr29]"], + [175, "dojo::database::index::query[expr38]"], + [176, "dojo::database::index::query[expr65]"], + [ + 177, + "core::starknet::contract_address::Felt252TryIntoContractAddress::try_into" + ], + [178, "dojo::packing::pack[expr25]"], + [179, "core::integer::U8Add::add"], + [180, "dojo::packing::unpack[expr19]"], + [181, "dojo::database::index::build_index_specific_key"], + [182, "dojo::packing::pack_inner"], + [ + 183, + "core::result::ResultTraitImpl::::expect::" + ], + [184, "dojo::packing::unpack_inner"], + [185, "core::integer::U8Sub::sub"], + [186, "core::traits::TIntoT::::into"], + [187, "core::integer::u256_from_felt252"], + [188, "dojo::packing::shl"], + [189, "core::integer::U256TryIntoFelt252::try_into"], + [190, "core::integer::U256Sub::sub"], + [191, "dojo::packing::shr"], + [192, "dojo::packing::fpow"], + [193, "core::integer::U256Mul::mul"], + [194, "core::integer::u256_checked_sub"], + [195, "core::integer::U256Div::div"], + [196, "core::integer::U8Div::div"], + [197, "core::integer::U8Rem::rem"], + [198, "core::integer::u256_checked_mul"], + [199, "core::integer::u256_overflow_sub"], + [200, "core::integer::U256TryIntoNonZero::try_into"], + [201, "core::integer::U128MulGuaranteeDestruct::destruct"], + [202, "core::integer::U8TryIntoNonZero::try_into"], + [203, "core::integer::u256_overflow_mul"], + [204, "core::integer::u256_as_non_zero"], + [205, "core::integer::u8_as_non_zero"], + [206, "core::integer::u256_try_as_non_zero"], + [207, "core::integer::u8_try_as_non_zero"] + ] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x2d15e90b6c97950698267456915f7a71eab1e2c2d9c29adda4c64351b947f6", + "function_idx": 19 + }, + { + "selector": "0x78e492aaf17f7a3f781cf5bd3bbfcc2b3eaa41d560004e97822a389e5b9938", + "function_idx": 4 + }, + { + "selector": "0x92c0700add430acfc01c011a36ab44410c9f866f45f5c6faf34816c329d815", + "function_idx": 11 + }, + { + "selector": "0x95201d0392af03939a89e3de12f33d3dba253a149135f3cf63df141304874a", + "function_idx": 1 + }, + { + "selector": "0xc9ce8ef5f69752e9f3464854b4d203757e0270e1484f07386d4858dbc90fd5", + "function_idx": 5 + }, + { + "selector": "0xd065c837ba98927ca43d2e15d8e840ca8e67646b8e00108f1b55d18a75d80f", + "function_idx": 14 + }, + { + "selector": "0xd682fdeedea6d7edc10c60b7f4feb26bba9c226f7f49d20537e0a5c8e4dca4", + "function_idx": 2 + }, + { + "selector": "0xdc49c2b31b72d9d49bdda99fca2fa95be0944a4ad731474dd3cdb1b704f9c6", + "function_idx": 20 + }, + { + "selector": "0xf2f7c15cbe06c8d94597cd91fd7f3369eae842359235712def5584f8d270cd", + "function_idx": 22 + }, + { + "selector": "0x11185346d2996711dd761c502ee7036b7bbf81137b5ba67ab29c6b6f57570a9", + "function_idx": 9 + }, + { + "selector": "0x1cdc902ca80aea4fa41f94d35654158d368cd858e75e9f2426d204944eef764", + "function_idx": 0 + }, + { + "selector": "0x1e7875674bcb09daaf984cbf77264ac98120cb39e6d17522520defcdc347476", + "function_idx": 8 + }, + { + "selector": "0x1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f", + "function_idx": 21 + }, + { + "selector": "0x2006b7fe6210e12240f1a27ac985955c598e7576256baac9572d2eaba0c1ec6", + "function_idx": 13 + }, + { + "selector": "0x2730079d734ee55315f4f141eaed376bddd8c2133523d223a344c5604e0f7f8", + "function_idx": 10 + }, + { + "selector": "0x27706e83545bc0fb130476239ec381f65fba8f92e2379d60a07869aa04b4ccc", + "function_idx": 17 + }, + { + "selector": "0x2bb4f87ddba687c0a9c116b582343d1ec88aac87d1a2b9d0d2eb97f72ec04b3", + "function_idx": 7 + }, + { + "selector": "0x2ee0e84a99e5b3cb20adcdbe548dd1ab3bb535bdd690595e43594707778be82", + "function_idx": 12 + }, + { + "selector": "0x326593e1b7478914a9c4ff6d556d1561d942e60fae7253b1eb00c19702dbf1f", + "function_idx": 16 + }, + { + "selector": "0x3271a0851c2c2e6b7ba8ba7abcb8224c6ea500835b9db9f2fb9ca5bb16e2191", + "function_idx": 3 + }, + { + "selector": "0x32f38f35a723d373631d54098023497b029ba854937c1f7d43d9a7e5d740dc2", + "function_idx": 6 + }, + { + "selector": "0x3b69340fcf8be188929519cadac84cb5deef1f1eb93ae649bc174185cabeded", + "function_idx": 18 + }, + { + "selector": "0x3fd91e956981a61ef4c1038f3b8f3aa8306728a656a6b695f280191ed6321ef", + "function_idx": 15 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "function_idx": 23 + } + ] + }, + "abi": [ + { + "type": "impl", + "name": "World", + "interface_name": "dojo::world::IWorld" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::felt252" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::>" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::IWorld", + "items": [ + { + "type": "function", + "name": "metadata_uri", + "inputs": [ + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_metadata_uri", + "inputs": [ + { + "name": "resource", + "type": "core::felt252" + }, + { + "name": "uri", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "model", + "inputs": [ + { + "name": "name", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "register_model", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "deploy_contract", + "inputs": [ + { + "name": "salt", + "type": "core::felt252" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "upgrade_contract", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "uuid", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "emit", + "inputs": [ + { + "name": "keys", + "type": "core::array::Array::" + }, + { + "name": "values", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "offset", + "type": "core::integer::u8" + }, + { + "name": "length", + "type": "core::integer::u32" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "offset", + "type": "core::integer::u8" + }, + { + "name": "values", + "type": "core::array::Span::" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "entities", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "index", + "type": "core::option::Option::" + }, + { + "name": "values", + "type": "core::array::Span::" + }, + { + "name": "values_length", + "type": "core::integer::u32" + }, + { + "name": "values_layout", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "(core::array::Span::, core::array::Span::>)" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "entity_ids", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_executor", + "inputs": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "executor", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "base", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "delete_entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "is_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "grant_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "revoke_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "is_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "grant_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "revoke_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "UpgradeableWorld", + "interface_name": "dojo::world::IUpgradeableWorld" + }, + { + "type": "interface", + "name": "dojo::world::IUpgradeableWorld", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "executor", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "contract_base", + "type": "core::starknet::class_hash::ClassHash" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WorldSpawned", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ContractDeployed", + "kind": "struct", + "members": [ + { + "name": "salt", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ContractUpgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WorldUpgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::MetadataUpdate", + "kind": "struct", + "members": [ + { + "name": "resource", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "uri", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ModelRegistered", + "kind": "struct", + "members": [ + { + "name": "name", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "prev_class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::StoreSetRecord", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "keys", + "type": "core::array::Span::", + "kind": "data" + }, + { + "name": "offset", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::StoreDelRecord", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "keys", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WriterUpdated", + "kind": "struct", + "members": [ + { + "name": "model", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "value", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::OwnerUpdated", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "resource", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "value", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ExecutorUpdated", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "prev_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::Event", + "kind": "enum", + "variants": [ + { + "name": "WorldSpawned", + "type": "dojo::world::world::WorldSpawned", + "kind": "nested" + }, + { + "name": "ContractDeployed", + "type": "dojo::world::world::ContractDeployed", + "kind": "nested" + }, + { + "name": "ContractUpgraded", + "type": "dojo::world::world::ContractUpgraded", + "kind": "nested" + }, + { + "name": "WorldUpgraded", + "type": "dojo::world::world::WorldUpgraded", + "kind": "nested" + }, + { + "name": "MetadataUpdate", + "type": "dojo::world::world::MetadataUpdate", + "kind": "nested" + }, + { + "name": "ModelRegistered", + "type": "dojo::world::world::ModelRegistered", + "kind": "nested" + }, + { + "name": "StoreSetRecord", + "type": "dojo::world::world::StoreSetRecord", + "kind": "nested" + }, + { + "name": "StoreDelRecord", + "type": "dojo::world::world::StoreDelRecord", + "kind": "nested" + }, + { + "name": "WriterUpdated", + "type": "dojo::world::world::WriterUpdated", + "kind": "nested" + }, + { + "name": "OwnerUpdated", + "type": "dojo::world::world::OwnerUpdated", + "kind": "nested" + }, + { + "name": "ExecutorUpdated", + "type": "dojo::world::world::ExecutorUpdated", + "kind": "nested" + } + ] + } + ] +} diff --git a/crates/katana/storage/db/benches/codec.rs b/crates/katana/storage/db/benches/codec.rs new file mode 100644 index 0000000000..e74344ec92 --- /dev/null +++ b/crates/katana/storage/db/benches/codec.rs @@ -0,0 +1,47 @@ +use blockifier::execution::contract_class::ContractClassV1; +use cairo_lang_starknet::casm_contract_class::CasmContractClass; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use katana_db::codecs::{Compress, Decompress}; +use katana_db::models::contract::StoredContractClass; +use katana_primitives::contract::CompiledContractClass; + +fn compress_contract(contract: CompiledContractClass) -> Vec { + let class = StoredContractClass::from(contract); + class.compress() +} + +fn decompress_contract(compressed: &[u8]) -> CompiledContractClass { + let class = StoredContractClass::decompress(compressed).unwrap(); + CompiledContractClass::from(class) +} + +fn compress_contract_with_main_codec(c: &mut Criterion) { + let class = { + let class = + serde_json::from_slice(include_bytes!("./artifacts/dojo_world_240.json")).unwrap(); + let class = CasmContractClass::from_contract_class(class, true).unwrap(); + CompiledContractClass::V1(ContractClassV1::try_from(class).unwrap()) + }; + + c.bench_function("compress world contract", |b| { + b.iter_with_large_drop(|| compress_contract(black_box(class.clone()))) + }); +} + +fn decompress_contract_with_main_codec(c: &mut Criterion) { + let class = { + let class = + serde_json::from_slice(include_bytes!("./artifacts/dojo_world_240.json")).unwrap(); + let class = CasmContractClass::from_contract_class(class, true).unwrap(); + CompiledContractClass::V1(ContractClassV1::try_from(class).unwrap()) + }; + + let compressed = compress_contract(class); + + c.bench_function("decompress world contract", |b| { + b.iter_with_large_drop(|| decompress_contract(black_box(&compressed))) + }); +} + +criterion_group!(contract, compress_contract_with_main_codec, decompress_contract_with_main_codec); +criterion_main!(contract); From dc5faa26730ffdcf574d22d3583861fad50abeb9 Mon Sep 17 00:00:00 2001 From: Yun Date: Mon, 18 Dec 2023 08:22:03 -0800 Subject: [PATCH 04/42] Rename entity ids to hashed_keys in grpc (#1286) * Rename entity ids to hashed_keys in grpc protobuf * use hashed_keys more generally --- crates/torii/grpc/proto/types.proto | 11 ++--- crates/torii/grpc/proto/world.proto | 2 +- crates/torii/grpc/src/client.rs | 6 +-- crates/torii/grpc/src/server/mod.rs | 45 +++++++++++-------- .../grpc/src/server/subscriptions/entity.rs | 25 ++++++----- crates/torii/grpc/src/types/schema.rs | 5 ++- 6 files changed, 52 insertions(+), 42 deletions(-) diff --git a/crates/torii/grpc/proto/types.proto b/crates/torii/grpc/proto/types.proto index dd27e2dc52..abb8495b9c 100644 --- a/crates/torii/grpc/proto/types.proto +++ b/crates/torii/grpc/proto/types.proto @@ -35,9 +35,10 @@ message Model { string name = 1; repeated Member members = 2; } + message Entity { - // The entity id - bytes id = 1; + // The entity's hashed keys + bytes hashed_keys = 1; // Models of the entity repeated Model models = 2; } @@ -74,15 +75,15 @@ message Query { message Clause { oneof clause_type { - IdsClause ids = 1; + HashedKeysClause hashed_keys = 1; KeysClause keys = 2; MemberClause member = 3; CompositeClause composite = 4; } } -message IdsClause { - repeated bytes ids = 1; +message HashedKeysClause { + repeated bytes hashed_keys = 1; } message KeysClause { diff --git a/crates/torii/grpc/proto/world.proto b/crates/torii/grpc/proto/world.proto index 3b42be93af..0539e4e493 100644 --- a/crates/torii/grpc/proto/world.proto +++ b/crates/torii/grpc/proto/world.proto @@ -40,7 +40,7 @@ message SubscribeModelsResponse { } message SubscribeEntitiesRequest { - repeated bytes ids = 1; + repeated bytes hashed_keys = 1; } message SubscribeEntityResponse { diff --git a/crates/torii/grpc/src/client.rs b/crates/torii/grpc/src/client.rs index c8870bbd1c..90852a0701 100644 --- a/crates/torii/grpc/src/client.rs +++ b/crates/torii/grpc/src/client.rs @@ -86,12 +86,12 @@ impl WorldClient { /// Subscribe to entities updates of a World. pub async fn subscribe_entities( &mut self, - ids: Vec, + hashed_keys: Vec, ) -> Result { - let ids = ids.iter().map(|id| id.to_bytes_be().to_vec()).collect(); + let hashed_keys = hashed_keys.iter().map(|hashed| hashed.to_bytes_be().to_vec()).collect(); let stream = self .inner - .subscribe_entities(SubscribeEntitiesRequest { ids }) + .subscribe_entities(SubscribeEntitiesRequest { hashed_keys }) .await .map_err(Error::Grpc) .map(|res| res.into_inner())?; diff --git a/crates/torii/grpc/src/server/mod.rs b/crates/torii/grpc/src/server/mod.rs index 87d3c9be7e..8216990e27 100644 --- a/crates/torii/grpc/src/server/mod.rs +++ b/crates/torii/grpc/src/server/mod.rs @@ -120,20 +120,20 @@ impl DojoWorld { limit: u32, offset: u32, ) -> Result, Error> { - self.entities_by_ids(None, limit, offset).await + self.entities_by_hashed_keys(None, limit, offset).await } - async fn entities_by_ids( + async fn entities_by_hashed_keys( &self, - ids_clause: Option, + hashed_keys: Option, limit: u32, offset: u32, ) -> Result, Error> { // TODO: use prepared statement for where clause - let filter_ids = match ids_clause { - Some(ids_clause) => { - let ids = ids_clause - .ids + let filter_ids = match hashed_keys { + Some(hashed_keys) => { + let ids = hashed_keys + .hashed_keys .iter() .map(|id| { Ok(FieldElement::from_byte_slice_be(id) @@ -180,8 +180,11 @@ impl DojoWorld { }) .collect::, Error>>()?; - let id = FieldElement::from_str(&entity_id).map_err(ParseError::FromStr)?; - entities.push(proto::types::Entity { id: id.to_bytes_be().to_vec(), models }) + let hashed_keys = FieldElement::from_str(&entity_id).map_err(ParseError::FromStr)?; + entities.push(proto::types::Entity { + hashed_keys: hashed_keys.to_bytes_be().to_vec(), + models, + }) } Ok(entities) @@ -312,9 +315,9 @@ impl DojoWorld { async fn subscribe_entities( &self, - ids: Vec, + hashed_keys: Vec, ) -> Result>, Error> { - self.entity_manager.add_subscriber(ids).await + self.entity_manager.add_subscriber(hashed_keys).await } async fn retrieve_entities( @@ -328,12 +331,13 @@ impl DojoWorld { clause.clause_type.ok_or(QueryError::MissingParam("clause_type".into()))?; match clause_type { - ClauseType::Ids(ids) => { - if ids.ids.is_empty() { + ClauseType::HashedKeys(hashed_keys) => { + if hashed_keys.hashed_keys.is_empty() { return Err(QueryError::MissingParam("ids".into()).into()); } - self.entities_by_ids(Some(ids), query.limit, query.offset).await? + self.entities_by_hashed_keys(Some(hashed_keys), query.limit, query.offset) + .await? } ClauseType::Keys(keys) => { if keys.keys.is_empty() { @@ -360,7 +364,7 @@ impl DojoWorld { } fn map_row_to_entity(row: &SqliteRow, schemas: &[Ty]) -> Result { - let id = + let hashed_keys = FieldElement::from_str(&row.get::("id")).map_err(ParseError::FromStr)?; let models = schemas .iter() @@ -372,7 +376,7 @@ impl DojoWorld { }) .collect::, Error>>()?; - Ok(proto::types::Entity { id: id.to_bytes_be().to_vec(), models }) + Ok(proto::types::Entity { hashed_keys: hashed_keys.to_bytes_be().to_vec(), models }) } } @@ -415,15 +419,18 @@ impl proto::world::world_server::World for DojoWorld { &self, request: Request, ) -> ServiceResult { - let SubscribeEntitiesRequest { ids } = request.into_inner(); - let ids = ids + let SubscribeEntitiesRequest { hashed_keys } = request.into_inner(); + let hashed_keys = hashed_keys .iter() .map(|id| { FieldElement::from_byte_slice_be(id) .map_err(|e| Status::invalid_argument(e.to_string())) }) .collect::, _>>()?; - let rx = self.subscribe_entities(ids).await.map_err(|e| Status::internal(e.to_string()))?; + let rx = self + .subscribe_entities(hashed_keys) + .await + .map_err(|e| Status::internal(e.to_string()))?; Ok(Response::new(Box::pin(ReceiverStream::new(rx)) as Self::SubscribeEntitiesStream)) } diff --git a/crates/torii/grpc/src/server/subscriptions/entity.rs b/crates/torii/grpc/src/server/subscriptions/entity.rs index a39529e681..e4a86176c8 100644 --- a/crates/torii/grpc/src/server/subscriptions/entity.rs +++ b/crates/torii/grpc/src/server/subscriptions/entity.rs @@ -23,7 +23,7 @@ use crate::proto; pub struct EntitiesSubscriber { /// Entity ids that the subscriber is interested in - ids: HashSet, + hashed_keys: HashSet, /// The channel to send the response back to the subscriber. sender: Sender>, } @@ -36,15 +36,15 @@ pub struct EntityManager { impl EntityManager { pub async fn add_subscriber( &self, - ids: Vec, + hashed_keys: Vec, ) -> Result>, Error> { let id = rand::thread_rng().gen::(); let (sender, receiver) = channel(1); - self.subscribers - .write() - .await - .insert(id, EntitiesSubscriber { ids: ids.iter().cloned().collect(), sender }); + self.subscribers.write().await.insert( + id, + EntitiesSubscriber { hashed_keys: hashed_keys.iter().cloned().collect(), sender }, + ); Ok(receiver) } @@ -80,14 +80,14 @@ impl Service { subs: Arc, cache: Arc, pool: Pool, - id: &str, + hashed_keys: &str, ) -> Result<(), Error> { let mut closed_stream = Vec::new(); for (idx, sub) in subs.subscribers.read().await.iter() { - let felt_id = FieldElement::from_str(id).map_err(ParseError::FromStr)?; + let hashed = FieldElement::from_str(hashed_keys).map_err(ParseError::FromStr)?; // publish all updates if ids is empty or only ids that are subscribed to - if sub.ids.is_empty() || sub.ids.contains(&felt_id) { + if sub.hashed_keys.is_empty() || sub.hashed_keys.contains(&hashed) { let models_query = r#" SELECT group_concat(entity_model.model_id) as model_names FROM entities @@ -96,11 +96,12 @@ impl Service { GROUP BY entities.id "#; let (model_names,): (String,) = - sqlx::query_as(models_query).bind(id).fetch_one(&pool).await?; + sqlx::query_as(models_query).bind(hashed_keys).fetch_one(&pool).await?; let model_names: Vec<&str> = model_names.split(',').collect(); let schemas = cache.schemas(model_names).await?; + let entity_query = format!("{} WHERE entities.id = ?", build_sql_query(&schemas)?); - let row = sqlx::query(&entity_query).bind(id).fetch_one(&pool).await?; + let row = sqlx::query(&entity_query).bind(hashed_keys).fetch_one(&pool).await?; let models = schemas .iter() @@ -115,7 +116,7 @@ impl Service { let resp = proto::world::SubscribeEntityResponse { entity: Some(proto::types::Entity { - id: felt_id.to_bytes_be().to_vec(), + hashed_keys: hashed.to_bytes_be().to_vec(), models, }), }; diff --git a/crates/torii/grpc/src/types/schema.rs b/crates/torii/grpc/src/types/schema.rs index 63d6adce8d..ecb97f0a5c 100644 --- a/crates/torii/grpc/src/types/schema.rs +++ b/crates/torii/grpc/src/types/schema.rs @@ -8,7 +8,7 @@ use crate::proto::{self}; #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct Entity { - pub id: FieldElement, + pub hashed_keys: FieldElement, pub models: Vec, } @@ -22,7 +22,8 @@ impl TryFrom for Entity { type Error = ClientError; fn try_from(entity: proto::types::Entity) -> Result { Ok(Self { - id: FieldElement::from_byte_slice_be(&entity.id).map_err(ClientError::SliceError)?, + hashed_keys: FieldElement::from_byte_slice_be(&entity.hashed_keys) + .map_err(ClientError::SliceError)?, models: entity .models .into_iter() From f61e50c37fd666abe2af2064bfcf97ade530a4cf Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 11:32:37 -0500 Subject: [PATCH 05/42] Improve platform specific builds --- .devcontainer/Dockerfile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f8542075ff..df398efd00 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,9 +1,8 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust/.devcontainer/base.Dockerfile # [Choice] Debian OS version (use bookworm on local arm64/Apple Silicon): buster, bullseye, bookworm -ARG VARIANT -ARG TARGETPLATFORM +ARG VARIANT FROM mcr.microsoft.com/vscode/devcontainers/rust:${VARIANT} # Install additional packages @@ -25,14 +24,17 @@ RUN rustup toolchain install $(cat rust-toolchain.toml | grep channel | cut -d\" RUN rustup target add x86_64-pc-windows-msvc && \ rustup target add wasm32-unknown-unknown -RUN rustup toolchain install nightly && \ - rustup target add x86_64-fortanix-unknown-sgx --toolchain nightly - RUN cargo binstall cargo-nextest cargo-llvm-cov --secure -y + +ARG TARGETPLATFORM RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] ; then \ + echo "Running arm64 branch" && \ rustup component add llvm-tools-preview --toolchain 1.70.0-aarch64-unknown-linux-gnu; \ elif [ "$TARGETPLATFORM" = "linux/amd64" ] ; then \ - rustup component add llvm-tools-preview --toolchain 1.70.0-x86_64-unknown-linux-gnu; \ + echo "Running amd64 branch" && \ + rustup component add llvm-tools-preview --toolchain 1.70.0-x86_64-unknown-linux-gnu && \ + rustup toolchain install nightly && \ + rustup target add x86_64-fortanix-unknown-sgx --toolchain nightly; \ fi RUN curl -L https://install.dojoengine.org | bash @@ -41,4 +43,4 @@ ENV PATH=${PATH}:/root/.dojo/bin RUN dojoup RUN chown -R root:root /usr/local/cargo -RUN chmod -R 700 /usr/local/cargo \ No newline at end of file +RUN chmod -R 700 /usr/local/cargo From e2b151383c0747d0061d6d7f0c79ca3f2487bdd6 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 12:09:55 -0500 Subject: [PATCH 06/42] Update devcontainer image hash: f61e50c (#1303) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ea62ddc04c..44a84d32b9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust { "name": "Rust", - "image": "ghcr.io/dojoengine/dojo-dev:54f0635", + "image": "ghcr.io/dojoengine/dojo-dev:f61e50c", "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e795d84e4..36b36d16b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: test: runs-on: ubuntu-latest-4-cores container: - image: ghcr.io/dojoengine/dojo-dev:54f0635 + image: ghcr.io/dojoengine/dojo-dev:f61e50c steps: - uses: actions/checkout@v3 with: From e0220426af212c6d904a54c14c0e247bf2c9b703 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 13:49:44 -0500 Subject: [PATCH 07/42] Integrate code coverage (#1296) --- .github/workflows/ci.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36b36d16b6..647d807bcc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ env: jobs: test: - runs-on: ubuntu-latest-4-cores + runs-on: ubuntu-latest-16-cores container: image: ghcr.io/dojoengine/dojo-dev:f61e50c steps: @@ -20,7 +20,12 @@ jobs: with: fetch-depth: 0 - uses: Swatinem/rust-cache@v2 - - run: cargo nextest run --all-features + - run: cargo llvm-cov nextest --all-features --lcov --output-path lcov.info + - uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: lcov.info + fail_ci_if_error: true ensure-wasm: runs-on: ubuntu-latest From 8dfe3002a05c93233366b8f82ab202919c20232e Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 13:56:50 -0500 Subject: [PATCH 08/42] Install cargo-release in devcontainer --- .devcontainer/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index df398efd00..7afa869fce 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -24,8 +24,9 @@ RUN rustup toolchain install $(cat rust-toolchain.toml | grep channel | cut -d\" RUN rustup target add x86_64-pc-windows-msvc && \ rustup target add wasm32-unknown-unknown -RUN cargo binstall cargo-nextest cargo-llvm-cov --secure -y +RUN cargo binstall cargo-nextest cargo-llvm-cov cargo-release --secure -y +# Platform specific tooling ARG TARGETPLATFORM RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] ; then \ echo "Running arm64 branch" && \ From 64b88aa56e544f89add6ca4ff1c1c81ae84c60fe Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 14:20:29 -0500 Subject: [PATCH 09/42] Add nightly rustfmt to devcontainer --- .devcontainer/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7afa869fce..efe6f0053e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -21,6 +21,9 @@ RUN rustup toolchain install $(cat rust-toolchain.toml | grep channel | cut -d\" rustup component add clippy && \ rustup component add rustfmt +RUN rustup toolchain install nightly && \ + rustup component add rustfmt --toolchain nightly + RUN rustup target add x86_64-pc-windows-msvc && \ rustup target add wasm32-unknown-unknown From f6a4b8a71ad668a31b987a4eda811107c5cab523 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 14:20:57 -0500 Subject: [PATCH 10/42] Add hurl to devcontainer (#1306) --- .devcontainer/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index efe6f0053e..4cbbfac4ea 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -32,10 +32,12 @@ RUN cargo binstall cargo-nextest cargo-llvm-cov cargo-release --secure -y # Platform specific tooling ARG TARGETPLATFORM RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] ; then \ - echo "Running arm64 branch" && \ + curl -L https://github.com/Orange-OpenSource/hurl/releases/download/4.1.0/hurl-4.1.0-aarch64-unknown-linux-gnu.tar.gz -o hurl.tar.gz && \ + tar -xzf hurl.tar.gz -C /usr/local/bin && rm hurl.tar.gz && \ rustup component add llvm-tools-preview --toolchain 1.70.0-aarch64-unknown-linux-gnu; \ elif [ "$TARGETPLATFORM" = "linux/amd64" ] ; then \ - echo "Running amd64 branch" && \ + curl -L https://github.com/Orange-OpenSource/hurl/releases/download/4.1.0/hurl-4.1.0-x86_64-unknown-linux-gnu.tar.gz -o hurl.tar.gz && \ + tar -xzf hurl.tar.gz -C /usr/local/bin && rm hurl.tar.gz && \ rustup component add llvm-tools-preview --toolchain 1.70.0-x86_64-unknown-linux-gnu && \ rustup toolchain install nightly && \ rustup target add x86_64-fortanix-unknown-sgx --toolchain nightly; \ From e1ba4a6bf4fddf0701762d07cc81feb3c7e23924 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 14:40:45 -0500 Subject: [PATCH 11/42] Update devcontainer image hash: f6a4b8a (#1305) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 44a84d32b9..595a1a5d37 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust { "name": "Rust", - "image": "ghcr.io/dojoengine/dojo-dev:f61e50c", + "image": "ghcr.io/dojoengine/dojo-dev:f6a4b8a", "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 647d807bcc..0a670f3a19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: test: runs-on: ubuntu-latest-16-cores container: - image: ghcr.io/dojoengine/dojo-dev:f61e50c + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 with: From 2e8cd6268b111632643441757d864b6f6214a141 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 15:09:39 -0500 Subject: [PATCH 12/42] Update ci to use devcontainer (#1304) --- .devcontainer/Dockerfile | 1 - .github/workflows/ci.yml | 69 +++++++++++----------------------------- 2 files changed, 18 insertions(+), 52 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 4cbbfac4ea..39ed05f851 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -39,7 +39,6 @@ RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] ; then \ curl -L https://github.com/Orange-OpenSource/hurl/releases/download/4.1.0/hurl-4.1.0-x86_64-unknown-linux-gnu.tar.gz -o hurl.tar.gz && \ tar -xzf hurl.tar.gz -C /usr/local/bin && rm hurl.tar.gz && \ rustup component add llvm-tools-preview --toolchain 1.70.0-x86_64-unknown-linux-gnu && \ - rustup toolchain install nightly && \ rustup target add x86_64-fortanix-unknown-sgx --toolchain nightly; \ fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a670f3a19..b4d27a45fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,17 +29,12 @@ jobs: ensure-wasm: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v2 - - name: "Ensure `torii-client` crate is WASM-able" - run: | - cargo build -r --target wasm32-unknown-unknown -p torii-client + - run: cargo build -r --target wasm32-unknown-unknown -p torii-client ensure-windows: runs-on: windows-latest @@ -51,9 +46,7 @@ jobs: target: x86_64-pc-windows-msvc - uses: Swatinem/rust-cache@v2 - uses: arduino/setup-protoc@v2 - - name: "Ensure buildable on windows" - run: | - cargo build --target x86_64-pc-windows-msvc --bins + - run: cargo build --target x86_64-pc-windows-msvc --bins # cairofmt: # runs-on: ubuntu-latest @@ -69,92 +62,66 @@ jobs: dojo-core-test: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v2 - run: cargo run --bin sozo -- --manifest-path crates/dojo-core/Scarb.toml test dojo-spawn-and-move-example-test: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v2 - run: cargo run --bin sozo -- --manifest-path examples/spawn-and-move/Scarb.toml test clippy: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - targets: wasm32-unknown-unknown - components: clippy - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - run: scripts/clippy.sh fmt: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - components: rustfmt - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - run: scripts/rust_fmt.sh --check docs: runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - uses: arduino/setup-protoc@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - run: > scripts/docs.sh test-hurl: runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - name: Checkout code - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.RUST_VERSION }} - uses: Swatinem/rust-cache@v2 - - name: Install Hurl - run: | + - run: | curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/3.0.0/hurl_3.0.0_amd64.deb sudo apt update && sudo apt install ./hurl_3.0.0_amd64.deb - - name: Build and start Katana node - run: | + - run: | cargo build --bin katana nohup target/debug/katana --accounts 2 --disable-fee & - - name: Execute Hurl Scripts - run: hurl --test examples/rpc/**/*.hurl + - run: hurl --test examples/rpc/**/*.hurl From 76decd2b5acd3573f42dbda128d049fe72f713f6 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 16:12:01 -0500 Subject: [PATCH 13/42] Update devcontainer image hash: 2e8cd62 (#1307) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/ci.yml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 595a1a5d37..07a8709a21 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust { "name": "Rust", - "image": "ghcr.io/dojoengine/dojo-dev:f6a4b8a", + "image": "ghcr.io/dojoengine/dojo-dev:2e8cd62", "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4d27a45fc..0fc1e4c1e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: test: runs-on: ubuntu-latest-16-cores container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 with: @@ -30,7 +30,7 @@ jobs: ensure-wasm: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -63,7 +63,7 @@ jobs: dojo-core-test: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -72,7 +72,7 @@ jobs: dojo-spawn-and-move-example-test: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -81,7 +81,7 @@ jobs: clippy: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 with: @@ -92,7 +92,7 @@ jobs: fmt: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -101,7 +101,7 @@ jobs: docs: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:2e8cd62 steps: - uses: actions/checkout@v3 with: From ed6e29e243e3834696fba005f229de1dc6e2f180 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 16:23:29 -0500 Subject: [PATCH 14/42] Prepare for cargo release (#1308) * Prepare for cargo release * Add release-dispatch job * Update all devcontainers --- .cargo/config.toml | 2 ++ .github/workflows/devcontainer.yml | 7 +++++-- .github/workflows/release-dispatch.yml | 24 ++++++++++++++++++++++++ Cargo.lock | 8 ++++++++ Cargo.toml | 2 ++ crates/dojo-core/Cargo.toml | 15 +++++++++++++++ crates/dojo-core/src/lib.rs | 1 + examples/spawn-and-move/Cargo.toml | 15 +++++++++++++++ examples/spawn-and-move/src/lib.rs | 1 + scripts/prepare_release.sh | 14 -------------- 10 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 .github/workflows/release-dispatch.yml create mode 100644 crates/dojo-core/Cargo.toml create mode 100644 crates/dojo-core/src/lib.rs create mode 100644 examples/spawn-and-move/Cargo.toml create mode 100644 examples/spawn-and-move/src/lib.rs delete mode 100755 scripts/prepare_release.sh diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000..8595a0cb48 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[registries.crates-io] +protocol = "git" \ No newline at end of file diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml index da93787b8b..c67c99e18b 100644 --- a/.github/workflows/devcontainer.yml +++ b/.github/workflows/devcontainer.yml @@ -71,8 +71,11 @@ jobs: - name: Update devcontainer.json run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json - - name: Update ci devcontainers - run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .github/workflows/ci.yml + - name: Update github action devcontainers + run: | + for file in .github/workflows/*.yml; do + sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" + done - name: Create Pull Request uses: peter-evans/create-pull-request@v3 diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml new file mode 100644 index 0000000000..2d8eee4717 --- /dev/null +++ b/.github/workflows/release-dispatch.yml @@ -0,0 +1,24 @@ +name: Test release-rust +on: + workflow_dispatch: + inputs: + version: + description: Version to release + required: true + type: string + +jobs: + release: + permissions: + id-token: write # Enable OIDC + pull-requests: write + contents: write + runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + steps: + - uses: actions/checkout@v3 + - uses: cargo-bins/release-pr@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version: ${{ inputs.version }} diff --git a/Cargo.lock b/Cargo.lock index 974617abcc..31c5320c5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2621,6 +2621,14 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dojo-core" +version = "0.4.1" + +[[package]] +name = "dojo-examples-spawn-and-move" +version = "0.4.1" + [[package]] name = "dojo-lang" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 560574e454..e3789f8627 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "crates/benches", + "crates/dojo-core", "crates/dojo-lang", "crates/dojo-language-server", "crates/dojo-signers", @@ -25,6 +26,7 @@ members = [ "crates/sozo", "crates/torii/client", "crates/torii/server", + "examples/spawn-and-move", ] [workspace.package] diff --git a/crates/dojo-core/Cargo.toml b/crates/dojo-core/Cargo.toml new file mode 100644 index 0000000000..803b077f0b --- /dev/null +++ b/crates/dojo-core/Cargo.toml @@ -0,0 +1,15 @@ +[package] +edition.workspace = true +license-file.workspace = true +name = "dojo-core" +repository.workspace = true +version.workspace = true + +[package.metadata.release] +pre-release-replacements = [ + { file = "Scarb.lock", search = "^name = \"dojo\"\nversion = \".*\"$", replace = "name = \"dojo\"\nversion = \"{{version}}\"", min = 1 }, + { file = "Scarb.toml", search = "^version = \".*\"$", replace = "version = \"{{version}}\"", min = 1 }, +] + +[lib] +path = "src/lib.rs" diff --git a/crates/dojo-core/src/lib.rs b/crates/dojo-core/src/lib.rs new file mode 100644 index 0000000000..4199cceb5f --- /dev/null +++ b/crates/dojo-core/src/lib.rs @@ -0,0 +1 @@ +// Placeholder so we can use `cargo release` to update Scarb.toml diff --git a/examples/spawn-and-move/Cargo.toml b/examples/spawn-and-move/Cargo.toml new file mode 100644 index 0000000000..1e257978ef --- /dev/null +++ b/examples/spawn-and-move/Cargo.toml @@ -0,0 +1,15 @@ +[package] +edition.workspace = true +license-file.workspace = true +name = "dojo-examples-spawn-and-move" +repository.workspace = true +version.workspace = true + +[package.metadata.release] +pre-release-replacements = [ + { file = "Scarb.lock", search = "^name = \"dojo\"\nversion = \".*\"$", replace = "name = \"dojo\"\nversion = \"{{version}}\"", min = 1 }, + { file = "Scarb.toml", search = "^version = \".*\"$", replace = "version = \"{{version}}\"", min = 1 }, +] + +[lib] +path = "src/lib.rs" diff --git a/examples/spawn-and-move/src/lib.rs b/examples/spawn-and-move/src/lib.rs new file mode 100644 index 0000000000..4199cceb5f --- /dev/null +++ b/examples/spawn-and-move/src/lib.rs @@ -0,0 +1 @@ +// Placeholder so we can use `cargo release` to update Scarb.toml diff --git a/scripts/prepare_release.sh b/scripts/prepare_release.sh deleted file mode 100755 index def15d4949..0000000000 --- a/scripts/prepare_release.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -euxo pipefail - -prev_version=$(cargo get workspace.package.version) -next_version=$1 - -find . -type f -name "*.toml" -exec sed -i "" "s/version = \"$prev_version\"/version = \"$next_version\"/g" {} \; -find . -type f -name "*.toml" -exec sed -i "" "s/dojo_plugin = \"$prev_version\"/dojo_plugin = \"$next_version\"/g" {} \; - -scripts/clippy.sh - -git commit -am "Prepare v$1" -git tag -a "v$1" -m "Version $1" -# git push origin --tags \ No newline at end of file From 5cc0589a4a6755e068d9bddb0fa32b1926709839 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 16:24:48 -0500 Subject: [PATCH 15/42] Fix action names for consistency --- .github/workflows/cargo-udeps.yml | 2 +- .github/workflows/release-dispatch.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cargo-udeps.yml b/.github/workflows/cargo-udeps.yml index 0e0ebdd7a3..656b097b03 100644 --- a/.github/workflows/cargo-udeps.yml +++ b/.github/workflows/cargo-udeps.yml @@ -1,4 +1,4 @@ -name: Unused dependencies +name: cargo-udeps on: schedule: diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 2d8eee4717..94e45b3606 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -1,4 +1,4 @@ -name: Test release-rust +name: release-dispatch on: workflow_dispatch: inputs: From 67cfbfb4cd3bbc3c8239cf7444b1f35e9fc7aaf5 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 16:37:01 -0500 Subject: [PATCH 16/42] Fix release dispatch --- .github/workflows/release-dispatch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 94e45b3606..ae20767efd 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -22,3 +22,4 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} version: ${{ inputs.version }} + crate-release-all: true From 890bbced1ac8745cbcfe6c67a30730fa03808b40 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 16:42:32 -0500 Subject: [PATCH 17/42] Sync crate versions with workspace --- Cargo.lock | 10 +++++----- crates/benches/Cargo.toml | 2 +- crates/katana/runner/Cargo.toml | 4 ++-- crates/metrics/Cargo.toml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31c5320c5d..c0d2ef86ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,7 +801,7 @@ dependencies = [ [[package]] name = "benches" -version = "0.1.0" +version = "0.4.1" dependencies = [ "anyhow", "clap_builder", @@ -5401,7 +5401,7 @@ dependencies = [ "console", "katana-core", "katana-rpc", - "metrics 0.1.0", + "metrics 0.4.1", "metrics-process", "serde_json", "starknet_api", @@ -5598,7 +5598,7 @@ dependencies = [ [[package]] name = "katana-runner" -version = "0.1.0" +version = "0.4.1" dependencies = [ "anyhow", "home", @@ -5889,7 +5889,7 @@ dependencies = [ [[package]] name = "metrics" -version = "0.1.0" +version = "0.4.1" dependencies = [ "anyhow", "hyper", @@ -9910,7 +9910,7 @@ dependencies = [ "hyper-reverse-proxy", "indexmap 1.9.3", "lazy_static", - "metrics 0.1.0", + "metrics 0.4.1", "metrics-process", "scarb", "serde", diff --git a/crates/benches/Cargo.toml b/crates/benches/Cargo.toml index 010ab448f7..4a8720e2bd 100644 --- a/crates/benches/Cargo.toml +++ b/crates/benches/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "benches" -version = "0.1.0" +version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/katana/runner/Cargo.toml b/crates/katana/runner/Cargo.toml index e74d612b43..a17bb83616 100644 --- a/crates/katana/runner/Cargo.toml +++ b/crates/katana/runner/Cargo.toml @@ -1,7 +1,7 @@ [package] +edition.workspace = true name = "katana-runner" -version = "0.1.0" -edition = "2021" +version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/metrics/Cargo.toml b/crates/metrics/Cargo.toml index 4e740cd611..d351b39341 100644 --- a/crates/metrics/Cargo.toml +++ b/crates/metrics/Cargo.toml @@ -1,7 +1,7 @@ [package] -edition = "2021" +edition.workspace = true name = "metrics" -version = "0.1.0" +version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 54a949910aeda279c835685c24e2b14d00908a19 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 17:19:05 -0500 Subject: [PATCH 18/42] Simplify release dispatch --- .cargo/config.toml | 2 -- .github/workflows/release-dispatch.yml | 13 ++++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 8595a0cb48..0000000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[registries.crates-io] -protocol = "git" \ No newline at end of file diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index ae20767efd..5e605a9b6f 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -10,7 +10,6 @@ on: jobs: release: permissions: - id-token: write # Enable OIDC pull-requests: write contents: write runs-on: ubuntu-latest @@ -18,8 +17,12 @@ jobs: image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: - uses: actions/checkout@v3 - - uses: cargo-bins/release-pr@v2 + - run: cargo release ${{ inputs.version }} --no-publish --no-verify --execute + - uses: peter-evans/create-pull-request@v3 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - version: ${{ inputs.version }} - crate-release-all: true + token: ${{ secrets.GITHUB_TOKEN }} + title: "Prepare release: ${{ inputs.version }}" + commit-message: "Prepare release: ${{ inputs.version }}" + branch: prepare-release + base: main + delete-branch: true From a5cd5537e06e74145dd01a8acfff71c73839f640 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 17:22:08 -0500 Subject: [PATCH 19/42] Update devcontainer ci to not match self --- .github/workflows/devcontainer.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml index c67c99e18b..83269f822a 100644 --- a/.github/workflows/devcontainer.yml +++ b/.github/workflows/devcontainer.yml @@ -69,12 +69,12 @@ jobs: uses: actions/checkout@v2 - name: Update devcontainer.json - run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json + run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json - name: Update github action devcontainers run: | for file in .github/workflows/*.yml; do - sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" + sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" done - name: Create Pull Request From 32e6bb0ea91be6f32c79587d1c0f468571c0ddba Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 17:24:38 -0500 Subject: [PATCH 20/42] Set safe repo for release dispatcher --- .github/workflows/release-dispatch.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 5e605a9b6f..6f06d3c61c 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -16,6 +16,8 @@ jobs: container: image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: + # Workaround described here: https://github.com/actions/checkout/issues/760 + - run: git config --global --add safe.directory /__w/dojo/dojo/ - uses: actions/checkout@v3 - run: cargo release ${{ inputs.version }} --no-publish --no-verify --execute - uses: peter-evans/create-pull-request@v3 From 9a0421fde06ef348a88de29418bebd30bb13cc3f Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 17:43:13 -0500 Subject: [PATCH 21/42] Use version + replace rather then release --- .github/workflows/release-dispatch.yml | 6 +-- Cargo.lock | 60 +++++++++++++------------- Cargo.toml | 2 +- crates/dojo-core/Scarb.lock | 2 +- crates/dojo-core/Scarb.toml | 2 +- examples/spawn-and-move/Scarb.lock | 2 +- examples/spawn-and-move/Scarb.toml | 2 +- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 6f06d3c61c..bcaef6e148 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -17,10 +17,10 @@ jobs: image: ghcr.io/dojoengine/dojo-dev:f6a4b8a steps: # Workaround described here: https://github.com/actions/checkout/issues/760 - - run: git config --global --add safe.directory /__w/dojo/dojo/ - uses: actions/checkout@v3 - - run: cargo release ${{ inputs.version }} --no-publish --no-verify --execute - - uses: peter-evans/create-pull-request@v3 + - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm + - uses: peter-evans/create-pull-request@v5 with: token: ${{ secrets.GITHUB_TOKEN }} title: "Prepare release: ${{ inputs.version }}" diff --git a/Cargo.lock b/Cargo.lock index c0d2ef86ef..2a8b652c6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,7 +801,7 @@ dependencies = [ [[package]] name = "benches" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "clap_builder", @@ -2623,15 +2623,15 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dojo-core" -version = "0.4.1" +version = "0.4.2" [[package]] name = "dojo-examples-spawn-and-move" -version = "0.4.1" +version = "0.4.2" [[package]] name = "dojo-lang" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2679,7 +2679,7 @@ dependencies = [ [[package]] name = "dojo-language-server" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "dojo-signers" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "starknet", @@ -2709,7 +2709,7 @@ dependencies = [ [[package]] name = "dojo-test-utils" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -2740,7 +2740,7 @@ dependencies = [ [[package]] name = "dojo-types" -version = "0.4.1" +version = "0.4.2" dependencies = [ "crypto-bigint", "hex", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "dojo-world" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -5393,7 +5393,7 @@ dependencies = [ [[package]] name = "katana" -version = "0.4.1" +version = "0.4.2" dependencies = [ "assert_matches", "clap", @@ -5401,7 +5401,7 @@ dependencies = [ "console", "katana-core", "katana-rpc", - "metrics 0.4.1", + "metrics 0.4.2", "metrics-process", "serde_json", "starknet_api", @@ -5413,7 +5413,7 @@ dependencies = [ [[package]] name = "katana-codecs" -version = "0.4.1" +version = "0.4.2" dependencies = [ "bytes", "katana-primitives", @@ -5421,7 +5421,7 @@ dependencies = [ [[package]] name = "katana-codecs-derive" -version = "0.4.1" +version = "0.4.2" dependencies = [ "proc-macro2", "quote", @@ -5431,7 +5431,7 @@ dependencies = [ [[package]] name = "katana-core" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_matches", @@ -5464,7 +5464,7 @@ dependencies = [ [[package]] name = "katana-db" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "bincode 1.3.3", @@ -5487,7 +5487,7 @@ dependencies = [ [[package]] name = "katana-executor" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "blockifier", @@ -5503,7 +5503,7 @@ dependencies = [ [[package]] name = "katana-primitives" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "blockifier", @@ -5521,7 +5521,7 @@ dependencies = [ [[package]] name = "katana-provider" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "auto_impl", @@ -5541,7 +5541,7 @@ dependencies = [ [[package]] name = "katana-rpc" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_matches", @@ -5573,7 +5573,7 @@ dependencies = [ [[package]] name = "katana-rpc-types" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "derive_more", @@ -5586,7 +5586,7 @@ dependencies = [ [[package]] name = "katana-rpc-types-builder" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "katana-executor", @@ -5598,7 +5598,7 @@ dependencies = [ [[package]] name = "katana-runner" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "home", @@ -5889,7 +5889,7 @@ dependencies = [ [[package]] name = "metrics" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "hyper", @@ -8558,7 +8558,7 @@ dependencies = [ [[package]] name = "sozo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -9752,7 +9752,7 @@ dependencies = [ [[package]] name = "torii-client" -version = "0.4.1" +version = "0.4.2" dependencies = [ "async-trait", "camino", @@ -9778,7 +9778,7 @@ dependencies = [ [[package]] name = "torii-core" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", @@ -9814,7 +9814,7 @@ dependencies = [ [[package]] name = "torii-graphql" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-graphql", @@ -9853,7 +9853,7 @@ dependencies = [ [[package]] name = "torii-grpc" -version = "0.4.1" +version = "0.4.2" dependencies = [ "bytes", "crypto-bigint", @@ -9891,7 +9891,7 @@ dependencies = [ [[package]] name = "torii-server" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", @@ -9910,7 +9910,7 @@ dependencies = [ "hyper-reverse-proxy", "indexmap 1.9.3", "lazy_static", - "metrics 0.4.1", + "metrics 0.4.2", "metrics-process", "scarb", "serde", diff --git a/Cargo.toml b/Cargo.toml index e3789f8627..bedca48a7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ edition = "2021" license = "Apache-2.0" license-file = "LICENSE" repository = "https://github.com/dojoengine/dojo/" -version = "0.4.1" +version = "0.4.2" [profile.performance] codegen-units = 1 diff --git a/crates/dojo-core/Scarb.lock b/crates/dojo-core/Scarb.lock index ee17c212ea..14d33d1dbb 100644 --- a/crates/dojo-core/Scarb.lock +++ b/crates/dojo-core/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/crates/dojo-core/Scarb.toml b/crates/dojo-core/Scarb.toml index a8809ef181..ef1080e43a 100644 --- a/crates/dojo-core/Scarb.toml +++ b/crates/dojo-core/Scarb.toml @@ -2,7 +2,7 @@ cairo-version = "2.4.0" description = "The Dojo Core library for autonomous worlds." name = "dojo" -version = "0.4.1" +version = "0.4.2" [dependencies] dojo_plugin = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.11" } diff --git a/examples/spawn-and-move/Scarb.lock b/examples/spawn-and-move/Scarb.lock index 9474cc125c..36fbad6d54 100644 --- a/examples/spawn-and-move/Scarb.lock +++ b/examples/spawn-and-move/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/examples/spawn-and-move/Scarb.toml b/examples/spawn-and-move/Scarb.toml index ec78dec2d8..2383af1a8e 100644 --- a/examples/spawn-and-move/Scarb.toml +++ b/examples/spawn-and-move/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "dojo_examples" -version = "0.4.0-rc0" +version = "0.4.2" # Use the prelude with the less imports as possible # from corelib. edition = "2023_10" From 9c6be5b6a5fb7a7f86d98e62f7c489b41e0d2a3f Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 20:34:40 -0500 Subject: [PATCH 22/42] Install cargo-get in devcontainer --- .devcontainer/Dockerfile | 2 +- .github/workflows/devcontainer.yml | 10 ++++++---- .github/workflows/release-dispatch.yml | 5 +++-- .github/workflows/release.yml | 3 --- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 39ed05f851..4b3c3e20c4 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -27,7 +27,7 @@ RUN rustup toolchain install nightly && \ RUN rustup target add x86_64-pc-windows-msvc && \ rustup target add wasm32-unknown-unknown -RUN cargo binstall cargo-nextest cargo-llvm-cov cargo-release --secure -y +RUN cargo binstall cargo-get cargo-nextest cargo-llvm-cov cargo-release --secure -y # Platform specific tooling ARG TARGETPLATFORM diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml index 83269f822a..85bc551e9c 100644 --- a/.github/workflows/devcontainer.yml +++ b/.github/workflows/devcontainer.yml @@ -63,10 +63,12 @@ jobs: needs: build-and-push runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' + permissions: + pull-requests: write + contents: write steps: - - name: Checkout repository - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - name: Update devcontainer.json run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json @@ -77,9 +79,9 @@ jobs: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" done - - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 + - uses: peter-evans/create-pull-request@v5 with: + # We have to use a PAT in order to trigger ci token: ${{ secrets.CREATE_PR_TOKEN }} title: "Update devcontainer image hash: ${{ needs.build-and-push.outputs.tag_name }}" commit-message: "Update devcontainer image hash: ${{ needs.build-and-push.outputs.tag_name }}" diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index bcaef6e148..0f1eafc57d 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -8,7 +8,7 @@ on: type: string jobs: - release: + propose-release: permissions: pull-requests: write contents: write @@ -22,7 +22,8 @@ jobs: - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm - uses: peter-evans/create-pull-request@v5 with: - token: ${{ secrets.GITHUB_TOKEN }} + # We have to use a PAT in order to trigger ci + token: ${{ secrets.CREATE_PR_TOKEN }} title: "Prepare release: ${{ inputs.version }}" commit-message: "Prepare release: ${{ inputs.version }}" branch: prepare-release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef0597e95e..a1af6f7d2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -252,9 +252,6 @@ jobs: name: binaries path: artifacts/linux - - name: Display structure of downloaded files - run: ls -R - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 From 5ab298bd681dbea453040908def9a22212d5f602 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 20:41:44 -0500 Subject: [PATCH 23/42] Install gh and fix hurl in devcontainer --- .devcontainer/Dockerfile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 4b3c3e20c4..29720815d3 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -9,7 +9,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/rust:${VARIANT} RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends protobuf-compiler libprotobuf-dev libclang-dev -RUN apt install -y libgmp3-dev +RUN apt install -y gh libgmp3-dev COPY rust-toolchain.toml . @@ -33,11 +33,17 @@ RUN cargo binstall cargo-get cargo-nextest cargo-llvm-cov cargo-release --secure ARG TARGETPLATFORM RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] ; then \ curl -L https://github.com/Orange-OpenSource/hurl/releases/download/4.1.0/hurl-4.1.0-aarch64-unknown-linux-gnu.tar.gz -o hurl.tar.gz && \ - tar -xzf hurl.tar.gz -C /usr/local/bin && rm hurl.tar.gz && \ + tar -xzf hurl.tar.gz && \ + mv hurl-4.1.0-aarch64-unknown-linux-gnu/hurl /usr/local/bin/ && \ + rm -r hurl-4.1.0-aarch64-unknown-linux-gnu && \ + rm hurl.tar.gz && \ rustup component add llvm-tools-preview --toolchain 1.70.0-aarch64-unknown-linux-gnu; \ elif [ "$TARGETPLATFORM" = "linux/amd64" ] ; then \ curl -L https://github.com/Orange-OpenSource/hurl/releases/download/4.1.0/hurl-4.1.0-x86_64-unknown-linux-gnu.tar.gz -o hurl.tar.gz && \ - tar -xzf hurl.tar.gz -C /usr/local/bin && rm hurl.tar.gz && \ + tar -xzf hurl.tar.gz && \ + mv hurl-4.1.0-x86_64-unknown-linux-gnu/hurl /usr/local/bin/ && \ + rm -r hurl-4.1.0-x86_64-unknown-linux-gnu && \ + rm hurl.tar.gz && \ rustup component add llvm-tools-preview --toolchain 1.70.0-x86_64-unknown-linux-gnu && \ rustup target add x86_64-fortanix-unknown-sgx --toolchain nightly; \ fi From 448ffdad3aa43c4b013f7a26b4251dcc6c3d1c65 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 21:15:02 -0500 Subject: [PATCH 24/42] Fix devcontainer update regex --- .devcontainer/devcontainer.json | 6 +----- .github/workflows/devcontainer.yml | 6 ++++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 07a8709a21..7f3c1db4b2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -34,13 +34,9 @@ }, // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "rustc --version", - // "postCreateCommand": ". scripts/startup.sh", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // "remoteUser": "vscode", "remoteEnv": { "PATH": "${containerEnv:PATH}:/workspace/dojo/target/release:/home/vscode/.dojo/bin" - }, - "postCreateCommand": "dojoup/dojoup && cargo install cargo-nextest" + } } \ No newline at end of file diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml index 85bc551e9c..2f238d2789 100644 --- a/.github/workflows/devcontainer.yml +++ b/.github/workflows/devcontainer.yml @@ -71,12 +71,14 @@ jobs: - uses: actions/checkout@v2 - name: Update devcontainer.json - run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json + run: sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" .devcontainer/devcontainer.json - name: Update github action devcontainers run: | for file in .github/workflows/*.yml; do - sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]+|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" + if [[ $file != ".github/workflows/devcontainer.yml" ]]; then + sed -i "s|ghcr.io/dojoengine/dojo-dev:[a-zA-Z0-9._-]*|ghcr.io/dojoengine/dojo-dev:${{ needs.build-and-push.outputs.tag_name }}|" "$file" + fi done - uses: peter-evans/create-pull-request@v5 From e8a556f267206f3f46d5894d79bb93c783b3309b Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 21:48:50 -0500 Subject: [PATCH 25/42] Update devcontainer image hash: 448ffda (#1313) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/release-dispatch.yml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7f3c1db4b2..08adc14f5d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust { "name": "Rust", - "image": "ghcr.io/dojoengine/dojo-dev:2e8cd62", + "image": "ghcr.io/dojoengine/dojo-dev:448ffda", "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fc1e4c1e5..f1d949da2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: test: runs-on: ubuntu-latest-16-cores container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 with: @@ -30,7 +30,7 @@ jobs: ensure-wasm: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -63,7 +63,7 @@ jobs: dojo-core-test: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -72,7 +72,7 @@ jobs: dojo-spawn-and-move-example-test: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -81,7 +81,7 @@ jobs: clippy: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 with: @@ -92,7 +92,7 @@ jobs: fmt: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - uses: Swatinem/rust-cache@v2 @@ -101,7 +101,7 @@ jobs: docs: runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:2e8cd62 + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 with: diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 0f1eafc57d..60585445d5 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -14,7 +14,7 @@ jobs: contents: write runs-on: ubuntu-latest container: - image: ghcr.io/dojoengine/dojo-dev:f6a4b8a + image: ghcr.io/dojoengine/dojo-dev:448ffda steps: # Workaround described here: https://github.com/actions/checkout/issues/760 - uses: actions/checkout@v3 From 065dcc961c12523f92e88d76976554a87d179da6 Mon Sep 17 00:00:00 2001 From: Yun Date: Mon, 18 Dec 2023 18:51:52 -0800 Subject: [PATCH 26/42] Move types-test to torii root (#1311) --- crates/dojo-test-utils/build.rs | 2 +- crates/torii/graphql/src/tests/mod.rs | 14 +++++++++----- .../{graphql/src/tests => }/types-test/Scarb.lock | 2 +- .../{graphql/src/tests => }/types-test/Scarb.toml | 2 +- .../src/tests => }/types-test/assets/cover.png | Bin .../src/tests => }/types-test/assets/icon.png | Bin .../src/tests => }/types-test/src/contracts.cairo | 0 .../src/tests => }/types-test/src/lib.cairo | 0 .../src/tests => }/types-test/src/models.cairo | 0 9 files changed, 12 insertions(+), 8 deletions(-) rename crates/torii/{graphql/src/tests => }/types-test/Scarb.lock (94%) rename crates/torii/{graphql/src/tests => }/types-test/Scarb.toml (93%) rename crates/torii/{graphql/src/tests => }/types-test/assets/cover.png (100%) rename crates/torii/{graphql/src/tests => }/types-test/assets/icon.png (100%) rename crates/torii/{graphql/src/tests => }/types-test/src/contracts.cairo (100%) rename crates/torii/{graphql/src/tests => }/types-test/src/lib.cairo (100%) rename crates/torii/{graphql/src/tests => }/types-test/src/models.cairo (100%) diff --git a/crates/dojo-test-utils/build.rs b/crates/dojo-test-utils/build.rs index 3f6b9592f8..f80c57027d 100644 --- a/crates/dojo-test-utils/build.rs +++ b/crates/dojo-test-utils/build.rs @@ -11,7 +11,7 @@ fn main() { use scarb::ops::CompileOpts; use scarb_ui::Verbosity; - let project_paths = ["../../examples/spawn-and-move", "../torii/graphql/src/tests/types-test"]; + let project_paths = ["../../examples/spawn-and-move", "../torii/types-test"]; project_paths.iter().for_each(|path| compile(path)); diff --git a/crates/torii/graphql/src/tests/mod.rs b/crates/torii/graphql/src/tests/mod.rs index d6abd80668..793ece1473 100644 --- a/crates/torii/graphql/src/tests/mod.rs +++ b/crates/torii/graphql/src/tests/mod.rs @@ -10,6 +10,7 @@ use dojo_test_utils::sequencer::{ use dojo_types::primitive::Primitive; use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty}; use dojo_world::contracts::WorldContractReader; +use dojo_world::manifest::Manifest; use dojo_world::utils::TransactionWaiter; use scarb::ops; use serde::Deserialize; @@ -236,8 +237,8 @@ pub async fn spinup_types_test() -> Result { let pool = SqlitePoolOptions::new().max_connections(5).connect_with(options).await.unwrap(); sqlx::migrate!("../migrations").run(&pool).await.unwrap(); - let migration = prepare_migration("./src/tests/types-test/target/dev".into()).unwrap(); - let config = build_test_config("./src/tests/types-test/Scarb.toml").unwrap(); + let migration = prepare_migration("../types-test/target/dev".into()).unwrap(); + let config = build_test_config("../types-test/Scarb.toml").unwrap(); let mut db = Sql::new(pool.clone(), migration.world_address().unwrap()).await.unwrap(); let sequencer = @@ -253,13 +254,16 @@ pub async fn spinup_types_test() -> Result { execute_strategy(&ws, &migration, &account, None).await.unwrap(); - // Execute `create` and insert 10 records into storage + let manifest = + Manifest::load_from_remote(&provider, migration.world_address().unwrap()).await.unwrap(); - let records_contract = "0x7b44a597f4027588f226293105c77c99c436ab4016bbcb51f6711ab1ccfeeb0"; + // Execute `create` and insert 10 records into storage + let records_contract = + manifest.contracts.iter().find(|contract| contract.name.eq("records")).unwrap(); let InvokeTransactionResult { transaction_hash } = account .execute(vec![Call { calldata: vec![FieldElement::from_str("0xa").unwrap()], - to: FieldElement::from_str(records_contract).unwrap(), + to: records_contract.address.unwrap(), selector: selector!("create"), }]) .send() diff --git a/crates/torii/graphql/src/tests/types-test/Scarb.lock b/crates/torii/types-test/Scarb.lock similarity index 94% rename from crates/torii/graphql/src/tests/types-test/Scarb.lock rename to crates/torii/types-test/Scarb.lock index a61afd0460..4f2d7aa41c 100644 --- a/crates/torii/graphql/src/tests/types-test/Scarb.lock +++ b/crates/torii/types-test/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.0-rc0" +version = "0.4.1" dependencies = [ "dojo_plugin", ] diff --git a/crates/torii/graphql/src/tests/types-test/Scarb.toml b/crates/torii/types-test/Scarb.toml similarity index 93% rename from crates/torii/graphql/src/tests/types-test/Scarb.toml rename to crates/torii/types-test/Scarb.toml index 2b149d7306..28eb076fb8 100644 --- a/crates/torii/graphql/src/tests/types-test/Scarb.toml +++ b/crates/torii/types-test/Scarb.toml @@ -7,7 +7,7 @@ version = "0.1.0" sierra-replace-ids = true [dependencies] -dojo = { path = "../../../../../dojo-core" } +dojo = { path = "../../dojo-core" } [[target.dojo]] build-external-contracts = [] diff --git a/crates/torii/graphql/src/tests/types-test/assets/cover.png b/crates/torii/types-test/assets/cover.png similarity index 100% rename from crates/torii/graphql/src/tests/types-test/assets/cover.png rename to crates/torii/types-test/assets/cover.png diff --git a/crates/torii/graphql/src/tests/types-test/assets/icon.png b/crates/torii/types-test/assets/icon.png similarity index 100% rename from crates/torii/graphql/src/tests/types-test/assets/icon.png rename to crates/torii/types-test/assets/icon.png diff --git a/crates/torii/graphql/src/tests/types-test/src/contracts.cairo b/crates/torii/types-test/src/contracts.cairo similarity index 100% rename from crates/torii/graphql/src/tests/types-test/src/contracts.cairo rename to crates/torii/types-test/src/contracts.cairo diff --git a/crates/torii/graphql/src/tests/types-test/src/lib.cairo b/crates/torii/types-test/src/lib.cairo similarity index 100% rename from crates/torii/graphql/src/tests/types-test/src/lib.cairo rename to crates/torii/types-test/src/lib.cairo diff --git a/crates/torii/graphql/src/tests/types-test/src/models.cairo b/crates/torii/types-test/src/models.cairo similarity index 100% rename from crates/torii/graphql/src/tests/types-test/src/models.cairo rename to crates/torii/types-test/src/models.cairo From 85e92c3bc04d29b98fac62bcb3feeef51589cecc Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Mon, 18 Dec 2023 23:19:04 -0500 Subject: [PATCH 27/42] Add types-test to cargo release (#1314) --- Cargo.lock | 4 ++++ Cargo.toml | 1 + crates/torii/types-test/Cargo.toml | 15 +++++++++++++++ crates/torii/types-test/Scarb.lock | 2 +- crates/torii/types-test/Scarb.toml | 2 +- crates/torii/types-test/src/lib.rs | 1 + 6 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 crates/torii/types-test/Cargo.toml create mode 100644 crates/torii/types-test/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2a8b652c6c..05748eb8b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10176,6 +10176,10 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "types-test" +version = "0.4.2" + [[package]] name = "ucd-trie" version = "0.1.6" diff --git a/Cargo.toml b/Cargo.toml index bedca48a7d..1ece9cfe98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ members = [ "crates/sozo", "crates/torii/client", "crates/torii/server", + "crates/torii/types-test", "examples/spawn-and-move", ] diff --git a/crates/torii/types-test/Cargo.toml b/crates/torii/types-test/Cargo.toml new file mode 100644 index 0000000000..5f67ac8803 --- /dev/null +++ b/crates/torii/types-test/Cargo.toml @@ -0,0 +1,15 @@ +[package] +edition.workspace = true +license-file.workspace = true +name = "types-test" +repository.workspace = true +version.workspace = true + +[package.metadata.release] +pre-release-replacements = [ + { file = "Scarb.lock", search = "^name = \"dojo\"\nversion = \".*\"$", replace = "name = \"dojo\"\nversion = \"{{version}}\"", min = 1 }, + { file = "Scarb.toml", search = "^version = \".*\"$", replace = "version = \"{{version}}\"", min = 1 }, +] + +[lib] +path = "src/lib.rs" diff --git a/crates/torii/types-test/Scarb.lock b/crates/torii/types-test/Scarb.lock index 4f2d7aa41c..736f84366b 100644 --- a/crates/torii/types-test/Scarb.lock +++ b/crates/torii/types-test/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/crates/torii/types-test/Scarb.toml b/crates/torii/types-test/Scarb.toml index 28eb076fb8..ac5bfa187f 100644 --- a/crates/torii/types-test/Scarb.toml +++ b/crates/torii/types-test/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "types_test" -version = "0.1.0" +version = "0.4.2" [cairo] sierra-replace-ids = true diff --git a/crates/torii/types-test/src/lib.rs b/crates/torii/types-test/src/lib.rs new file mode 100644 index 0000000000..4199cceb5f --- /dev/null +++ b/crates/torii/types-test/src/lib.rs @@ -0,0 +1 @@ +// Placeholder so we can use `cargo release` to update Scarb.toml From bc42b8eb1220f397420feba9f6315b854289733b Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Tue, 19 Dec 2023 22:42:33 +0800 Subject: [PATCH 28/42] fix(katana-provider): handle not found err as `None` (#1316) --- .../provider/src/providers/fork/backend.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/katana/storage/provider/src/providers/fork/backend.rs b/crates/katana/storage/provider/src/providers/fork/backend.rs index 4c4d3353f0..cfba328649 100644 --- a/crates/katana/storage/provider/src/providers/fork/backend.rs +++ b/crates/katana/storage/provider/src/providers/fork/backend.rs @@ -415,10 +415,18 @@ impl ContractClassProvider for SharedStateProvider { return Ok(hash.cloned()); } - let compiled_hash = self.0.do_get_compiled_class_hash(hash)?; - self.0.compiled_class_hashes.write().insert(hash, compiled_hash); - - Ok(Some(hash)) + if let Some(hash) = + handle_contract_or_class_not_found_err(self.0.do_get_compiled_class_hash(hash)) + .map_err(|e| { + error!(target: "forked_backend", "error while fetching compiled class hash for class hash {hash:#x}: {e}"); + e + })? + { + self.0.compiled_class_hashes.write().insert(hash, hash); + Ok(Some(hash)) + } else { + Ok(None) + } } fn class(&self, hash: ClassHash) -> Result> { From 90fa4f32a564fa33d2ff825a7cbd2e8da443c9c7 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Tue, 19 Dec 2023 14:50:08 -0500 Subject: [PATCH 29/42] Remove nightly releases (#1315) --- .github/scripts/create-tag.js | 14 --- .github/scripts/move-tag.js | 15 ---- .github/scripts/prune-prereleases.js | 39 --------- .github/workflows/ci.yml | 6 -- .github/workflows/release-dispatch.yml | 3 + .github/workflows/release.yml | 115 +++---------------------- dojoup/dojoup | 7 +- 7 files changed, 18 insertions(+), 181 deletions(-) delete mode 100644 .github/scripts/create-tag.js delete mode 100644 .github/scripts/move-tag.js delete mode 100644 .github/scripts/prune-prereleases.js diff --git a/.github/scripts/create-tag.js b/.github/scripts/create-tag.js deleted file mode 100644 index 6ecd0bc9a8..0000000000 --- a/.github/scripts/create-tag.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = async ({ github, context }, tagName) => { - try { - await github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: `refs/tags/${tagName}`, - sha: context.sha, - force: true, - }); - } catch (err) { - console.error(`Failed to create tag: ${tagName}`); - console.error(err); - } -}; \ No newline at end of file diff --git a/.github/scripts/move-tag.js b/.github/scripts/move-tag.js deleted file mode 100644 index 580fa58e75..0000000000 --- a/.github/scripts/move-tag.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = async ({ github, context }, tagName) => { - try { - await github.rest.git.updateRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: `tags/${tagName}`, - sha: context.sha, - force: true, - }); - } catch (err) { - console.error(`Failed to move nightly tag.`); - console.error(`This should only happen the first time.`); - console.error(err); - } -}; \ No newline at end of file diff --git a/.github/scripts/prune-prereleases.js b/.github/scripts/prune-prereleases.js deleted file mode 100644 index 0537fbf138..0000000000 --- a/.github/scripts/prune-prereleases.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = async ({ github, context }) => { - console.log("Pruning old prereleases"); - - // doc: https://docs.github.com/en/rest/releases/releases - const { data: releases } = await github.rest.repos.listReleases({ - owner: context.repo.owner, - repo: context.repo.repo, - }); - - let nightlies = releases.filter( - release => - // Only consider releases tagged `nightly-${SHA}` for deletion - release.tag_name.includes("nightly") && - release.tag_name !== "nightly" && - // ref: https://github.com/foundry-rs/foundry/issues/3881 - // Skipping pruning the build on 1st day of each month - !release.created_at.includes("-01T") - ); - - // Keep newest 3 nightlies - nightlies = nightlies.slice(3); - - for (const nightly of nightlies) { - console.log(`Deleting nightly: ${nightly.tag_name}`); - await github.rest.repos.deleteRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: nightly.id, - }); - console.log(`Deleting nightly tag: ${nightly.tag_name}`); - await github.rest.git.deleteRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: `tags/${nightly.tag_name}`, - }); - } - - console.log("Done."); -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1d949da2a..abd5c036bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,8 +17,6 @@ jobs: image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - uses: Swatinem/rust-cache@v2 - run: cargo llvm-cov nextest --all-features --lcov --output-path lcov.info - uses: codecov/codecov-action@v3 @@ -84,8 +82,6 @@ jobs: image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - uses: Swatinem/rust-cache@v2 - run: scripts/clippy.sh @@ -104,8 +100,6 @@ jobs: image: ghcr.io/dojoengine/dojo-dev:448ffda steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - uses: Swatinem/rust-cache@v2 - run: > scripts/docs.sh diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index 60585445d5..b0917f9f44 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -20,6 +20,8 @@ jobs: - uses: actions/checkout@v3 - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm + - id: changelog + uses: mikepenz/release-changelog-builder-action@v4.1.0 - uses: peter-evans/create-pull-request@v5 with: # We have to use a PAT in order to trigger ci @@ -29,3 +31,4 @@ jobs: branch: prepare-release base: main delete-branch: true + body: ${{steps.changelog.outputs.changelog}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a1af6f7d2f..fe9d0d75a0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,81 +1,29 @@ name: release on: - push: - tags: - - "*" - schedule: - - cron: "0 0 * * *" - workflow_dispatch: + pull_request: + types: [closed] + branches: + - main env: - IS_NIGHTLY: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && 'true' || 'false' }} CARGO_TERM_COLOR: always RUST_VERSION: 1.70.0 REGISTRY_IMAGE: ghcr.io/${{ github.repository }} jobs: prepare: - name: Prepare release + if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release' runs-on: ubuntu-latest - outputs: tag_name: ${{ steps.release_info.outputs.tag_name }} - release_name: ${{ steps.release_info.outputs.release_name }} - changelog: ${{ steps.build_changelog.outputs.changelog }} - steps: - - name: Checkout sources - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Compute release name and tag + - uses: actions/checkout@v3 + - name: Get version id: release_info run: | - if [[ $IS_NIGHTLY == "true" ]]; then - echo "tag_name=nightly-${GITHUB_SHA}" >> $GITHUB_OUTPUT - echo "release_name=Nightly ($(date '+%Y-%m-%d'))" >> $GITHUB_OUTPUT - else - echo "tag_name=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT - echo "release_name=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT - fi - - - name: Check version - run: | - if [[ $IS_NIGHTLY != "true" ]]; then - cargo install cargo-get - VERSION=$(cargo get workspace.package.version) - TAG=${{ steps.release_info.outputs.tag_name }} - if [[ "v$VERSION" != "$TAG" ]]; then - echo "Version in Cargo.toml ($VERSION) does not match release tag ($TAG)" - exit 1 - fi - fi - - # Creates a `nightly-SHA` tag for this specific nightly - # This tag is used for this specific nightly version's release - # which allows users to roll back. It is also used to build - # the changelog. - - name: Create build-specific nightly tag - if: ${{ env.IS_NIGHTLY == 'true' }} - uses: actions/github-script@v5 - env: - TAG_NAME: ${{ steps.release_info.outputs.tag_name }} - with: - script: | - const createTag = require('./.github/scripts/create-tag.js') - await createTag({ github, context }, process.env.TAG_NAME) - - - name: Build changelog - id: build_changelog - uses: mikepenz/release-changelog-builder-action@v2 - with: - configuration: "./.github/changelog.json" - fromTag: ${{ env.IS_NIGHTLY == 'true' && 'nightly' || '' }} - toTag: ${{ steps.release_info.outputs.tag_name }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + cargo install cargo-get + echo "tag_name=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT release: name: ${{ matrix.job.target }} (${{ matrix.job.os }}) @@ -152,7 +100,7 @@ jobs: - name: Archive binaries id: artifacts env: - VERSION_NAME: ${{ (env.IS_NIGHTLY == 'true' && 'nightly') || needs.prepare.outputs.tag_name }} + VERSION_NAME: ${{ needs.prepare.outputs.tag_name }} run: | if [ "$PLATFORM_NAME" == "linux" ]; then tar -czvf "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" -C ./target/${TARGET}/release katana sozo torii dojo-language-server @@ -174,23 +122,9 @@ jobs: - name: Create release uses: softprops/action-gh-release@v1 with: - name: ${{ needs.prepare.outputs.release_name }} + name: ${{ github.event.pull_request.title }} tag_name: ${{ needs.prepare.outputs.tag_name }} - prerelease: ${{ env.IS_NIGHTLY == 'true' }} - body: ${{ needs.prepare.outputs.changelog }} - files: | - ${{ steps.artifacts.outputs.file_name }} - - # If this is a nightly release, it also updates the release - # tagged `nightly` for compatibility with `dojoup` - - name: Update nightly release - if: ${{ env.IS_NIGHTLY == 'true' }} - uses: softprops/action-gh-release@v1 - with: - name: "Nightly" - tag_name: "nightly" - prerelease: true - body: ${{ needs.prepare.outputs.changelog }} + body: ${{ github.event.pull_request.body }} files: | ${{ steps.artifacts.outputs.file_name }} @@ -212,31 +146,6 @@ jobs: path: ${{ env.PLATFORM_NAME }} retention-days: 1 - cleanup: - name: Release cleanup - runs-on: ubuntu-latest - needs: release - - steps: - - name: Checkout sources - uses: actions/checkout@v2 - - # Moves the `nightly` tag to `HEAD` - - name: Move nightly tag - if: ${{ env.IS_NIGHTLY == 'true' }} - uses: actions/github-script@v5 - with: - script: | - const moveTag = require('./.github/scripts/move-tag.js') - await moveTag({ github, context }, 'nightly') - - - name: Delete old nightlies - uses: actions/github-script@v5 - with: - script: | - const prunePrereleases = require('./.github/scripts/prune-prereleases.js') - await prunePrereleases({github, context}) - docker-build-and-push: name: Build and push docker image runs-on: ubuntu-latest-4-cores diff --git a/dojoup/dojoup b/dojoup/dojoup index a0e7e2c871..f07f251028 100755 --- a/dojoup/dojoup +++ b/dojoup/dojoup @@ -88,8 +88,6 @@ main() { | tr -d '"' \ | head -n 1) DOJOUP_VERSION=$DOJOUP_TAG - elif [[ "$DOJOUP_VERSION" == nightly* ]]; then - DOJOUP_VERSION="nightly" elif [[ "$DOJOUP_VERSION" == [[:digit:]]* ]]; then # Add v prefix DOJOUP_VERSION="v${DOJOUP_VERSION}" @@ -288,8 +286,9 @@ banner() { Repo : https://github.com/dojoengine/dojo - Book : https://book.dojoengine.org/ - Chat : https://t.me/+DJxNYR3rsfJmZTg1 + Book : https://book.dojoengine.org/ + Chat : https://discord.gg/dojoengine + https://t.me/dojoengine ═════════════════════════════════════════════════════════════════════════ From c6dab678a2fc129869fceb5ab487d9d3aed56898 Mon Sep 17 00:00:00 2001 From: Yun Date: Tue, 19 Dec 2023 11:56:54 -0800 Subject: [PATCH 30/42] Torii grpc member clause query (#1312) --- Cargo.lock | 1 + crates/torii/grpc/Cargo.toml | 1 + crates/torii/grpc/src/server/mod.rs | 61 ++++++++++++++++++++++++++--- crates/torii/grpc/src/types/mod.rs | 38 +++++++++++++++++- 4 files changed, 93 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05748eb8b5..039efe4190 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9872,6 +9872,7 @@ dependencies = [ "sqlx", "starknet", "starknet-crypto 0.6.1", + "strum 0.25.0", "strum_macros 0.25.3", "thiserror", "tokio", diff --git a/crates/torii/grpc/Cargo.toml b/crates/torii/grpc/Cargo.toml index b1101c82fc..24987b5534 100644 --- a/crates/torii/grpc/Cargo.toml +++ b/crates/torii/grpc/Cargo.toml @@ -18,6 +18,7 @@ thiserror.workspace = true torii-core = { path = "../core", optional = true } serde.workspace = true +strum.workspace = true strum_macros.workspace = true crypto-bigint.workspace = true diff --git a/crates/torii/grpc/src/server/mod.rs b/crates/torii/grpc/src/server/mod.rs index 8216990e27..a6c3625a28 100644 --- a/crates/torii/grpc/src/server/mod.rs +++ b/crates/torii/grpc/src/server/mod.rs @@ -34,6 +34,7 @@ use crate::proto::types::clause::ClauseType; use crate::proto::world::world_server::WorldServer; use crate::proto::world::{SubscribeEntitiesRequest, SubscribeEntityResponse}; use crate::proto::{self}; +use crate::types::ComparisonOperator; #[derive(Clone)] pub struct DojoWorld { @@ -242,14 +243,62 @@ impl DojoWorld { db_entities.iter().map(|row| Self::map_row_to_entity(row, &schemas)).collect() } - async fn entities_by_attribute( + async fn entities_by_member( &self, - _attribute: proto::types::MemberClause, + member_clause: proto::types::MemberClause, _limit: u32, _offset: u32, ) -> Result, Error> { - // TODO: Implement - Err(QueryError::UnsupportedQuery.into()) + let comparison_operator = ComparisonOperator::from_repr(member_clause.operator as usize) + .expect("invalid comparison operator"); + + let value_type = member_clause + .value + .ok_or(QueryError::MissingParam("value".into()))? + .value_type + .ok_or(QueryError::MissingParam("value_type".into()))?; + + let comparison_value = match value_type { + proto::types::value::ValueType::StringValue(string) => string, + proto::types::value::ValueType::IntValue(int) => int.to_string(), + proto::types::value::ValueType::UintValue(uint) => uint.to_string(), + proto::types::value::ValueType::BoolValue(bool) => { + if bool { + "1".to_string() + } else { + "0".to_string() + } + } + _ => return Err(QueryError::UnsupportedQuery.into()), + }; + + let models_query = format!( + r#" + SELECT group_concat(entity_model.model_id) as model_names + FROM entities + JOIN entity_model ON entities.id = entity_model.entity_id + GROUP BY entities.id + HAVING model_names REGEXP '(^|,){}(,|$)' + LIMIT 1 + "#, + member_clause.model + ); + let (models_str,): (String,) = sqlx::query_as(&models_query).fetch_one(&self.pool).await?; + + let model_names = models_str.split(',').collect::>(); + let schemas = self.model_cache.schemas(model_names).await?; + + let table_name = member_clause.model; + let column_name = format!("external_{}", member_clause.member); + let member_query = format!( + "{} WHERE {table_name}.{column_name} {comparison_operator} ?", + build_sql_query(&schemas)? + ); + + let db_entities = + sqlx::query(&member_query).bind(comparison_value).fetch_all(&self.pool).await?; + + db_entities.iter().map(|row| Self::map_row_to_entity(row, &schemas)).collect() } async fn entities_by_composite( @@ -350,8 +399,8 @@ impl DojoWorld { self.entities_by_keys(keys, query.limit, query.offset).await? } - ClauseType::Member(attribute) => { - self.entities_by_attribute(attribute, query.limit, query.offset).await? + ClauseType::Member(member) => { + self.entities_by_member(member, query.limit, query.offset).await? } ClauseType::Composite(composite) => { self.entities_by_composite(composite, query.limit, query.offset).await? diff --git a/crates/torii/grpc/src/types/mod.rs b/crates/torii/grpc/src/types/mod.rs index da97af938b..bc18d7f5cf 100644 --- a/crates/torii/grpc/src/types/mod.rs +++ b/crates/torii/grpc/src/types/mod.rs @@ -1,3 +1,4 @@ +use core::fmt; use std::collections::HashMap; use std::str::FromStr; @@ -8,6 +9,7 @@ use starknet::core::types::{ ContractStorageDiffItem, FromByteSliceError, FromStrError, StateDiff, StateUpdate, StorageEntry, }; use starknet_crypto::FieldElement; +use strum_macros::{AsRefStr, EnumIter, FromRepr}; use crate::proto::{self}; @@ -48,13 +50,19 @@ pub struct CompositeClause { pub clauses: Vec, } -#[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] +#[derive( + Debug, AsRefStr, Serialize, Deserialize, EnumIter, FromRepr, PartialEq, Hash, Eq, Clone, +)] +#[strum(serialize_all = "UPPERCASE")] pub enum LogicalOperator { And, Or, } -#[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] +#[derive( + Debug, AsRefStr, Serialize, Deserialize, EnumIter, FromRepr, PartialEq, Hash, Eq, Clone, +)] +#[strum(serialize_all = "UPPERCASE")] pub enum ComparisonOperator { Eq, Neq, @@ -64,6 +72,32 @@ pub enum ComparisonOperator { Lte, } +impl fmt::Display for ComparisonOperator { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ComparisonOperator::Gt => write!(f, ">"), + ComparisonOperator::Gte => write!(f, ">="), + ComparisonOperator::Lt => write!(f, "<"), + ComparisonOperator::Lte => write!(f, "<="), + ComparisonOperator::Neq => write!(f, "!="), + ComparisonOperator::Eq => write!(f, "="), + } + } +} + +impl From for ComparisonOperator { + fn from(operator: proto::types::ComparisonOperator) -> Self { + match operator { + proto::types::ComparisonOperator::Eq => ComparisonOperator::Eq, + proto::types::ComparisonOperator::Gte => ComparisonOperator::Gte, + proto::types::ComparisonOperator::Gt => ComparisonOperator::Gt, + proto::types::ComparisonOperator::Lt => ComparisonOperator::Lt, + proto::types::ComparisonOperator::Lte => ComparisonOperator::Lte, + proto::types::ComparisonOperator::Neq => ComparisonOperator::Neq, + } + } +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Hash, Eq, Clone)] pub struct Value { pub primitive_type: Primitive, From e8a1c952041301ca079d7586f3bd462801aa9677 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Tue, 19 Dec 2023 15:12:08 -0500 Subject: [PATCH 31/42] Improve release dispatch content --- .github/workflows/release-dispatch.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index b0917f9f44..bb22b33d1c 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -19,15 +19,25 @@ jobs: # Workaround described here: https://github.com/actions/checkout/issues/760 - uses: actions/checkout@v3 - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - id: current_release_info + run: | + cargo install cargo-get + echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm - id: changelog uses: mikepenz/release-changelog-builder-action@v4.1.0 + with: + fromTag: v${{ steps.current_release_info.outputs.version }} + - id: next_release_info + run: | + cargo install cargo-get + echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - uses: peter-evans/create-pull-request@v5 with: # We have to use a PAT in order to trigger ci token: ${{ secrets.CREATE_PR_TOKEN }} - title: "Prepare release: ${{ inputs.version }}" - commit-message: "Prepare release: ${{ inputs.version }}" + title: "Prepare release: ${{ steps.next_release_info.outputs.version }}" + commit-message: "Prepare release: ${{ steps.next_release_info.outputs.version }}" branch: prepare-release base: main delete-branch: true From 5514ad2135bc87d80532204beb588d0a111e499f Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Tue, 19 Dec 2023 15:25:29 -0500 Subject: [PATCH 32/42] Revert Cargo version to 0.4.1 --- .github/workflows/release-dispatch.yml | 4 +- Cargo.lock | 62 +++++++++++++------------- Cargo.toml | 2 +- crates/dojo-core/Scarb.lock | 2 +- crates/dojo-core/Scarb.toml | 2 +- crates/torii/types-test/Scarb.lock | 2 +- crates/torii/types-test/Scarb.toml | 2 +- examples/spawn-and-move/Scarb.lock | 2 +- examples/spawn-and-move/Scarb.toml | 2 +- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index bb22b33d1c..a2bea6eff3 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -36,8 +36,8 @@ jobs: with: # We have to use a PAT in order to trigger ci token: ${{ secrets.CREATE_PR_TOKEN }} - title: "Prepare release: ${{ steps.next_release_info.outputs.version }}" - commit-message: "Prepare release: ${{ steps.next_release_info.outputs.version }}" + title: "Prepare release: v${{ steps.next_release_info.outputs.version }}" + commit-message: "Prepare release: v${{ steps.next_release_info.outputs.version }}" branch: prepare-release base: main delete-branch: true diff --git a/Cargo.lock b/Cargo.lock index 039efe4190..c0bf341d33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,7 +801,7 @@ dependencies = [ [[package]] name = "benches" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "clap_builder", @@ -2623,15 +2623,15 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dojo-core" -version = "0.4.2" +version = "0.4.1" [[package]] name = "dojo-examples-spawn-and-move" -version = "0.4.2" +version = "0.4.1" [[package]] name = "dojo-lang" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2679,7 +2679,7 @@ dependencies = [ [[package]] name = "dojo-language-server" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "dojo-signers" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "starknet", @@ -2709,7 +2709,7 @@ dependencies = [ [[package]] name = "dojo-test-utils" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "assert_fs", @@ -2740,7 +2740,7 @@ dependencies = [ [[package]] name = "dojo-types" -version = "0.4.2" +version = "0.4.1" dependencies = [ "crypto-bigint", "hex", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "dojo-world" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "assert_fs", @@ -5393,7 +5393,7 @@ dependencies = [ [[package]] name = "katana" -version = "0.4.2" +version = "0.4.1" dependencies = [ "assert_matches", "clap", @@ -5401,7 +5401,7 @@ dependencies = [ "console", "katana-core", "katana-rpc", - "metrics 0.4.2", + "metrics 0.4.1", "metrics-process", "serde_json", "starknet_api", @@ -5413,7 +5413,7 @@ dependencies = [ [[package]] name = "katana-codecs" -version = "0.4.2" +version = "0.4.1" dependencies = [ "bytes", "katana-primitives", @@ -5421,7 +5421,7 @@ dependencies = [ [[package]] name = "katana-codecs-derive" -version = "0.4.2" +version = "0.4.1" dependencies = [ "proc-macro2", "quote", @@ -5431,7 +5431,7 @@ dependencies = [ [[package]] name = "katana-core" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "assert_matches", @@ -5464,7 +5464,7 @@ dependencies = [ [[package]] name = "katana-db" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "bincode 1.3.3", @@ -5487,7 +5487,7 @@ dependencies = [ [[package]] name = "katana-executor" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "blockifier", @@ -5503,7 +5503,7 @@ dependencies = [ [[package]] name = "katana-primitives" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "blockifier", @@ -5521,7 +5521,7 @@ dependencies = [ [[package]] name = "katana-provider" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "auto_impl", @@ -5541,7 +5541,7 @@ dependencies = [ [[package]] name = "katana-rpc" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "assert_matches", @@ -5573,7 +5573,7 @@ dependencies = [ [[package]] name = "katana-rpc-types" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "derive_more", @@ -5586,7 +5586,7 @@ dependencies = [ [[package]] name = "katana-rpc-types-builder" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "katana-executor", @@ -5598,7 +5598,7 @@ dependencies = [ [[package]] name = "katana-runner" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "home", @@ -5889,7 +5889,7 @@ dependencies = [ [[package]] name = "metrics" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "hyper", @@ -8558,7 +8558,7 @@ dependencies = [ [[package]] name = "sozo" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "assert_fs", @@ -9752,7 +9752,7 @@ dependencies = [ [[package]] name = "torii-client" -version = "0.4.2" +version = "0.4.1" dependencies = [ "async-trait", "camino", @@ -9778,7 +9778,7 @@ dependencies = [ [[package]] name = "torii-core" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "async-trait", @@ -9814,7 +9814,7 @@ dependencies = [ [[package]] name = "torii-graphql" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "async-graphql", @@ -9853,7 +9853,7 @@ dependencies = [ [[package]] name = "torii-grpc" -version = "0.4.2" +version = "0.4.1" dependencies = [ "bytes", "crypto-bigint", @@ -9892,7 +9892,7 @@ dependencies = [ [[package]] name = "torii-server" -version = "0.4.2" +version = "0.4.1" dependencies = [ "anyhow", "async-trait", @@ -9911,7 +9911,7 @@ dependencies = [ "hyper-reverse-proxy", "indexmap 1.9.3", "lazy_static", - "metrics 0.4.2", + "metrics 0.4.1", "metrics-process", "scarb", "serde", @@ -10179,7 +10179,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types-test" -version = "0.4.2" +version = "0.4.1" [[package]] name = "ucd-trie" diff --git a/Cargo.toml b/Cargo.toml index 1ece9cfe98..d50ab59a7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ edition = "2021" license = "Apache-2.0" license-file = "LICENSE" repository = "https://github.com/dojoengine/dojo/" -version = "0.4.2" +version = "0.4.1" [profile.performance] codegen-units = 1 diff --git a/crates/dojo-core/Scarb.lock b/crates/dojo-core/Scarb.lock index 14d33d1dbb..ee17c212ea 100644 --- a/crates/dojo-core/Scarb.lock +++ b/crates/dojo-core/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.2" +version = "0.4.1" dependencies = [ "dojo_plugin", ] diff --git a/crates/dojo-core/Scarb.toml b/crates/dojo-core/Scarb.toml index ef1080e43a..a8809ef181 100644 --- a/crates/dojo-core/Scarb.toml +++ b/crates/dojo-core/Scarb.toml @@ -2,7 +2,7 @@ cairo-version = "2.4.0" description = "The Dojo Core library for autonomous worlds." name = "dojo" -version = "0.4.2" +version = "0.4.1" [dependencies] dojo_plugin = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.11" } diff --git a/crates/torii/types-test/Scarb.lock b/crates/torii/types-test/Scarb.lock index 736f84366b..4f2d7aa41c 100644 --- a/crates/torii/types-test/Scarb.lock +++ b/crates/torii/types-test/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.2" +version = "0.4.1" dependencies = [ "dojo_plugin", ] diff --git a/crates/torii/types-test/Scarb.toml b/crates/torii/types-test/Scarb.toml index ac5bfa187f..3bb6831b41 100644 --- a/crates/torii/types-test/Scarb.toml +++ b/crates/torii/types-test/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "types_test" -version = "0.4.2" +version = "0.4.1" [cairo] sierra-replace-ids = true diff --git a/examples/spawn-and-move/Scarb.lock b/examples/spawn-and-move/Scarb.lock index 36fbad6d54..9474cc125c 100644 --- a/examples/spawn-and-move/Scarb.lock +++ b/examples/spawn-and-move/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.2" +version = "0.4.1" dependencies = [ "dojo_plugin", ] diff --git a/examples/spawn-and-move/Scarb.toml b/examples/spawn-and-move/Scarb.toml index 2383af1a8e..35969ed10f 100644 --- a/examples/spawn-and-move/Scarb.toml +++ b/examples/spawn-and-move/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "dojo_examples" -version = "0.4.2" +version = "0.4.1" # Use the prelude with the less imports as possible # from corelib. edition = "2023_10" From 3af74d5cf343da6a9500b05c674aa84939717cb1 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Tue, 19 Dec 2023 15:32:07 -0500 Subject: [PATCH 33/42] Set changelog to tag --- .github/workflows/release-dispatch.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index a2bea6eff3..c8ec5c6845 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -24,14 +24,15 @@ jobs: cargo install cargo-get echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm - - id: changelog - uses: mikepenz/release-changelog-builder-action@v4.1.0 - with: - fromTag: v${{ steps.current_release_info.outputs.version }} - id: next_release_info run: | cargo install cargo-get echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT + - id: changelog + uses: mikepenz/release-changelog-builder-action@v4.1.0 + with: + fromTag: v${{ steps.current_release_info.outputs.version }} + toTag: main - uses: peter-evans/create-pull-request@v5 with: # We have to use a PAT in order to trigger ci From 1840d7282721af874852f389abd3cbe2a3af5d7b Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Wed, 20 Dec 2023 06:08:58 +0800 Subject: [PATCH 34/42] test(katana-provider): more elaborate tests (#1317) * test(katana-provider): more elaborate tests * ignore log files from runner --- Cargo.lock | 2 + crates/katana/primitives/src/receipt.rs | 16 +- crates/katana/storage/provider/.gitignore | 1 + crates/katana/storage/provider/Cargo.toml | 8 +- .../provider/tests/{common.rs => block.rs} | 59 ++----- crates/katana/storage/provider/tests/class.rs | 146 +++++++++++++++++ .../katana/storage/provider/tests/contract.rs | 145 +++++++++++++++++ .../katana/storage/provider/tests/fixtures.rs | 135 +++++++++++++++- .../katana/storage/provider/tests/storage.rs | 153 ++++++++++++++++++ crates/katana/storage/provider/tests/utils.rs | 46 ++++++ 10 files changed, 654 insertions(+), 57 deletions(-) create mode 100644 crates/katana/storage/provider/.gitignore rename crates/katana/storage/provider/tests/{common.rs => block.rs} (51%) create mode 100644 crates/katana/storage/provider/tests/class.rs create mode 100644 crates/katana/storage/provider/tests/contract.rs create mode 100644 crates/katana/storage/provider/tests/storage.rs create mode 100644 crates/katana/storage/provider/tests/utils.rs diff --git a/Cargo.lock b/Cargo.lock index c0bf341d33..67bb5e3c7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5528,6 +5528,8 @@ dependencies = [ "futures", "katana-db", "katana-primitives", + "katana-runner", + "lazy_static", "parking_lot 0.12.1", "rand", "rstest", diff --git a/crates/katana/primitives/src/receipt.rs b/crates/katana/primitives/src/receipt.rs index e053f4e845..34bfa888ed 100644 --- a/crates/katana/primitives/src/receipt.rs +++ b/crates/katana/primitives/src/receipt.rs @@ -3,7 +3,7 @@ use ethers::types::H256; use crate::contract::ContractAddress; use crate::FieldElement; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Event { /// The contract address that emitted the event. @@ -15,7 +15,7 @@ pub struct Event { } /// Represents a message sent to L1. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MessageToL1 { /// The L2 contract address that sent the message. @@ -27,7 +27,7 @@ pub struct MessageToL1 { } /// Receipt for a `Invoke` transaction. -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct InvokeTxReceipt { /// Actual fee paid for the transaction. @@ -43,7 +43,7 @@ pub struct InvokeTxReceipt { } /// Receipt for a `Declare` transaction. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeclareTxReceipt { /// Actual fee paid for the transaction. @@ -59,7 +59,7 @@ pub struct DeclareTxReceipt { } /// Receipt for a `L1Handler` transaction. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct L1HandlerTxReceipt { /// Actual fee paid for the transaction. @@ -77,7 +77,7 @@ pub struct L1HandlerTxReceipt { } /// Receipt for a `DeployAccount` transaction. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeployAccountTxReceipt { /// Actual fee paid for the transaction. @@ -95,7 +95,7 @@ pub struct DeployAccountTxReceipt { } /// The receipt of a transaction containing the outputs of its execution. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Receipt { Invoke(InvokeTxReceipt), @@ -139,7 +139,7 @@ impl Receipt { /// Transaction execution resources. /// /// The resources consumed by a transaction during its execution. -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TxExecutionResources { /// The number of cairo steps used diff --git a/crates/katana/storage/provider/.gitignore b/crates/katana/storage/provider/.gitignore new file mode 100644 index 0000000000..b6d592eb2a --- /dev/null +++ b/crates/katana/storage/provider/.gitignore @@ -0,0 +1 @@ +/logs diff --git a/crates/katana/storage/provider/Cargo.toml b/crates/katana/storage/provider/Cargo.toml index dc59a8d1b0..af9d492a08 100644 --- a/crates/katana/storage/provider/Cargo.toml +++ b/crates/katana/storage/provider/Cargo.toml @@ -22,11 +22,13 @@ starknet.workspace = true tokio.workspace = true [features] -default = ["fork", "in-memory"] -fork = ["in-memory"] -in-memory = [] +default = [ "fork", "in-memory" ] +fork = [ "in-memory" ] +in-memory = [ ] [dev-dependencies] +katana-runner = { path = "../../runner" } +lazy_static.workspace = true rand = "0.8.5" rstest = "0.18.2" rstest_reuse = "0.6.0" diff --git a/crates/katana/storage/provider/tests/common.rs b/crates/katana/storage/provider/tests/block.rs similarity index 51% rename from crates/katana/storage/provider/tests/common.rs rename to crates/katana/storage/provider/tests/block.rs index 9fa4086298..03b8a4cecc 100644 --- a/crates/katana/storage/provider/tests/common.rs +++ b/crates/katana/storage/provider/tests/block.rs @@ -1,46 +1,16 @@ -use katana_primitives::block::{ - Block, BlockHash, BlockHashOrNumber, FinalityStatus, Header, SealedBlockWithStatus, -}; -use katana_primitives::transaction::{Tx, TxHash, TxWithHash}; -use katana_primitives::FieldElement; +use katana_primitives::block::BlockHashOrNumber; use katana_provider::providers::fork::ForkedProvider; use katana_provider::providers::in_memory::InMemoryProvider; use katana_provider::traits::block::{BlockProvider, BlockWriter}; -use katana_provider::traits::transaction::TransactionProvider; +use katana_provider::traits::transaction::{ReceiptProvider, TransactionProvider}; use katana_provider::BlockchainProvider; use rstest_reuse::{self, *}; mod fixtures; +mod utils; use fixtures::{fork_provider, in_memory_provider}; - -fn generate_dummy_txs(count: u64) -> Vec { - let mut txs = Vec::with_capacity(count as usize); - for _ in 0..count { - txs.push(TxWithHash { - hash: TxHash::from(rand::random::()), - transaction: Tx::Invoke(Default::default()), - }); - } - txs -} - -fn generate_dummy_blocks(count: u64) -> Vec { - let mut blocks = Vec::with_capacity(count as usize); - let mut parent_hash: BlockHash = 0u8.into(); - - for i in 0..count { - let body = generate_dummy_txs(rand::random::() % 10); - let header = Header { parent_hash, number: i, ..Default::default() }; - let block = - Block { header, body }.seal_with_hash(FieldElement::from(rand::random::())); - parent_hash = block.header.hash; - - blocks.push(SealedBlockWithStatus { block, status: FinalityStatus::AcceptedOnL2 }); - } - - blocks -} +use utils::generate_dummy_blocks_and_receipts; #[template] #[rstest::rstest] @@ -55,7 +25,7 @@ fn insert_block_with_in_memory_provider( #[from(in_memory_provider)] provider: BlockchainProvider, #[case] block_count: u64, ) -> anyhow::Result<()> { - insert_block_impl(provider, block_count) + insert_block_test_impl(provider, block_count) } #[apply(insert_block_cases)] @@ -63,24 +33,24 @@ fn insert_block_with_fork_provider( #[from(fork_provider)] provider: BlockchainProvider, #[case] block_count: u64, ) -> anyhow::Result<()> { - insert_block_impl(provider, block_count) + insert_block_test_impl(provider, block_count) } -fn insert_block_impl(provider: BlockchainProvider, count: u64) -> anyhow::Result<()> +fn insert_block_test_impl(provider: BlockchainProvider, count: u64) -> anyhow::Result<()> where - Db: BlockProvider + BlockWriter, + Db: BlockProvider + BlockWriter + ReceiptProvider, { - let blocks = generate_dummy_blocks(count); + let blocks = generate_dummy_blocks_and_receipts(count); - for block in &blocks { + for (block, receipts) in &blocks { provider.insert_block_with_states_and_receipts( block.clone(), Default::default(), - Default::default(), + receipts.clone(), )?; } - for block in blocks { + for (block, receipts) in blocks { let block_id = BlockHashOrNumber::Hash(block.block.header.hash); let expected_block = block.block.unseal(); @@ -88,6 +58,11 @@ where let actual_block_txs = provider.transactions_by_block(block_id)?; let actual_block_tx_count = provider.transaction_count_by_block(block_id)?; + let actual_receipts = provider.receipts_by_block(block_id)?; + + assert_eq!(actual_receipts.as_ref().map(|r| r.len()), Some(expected_block.body.len())); + assert_eq!(actual_receipts, Some(receipts)); + assert_eq!(actual_block_tx_count, Some(expected_block.body.len() as u64)); assert_eq!(actual_block_txs, Some(expected_block.body.clone())); assert_eq!(actual_block, Some(expected_block)); diff --git a/crates/katana/storage/provider/tests/class.rs b/crates/katana/storage/provider/tests/class.rs new file mode 100644 index 0000000000..68a2959843 --- /dev/null +++ b/crates/katana/storage/provider/tests/class.rs @@ -0,0 +1,146 @@ +mod fixtures; + +use anyhow::Result; +use fixtures::{fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states}; +use katana_primitives::block::{BlockHashOrNumber, BlockNumber}; +use katana_primitives::contract::{ClassHash, CompiledClassHash}; +use katana_provider::providers::fork::ForkedProvider; +use katana_provider::providers::in_memory::InMemoryProvider; +use katana_provider::traits::state::{StateFactoryProvider, StateProvider}; +use katana_provider::BlockchainProvider; +use rstest_reuse::{self, *}; +use starknet::macros::felt; + +fn assert_state_provider_class( + state_provider: Box, + expected_class: Vec<(ClassHash, Option)>, +) -> Result<()> { + for (class_hash, expected_compiled_hash) in expected_class { + let actual_compiled_hash = state_provider.compiled_class_hash_of_class_hash(class_hash)?; + assert_eq!(actual_compiled_hash, expected_compiled_hash); + } + Ok(()) +} + +mod latest { + use super::*; + + fn assert_latest_class( + provider: BlockchainProvider, + expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + let state_provider = provider.latest()?; + assert_state_provider_class(state_provider, expected_class) + } + + #[template] + #[rstest::rstest] + #[case( + vec![ + (felt!("11"), Some(felt!("1000"))), + (felt!("22"), Some(felt!("2000"))), + (felt!("33"), Some(felt!("3000"))), + ] + )] + fn test_latest_class_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) { + } + + #[apply(test_latest_class_read)] + fn read_class_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_latest_class(provider, expected_class) + } + + #[apply(test_latest_class_read)] + fn read_class_from_fork_provider( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_latest_class(provider, expected_class) + } +} + +mod historical { + use super::*; + + fn assert_historical_class( + provider: BlockchainProvider, + block_num: BlockNumber, + expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + let state_provider = provider + .historical(BlockHashOrNumber::Num(block_num))? + .expect(ERROR_CREATE_HISTORICAL_PROVIDER); + assert_state_provider_class(state_provider, expected_class) + } + + const ERROR_CREATE_HISTORICAL_PROVIDER: &str = "Failed to create historical state provider."; + + #[template] + #[rstest::rstest] + #[case::class_hash_at_block_0( + 0, + vec![ + (felt!("11"), None), + (felt!("22"), None), + (felt!("33"), None) + ]) + ] + #[case::class_hash_at_block_1( + 1, + vec![ + (felt!("11"), Some(felt!("1000"))), + (felt!("22"), None), + (felt!("33"), None), + ]) + ] + #[case::class_hash_at_block_4( + 4, + vec![ + (felt!("11"), Some(felt!("1000"))), + (felt!("22"), Some(felt!("2000"))), + (felt!("33"), None), + ]) + ] + #[case::class_hash_at_block_5( + 5, + vec![ + (felt!("11"), Some(felt!("1000"))), + (felt!("22"), Some(felt!("2000"))), + (felt!("33"), Some(felt!("3000"))), + ]) + ] + fn test_historical_class_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) { + } + + #[apply(test_historical_class_read)] + fn read_class_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_historical_class(provider, block_num, expected_class) + } + + #[apply(test_historical_class_read)] + fn read_class_from_fork_provider( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] block_num: BlockNumber, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_historical_class(provider, block_num, expected_class) + } +} diff --git a/crates/katana/storage/provider/tests/contract.rs b/crates/katana/storage/provider/tests/contract.rs new file mode 100644 index 0000000000..3b54fdff78 --- /dev/null +++ b/crates/katana/storage/provider/tests/contract.rs @@ -0,0 +1,145 @@ +mod fixtures; + +use anyhow::Result; +use fixtures::{fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states}; +use katana_primitives::block::{BlockHashOrNumber, BlockNumber}; +use katana_primitives::contract::{ClassHash, ContractAddress, Nonce}; +use katana_provider::providers::fork::ForkedProvider; +use katana_provider::providers::in_memory::InMemoryProvider; +use katana_provider::traits::state::{StateFactoryProvider, StateProvider}; +use katana_provider::BlockchainProvider; +use rstest_reuse::{self, *}; +use starknet::macros::felt; + +fn assert_state_provider_contract_info( + state_provider: Box, + expected_contract_info: Vec<(ContractAddress, Option, Option)>, +) -> Result<()> { + for (address, expected_class_hash, expected_nonce) in expected_contract_info { + let actual_class_hash = state_provider.class_hash_of_contract(address)?; + let actual_nonce = state_provider.nonce(address)?; + + assert_eq!(actual_class_hash, expected_class_hash); + assert_eq!(actual_nonce, expected_nonce); + } + + Ok(()) +} + +mod latest { + use super::*; + + fn assert_latest_contract_info( + provider: BlockchainProvider, + expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + let state_provider = provider.latest()?; + assert_state_provider_contract_info(state_provider, expected_contract_info) + } + + #[template] + #[rstest::rstest] + #[case( + vec![ + (ContractAddress::from(felt!("1")), Some(felt!("22")), Some(felt!("3"))), + (ContractAddress::from(felt!("2")), Some(felt!("33")), Some(felt!("2"))), + ] + )] + fn test_latest_contract_info_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) { + } + + #[apply(test_latest_contract_info_read)] + fn read_storage_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_latest_contract_info(provider, expected_contract_info) + } + + #[apply(test_latest_contract_info_read)] + fn read_storage_from_fork_provider( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_latest_contract_info(provider, expected_contract_info) + } +} + +mod historical { + use super::*; + + fn assert_historical_contract_info( + provider: BlockchainProvider, + block_num: BlockNumber, + expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + let state_provider = provider + .historical(BlockHashOrNumber::Num(block_num))? + .expect(ERROR_CREATE_HISTORICAL_PROVIDER); + assert_state_provider_contract_info(state_provider, expected_contract_info) + } + + const ERROR_CREATE_HISTORICAL_PROVIDER: &str = "Failed to create historical state provider."; + + #[template] + #[rstest::rstest] + #[case::storage_at_block_0( + 0, + vec![ + (ContractAddress::from(felt!("1")), None, None), + (ContractAddress::from(felt!("2")), None, None) + ]) + ] + #[case::storage_at_block_1( + 1, + vec![ + (ContractAddress::from(felt!("1")), Some(felt!("11")), Some(felt!("1"))), + (ContractAddress::from(felt!("2")), Some(felt!("11")), Some(felt!("1"))), + ]) + ] + #[case::storage_at_block_4( + 4, + vec![ + (ContractAddress::from(felt!("1")), Some(felt!("11")), Some(felt!("2"))), + (ContractAddress::from(felt!("2")), Some(felt!("22")), Some(felt!("1"))), + ]) + ] + #[case::storage_at_block_5( + 5, + vec![ + (ContractAddress::from(felt!("1")), Some(felt!("22")), Some(felt!("3"))), + (ContractAddress::from(felt!("2")), Some(felt!("33")), Some(felt!("2"))), + ]) + ] + fn test_historical_storage_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) { + } + + #[apply(test_historical_storage_read)] + fn read_storage_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_historical_contract_info(provider, block_num, expected_contract_info) + } + + #[apply(test_historical_storage_read)] + fn read_storage_from_fork_provider( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] block_num: BlockNumber, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_historical_contract_info(provider, block_num, expected_contract_info) + } +} diff --git a/crates/katana/storage/provider/tests/fixtures.rs b/crates/katana/storage/provider/tests/fixtures.rs index d6c0ff6f85..4021ab3672 100644 --- a/crates/katana/storage/provider/tests/fixtures.rs +++ b/crates/katana/storage/provider/tests/fixtures.rs @@ -1,13 +1,30 @@ +use std::collections::HashMap; use std::sync::Arc; -use katana_primitives::block::BlockHashOrNumber; +use katana_primitives::block::{ + BlockHashOrNumber, FinalityStatus, Header, SealedBlock, SealedBlockWithStatus, SealedHeader, +}; +use katana_primitives::contract::ContractAddress; +use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; use katana_provider::providers::fork::ForkedProvider; use katana_provider::providers::in_memory::InMemoryProvider; +use katana_provider::traits::block::BlockWriter; +use katana_provider::traits::state::StateFactoryProvider; use katana_provider::BlockchainProvider; +use katana_runner::KatanaRunner; +use lazy_static::lazy_static; +use starknet::macros::felt; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::JsonRpcClient; use url::Url; +lazy_static! { + pub static ref FORKED_PROVIDER: (KatanaRunner, Arc>) = { + let (runner, provider) = katana_runner::KatanaRunner::new().unwrap(); + (runner, Arc::new(provider)) + }; +} + #[rstest::fixture] pub fn in_memory_provider() -> BlockchainProvider { BlockchainProvider::new(InMemoryProvider::new()) @@ -15,10 +32,120 @@ pub fn in_memory_provider() -> BlockchainProvider { #[rstest::fixture] pub fn fork_provider( - #[default("http://localhost:5050")] rpc: &str, + #[default("http://127.0.0.1:5050")] rpc: &str, #[default(0)] block_num: u64, ) -> BlockchainProvider { - let rpc_provider = JsonRpcClient::new(HttpTransport::new(Url::parse(rpc).unwrap())); - let provider = ForkedProvider::new(Arc::new(rpc_provider), BlockHashOrNumber::Num(block_num)); + let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(rpc).unwrap())); + let provider = ForkedProvider::new(Arc::new(provider), BlockHashOrNumber::Num(block_num)); BlockchainProvider::new(provider) } + +#[rstest::fixture] +pub fn fork_provider_with_spawned_fork_network( + #[default(0)] block_num: u64, +) -> BlockchainProvider { + let provider = + ForkedProvider::new(FORKED_PROVIDER.1.clone(), BlockHashOrNumber::Num(block_num)); + BlockchainProvider::new(provider) +} + +#[rstest::fixture] +#[default(BlockchainProvider)] +pub fn provider_with_states( + #[default(in_memory_provider())] provider: BlockchainProvider, +) -> BlockchainProvider +where + Db: BlockWriter + StateFactoryProvider, +{ + let address_1 = ContractAddress::from(felt!("1")); + let address_2 = ContractAddress::from(felt!("2")); + + let class_hash_1 = felt!("11"); + let compiled_class_hash_1 = felt!("1000"); + + let class_hash_2 = felt!("22"); + let compiled_class_hash_2 = felt!("2000"); + + let class_hash_3 = felt!("33"); + let compiled_class_hash_3 = felt!("3000"); + + let state_update_at_block_1 = StateUpdatesWithDeclaredClasses { + state_updates: StateUpdates { + nonce_updates: HashMap::from([(address_1, 1u8.into()), (address_2, 1u8.into())]), + storage_updates: HashMap::from([ + ( + address_1, + HashMap::from([(1u8.into(), 100u32.into()), (2u8.into(), 101u32.into())]), + ), + ( + address_2, + HashMap::from([(1u8.into(), 200u32.into()), (2u8.into(), 201u32.into())]), + ), + ]), + declared_classes: HashMap::from([(class_hash_1, compiled_class_hash_1)]), + contract_updates: HashMap::from([(address_1, class_hash_1), (address_2, class_hash_1)]), + }, + ..Default::default() + }; + + let state_update_at_block_2 = StateUpdatesWithDeclaredClasses { + state_updates: StateUpdates { + nonce_updates: HashMap::from([(address_1, 2u8.into())]), + storage_updates: HashMap::from([( + address_1, + HashMap::from([(felt!("1"), felt!("111")), (felt!("2"), felt!("222"))]), + )]), + declared_classes: HashMap::from([(class_hash_2, compiled_class_hash_2)]), + contract_updates: HashMap::from([(address_2, class_hash_2)]), + }, + ..Default::default() + }; + + let state_update_at_block_5 = StateUpdatesWithDeclaredClasses { + state_updates: StateUpdates { + nonce_updates: HashMap::from([(address_1, 3u8.into()), (address_2, 2u8.into())]), + storage_updates: HashMap::from([ + (address_1, HashMap::from([(3u8.into(), 77u32.into())])), + ( + address_2, + HashMap::from([(1u8.into(), 12u32.into()), (2u8.into(), 13u32.into())]), + ), + ]), + contract_updates: HashMap::from([(address_1, class_hash_2), (address_2, class_hash_3)]), + declared_classes: HashMap::from([(class_hash_3, compiled_class_hash_3)]), + }, + ..Default::default() + }; + + // Fill provider with states. + + for i in 0..=5 { + let block_id = BlockHashOrNumber::from(i); + + let state_update = match block_id { + BlockHashOrNumber::Num(1) => state_update_at_block_1.clone(), + BlockHashOrNumber::Num(2) => state_update_at_block_2.clone(), + BlockHashOrNumber::Num(5) => state_update_at_block_5.clone(), + _ => StateUpdatesWithDeclaredClasses::default(), + }; + + provider + .insert_block_with_states_and_receipts( + SealedBlockWithStatus { + status: FinalityStatus::AcceptedOnL2, + block: SealedBlock { + header: SealedHeader { + hash: i.into(), + header: Header { number: i, ..Default::default() }, + }, + body: Default::default(), + }, + }, + state_update, + Default::default(), + ) + .unwrap(); + } + + provider +} diff --git a/crates/katana/storage/provider/tests/storage.rs b/crates/katana/storage/provider/tests/storage.rs new file mode 100644 index 0000000000..4f12e8f5d8 --- /dev/null +++ b/crates/katana/storage/provider/tests/storage.rs @@ -0,0 +1,153 @@ +mod fixtures; + +use anyhow::Result; +use fixtures::{fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states}; +use katana_primitives::block::{BlockHashOrNumber, BlockNumber}; +use katana_primitives::contract::{ContractAddress, StorageKey, StorageValue}; +use katana_provider::providers::fork::ForkedProvider; +use katana_provider::providers::in_memory::InMemoryProvider; +use katana_provider::traits::state::{StateFactoryProvider, StateProvider}; +use katana_provider::BlockchainProvider; +use rstest_reuse::{self, *}; +use starknet::macros::felt; + +fn assert_state_provider_storage( + state_provider: Box, + expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, +) -> Result<()> { + for (address, key, expected_value) in expected_storage_entry { + let actual_value = state_provider.storage(address, key)?; + assert_eq!(actual_value, expected_value); + } + Ok(()) +} + +mod latest { + use super::*; + + fn assert_latest_storage_value( + provider: BlockchainProvider, + expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + let state_provider = provider.latest()?; + assert_state_provider_storage(state_provider, expected_storage_entry) + } + + #[template] + #[rstest::rstest] + #[case( + vec![ + (ContractAddress::from(felt!("1")), felt!("1"), Some(felt!("111"))), + (ContractAddress::from(felt!("1")), felt!("2"), Some(felt!("222"))), + (ContractAddress::from(felt!("1")), felt!("3"), Some(felt!("77"))), + (ContractAddress::from(felt!("2")), felt!("1"), Some(felt!("12"))), + (ContractAddress::from(felt!("2")), felt!("2"), Some(felt!("13"))) + ] + )] + fn test_latest_storage_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) { + } + + #[apply(test_latest_storage_read)] + fn read_storage_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_latest_storage_value(provider, expected_storage_entry) + } + + #[apply(test_latest_storage_read)] + fn read_storage_from_fork_provider_with_spawned_fork_network( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_latest_storage_value(provider, expected_storage_entry) + } +} + +mod historical { + use super::*; + + fn assert_historical_storage_value( + provider: BlockchainProvider, + block_num: BlockNumber, + expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + let state_provider = provider + .historical(BlockHashOrNumber::Num(block_num))? + .expect(ERROR_CREATE_HISTORICAL_PROVIDER); + assert_state_provider_storage(state_provider, expected_storage_entry) + } + + const ERROR_CREATE_HISTORICAL_PROVIDER: &str = "Failed to create historical state provider."; + + #[template] + #[rstest::rstest] + #[case::storage_at_block_0( + 0, + vec![ + (ContractAddress::from(felt!("1")), felt!("1"), None), + (ContractAddress::from(felt!("1")), felt!("2"), None), + (ContractAddress::from(felt!("2")), felt!("1"), None), + (ContractAddress::from(felt!("2")), felt!("2"), None) + ]) + ] + #[case::storage_at_block_1( + 1, + vec![ + (ContractAddress::from(felt!("1")), felt!("1"), Some(felt!("100"))), + (ContractAddress::from(felt!("1")), felt!("2"), Some(felt!("101"))), + (ContractAddress::from(felt!("2")), felt!("1"), Some(felt!("200"))), + (ContractAddress::from(felt!("2")), felt!("2"), Some(felt!("201"))), + ]) + ] + #[case::storage_at_block_4( + 4, + vec![ + (ContractAddress::from(felt!("1")), felt!("1"), Some(felt!("111"))), + (ContractAddress::from(felt!("1")), felt!("2"), Some(felt!("222"))), + (ContractAddress::from(felt!("2")), felt!("1"), Some(felt!("200"))), + (ContractAddress::from(felt!("2")), felt!("2"), Some(felt!("201"))), + ]) + ] + #[case::storage_at_block_5( + 5, + vec![ + (ContractAddress::from(felt!("1")), felt!("1"), Some(felt!("111"))), + (ContractAddress::from(felt!("1")), felt!("2"), Some(felt!("222"))), + (ContractAddress::from(felt!("1")), felt!("3"), Some(felt!("77"))), + (ContractAddress::from(felt!("2")), felt!("1"), Some(felt!("12"))), + (ContractAddress::from(felt!("2")), felt!("2"), Some(felt!("13"))), + ]) + ] + fn test_historical_storage_read( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) { + } + + #[apply(test_historical_storage_read)] + fn read_storage_from_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_historical_storage_value(provider, block_num, expected_storage_entry) + } + + #[apply(test_historical_storage_read)] + fn read_storage_from_fork_provider_with_spawned_fork_network( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] block_num: BlockNumber, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_historical_storage_value(provider, block_num, expected_storage_entry) + } +} diff --git a/crates/katana/storage/provider/tests/utils.rs b/crates/katana/storage/provider/tests/utils.rs new file mode 100644 index 0000000000..510b80e70a --- /dev/null +++ b/crates/katana/storage/provider/tests/utils.rs @@ -0,0 +1,46 @@ +use katana_primitives::block::{Block, BlockHash, FinalityStatus, Header, SealedBlockWithStatus}; +use katana_primitives::receipt::{InvokeTxReceipt, Receipt}; +use katana_primitives::transaction::{Tx, TxHash, TxWithHash}; +use katana_primitives::FieldElement; + +pub fn generate_dummy_txs_and_receipts(count: usize) -> (Vec, Vec) { + let mut txs = Vec::with_capacity(count); + let mut receipts = Vec::with_capacity(count); + + // TODO: generate random txs and receipts variants + for _ in 0..count { + txs.push(TxWithHash { + hash: TxHash::from(rand::random::()), + transaction: Tx::Invoke(Default::default()), + }); + + receipts.push(Receipt::Invoke(InvokeTxReceipt::default())); + } + + (txs, receipts) +} + +pub fn generate_dummy_blocks_and_receipts( + count: u64, +) -> Vec<(SealedBlockWithStatus, Vec)> { + let mut blocks = Vec::with_capacity(count as usize); + let mut parent_hash: BlockHash = 0u8.into(); + + for i in 0..count { + let tx_count = (rand::random::() % 10) as usize; + let (body, receipts) = generate_dummy_txs_and_receipts(tx_count); + + let header = Header { parent_hash, number: i, ..Default::default() }; + let block = + Block { header, body }.seal_with_hash(FieldElement::from(rand::random::())); + + parent_hash = block.header.hash; + + blocks.push(( + SealedBlockWithStatus { block, status: FinalityStatus::AcceptedOnL2 }, + receipts, + )); + } + + blocks +} From 792194c1333226bbd1cec2d0aec7012d6f3a81fd Mon Sep 17 00:00:00 2001 From: glihm Date: Wed, 20 Dec 2023 10:27:32 -0600 Subject: [PATCH 35/42] feat: use of `WorldContractReader` from `abigen!` (#1010) * feat: add cainome abigen to sozo * feat: add cainome abigen to torii * fix: adjust test and fmt * fix: remove additional calldata input * feat(katana-rpc): add ContractErrorData when it applies * fix: fix tests * fix: adjust indexes for executor call results * fix: restore Scarb.lock and add .tool-versions * chore: bump cainome to 0.1.5 * fix: embed world and executor ABI in .git * chore: bump cainome to 0.1.7 * chore: update Scarb.lock * docs: update README for contract ABI * fix: fmt clippy from merge * fix: fix PR comments * fix: fix typo after test being run * fix: fix Scarb.lock version --- Cargo.lock | 48 ++ crates/dojo-core/.tool-versions | 1 + crates/dojo-world/Cargo.toml | 1 + crates/dojo-world/src/contracts/abi/README.md | 13 + .../src/contracts/abi/executor.json | 53 ++ .../dojo-world/src/contracts/abi/world.json | 775 ++++++++++++++++++ .../dojo-world/src/contracts/cairo_utils.rs | 26 + crates/dojo-world/src/contracts/mod.rs | 3 +- crates/dojo-world/src/contracts/model.rs | 72 +- crates/dojo-world/src/contracts/model_test.rs | 4 +- crates/dojo-world/src/contracts/world.rs | 334 +------- crates/dojo-world/src/contracts/world_test.rs | 18 +- crates/dojo-world/src/manifest.rs | 22 +- crates/sozo/src/ops/auth.rs | 4 +- crates/sozo/src/ops/migration/mod.rs | 20 +- crates/sozo/src/ops/model.rs | 6 +- crates/sozo/src/ops/register.rs | 13 +- crates/torii/client/src/client/mod.rs | 6 +- crates/torii/core/src/engine.rs | 2 +- crates/torii/core/src/processors/mod.rs | 2 +- .../core/src/processors/register_model.rs | 2 +- examples/spawn-and-move/Scarb.lock | 2 +- 22 files changed, 1046 insertions(+), 381 deletions(-) create mode 100644 crates/dojo-core/.tool-versions create mode 100644 crates/dojo-world/src/contracts/abi/README.md create mode 100644 crates/dojo-world/src/contracts/abi/executor.json create mode 100644 crates/dojo-world/src/contracts/abi/world.json create mode 100644 crates/dojo-world/src/contracts/cairo_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 67bb5e3c7b..d1ecb5a4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1117,6 +1117,53 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +[[package]] +name = "cainome" +version = "0.1.5" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.7#2d4b52b2e79796f76fba9e3a1b1027e8e63292b8" +dependencies = [ + "cainome-cairo-serde", + "cainome-parser", + "cainome-rs", +] + +[[package]] +name = "cainome-cairo-serde" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.7#2d4b52b2e79796f76fba9e3a1b1027e8e63292b8" +dependencies = [ + "starknet", + "thiserror", +] + +[[package]] +name = "cainome-parser" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.7#2d4b52b2e79796f76fba9e3a1b1027e8e63292b8" +dependencies = [ + "quote", + "serde_json", + "starknet", + "syn 2.0.41", + "thiserror", +] + +[[package]] +name = "cainome-rs" +version = "0.1.0" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.1.7#2d4b52b2e79796f76fba9e3a1b1027e8e63292b8" +dependencies = [ + "anyhow", + "cainome-cairo-serde", + "cainome-parser", + "proc-macro2", + "quote", + "serde_json", + "starknet", + "syn 2.0.41", + "thiserror", +] + [[package]] name = "cairo-felt" version = "0.8.2" @@ -2761,6 +2808,7 @@ dependencies = [ "assert_fs", "assert_matches", "async-trait", + "cainome", "cairo-lang-filesystem", "cairo-lang-project", "cairo-lang-starknet", diff --git a/crates/dojo-core/.tool-versions b/crates/dojo-core/.tool-versions new file mode 100644 index 0000000000..21cfc80772 --- /dev/null +++ b/crates/dojo-core/.tool-versions @@ -0,0 +1 @@ +scarb 2.4.0 diff --git a/crates/dojo-world/Cargo.toml b/crates/dojo-world/Cargo.toml index d6da3ff3b0..cbedf2fa5e 100644 --- a/crates/dojo-world/Cargo.toml +++ b/crates/dojo-world/Cargo.toml @@ -24,6 +24,7 @@ starknet.workspace = true thiserror.workspace = true tracing.workspace = true +cainome = { git = "https://github.com/cartridge-gg/cainome", tag = "v0.1.7", features = ["abigen-rs"] } dojo-types = { path = "../dojo-types", optional = true } http = { version = "0.2.9", optional = true } ipfs-api-backend-hyper = { git = "https://github.com/ferristseng/rust-ipfs-api", rev = "af2c17f7b19ef5b9898f458d97a90055c3605633", features = [ "with-hyper-rustls" ], optional = true } diff --git a/crates/dojo-world/src/contracts/abi/README.md b/crates/dojo-world/src/contracts/abi/README.md new file mode 100644 index 0000000000..3985ecc602 --- /dev/null +++ b/crates/dojo-world/src/contracts/abi/README.md @@ -0,0 +1,13 @@ +# Embedded ABI for contracts + +Currently, the ABIs for `world` and `executor` are embedded in the repo. +To build them, consider the following: + +1. Change directory into `examples/spawn-and-move` at the root of the workspace. +2. Build the example with `sozo`. +3. Extract the ABI key only for `world` and `executor`: +``` +sozo build +jq .abi ./target/dev/dojo\:\:world\:\:world.json > ../../crates/dojo-world/src/contracts/abi/world.json +jq .abi ./target/dev/dojo\:\:executor\:\:executor.json > ../../crates/dojo-world/src/contracts/abi/executor.json +``` diff --git a/crates/dojo-world/src/contracts/abi/executor.json b/crates/dojo-world/src/contracts/abi/executor.json new file mode 100644 index 0000000000..ad21e66317 --- /dev/null +++ b/crates/dojo-world/src/contracts/abi/executor.json @@ -0,0 +1,53 @@ +[ + { + "type": "impl", + "name": "Executor", + "interface_name": "dojo::executor::IExecutor" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "interface", + "name": "dojo::executor::IExecutor", + "items": [ + { + "type": "function", + "name": "call", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + }, + { + "name": "entrypoint", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "dojo::executor::executor::Event", + "kind": "enum", + "variants": [] + } +] diff --git a/crates/dojo-world/src/contracts/abi/world.json b/crates/dojo-world/src/contracts/abi/world.json new file mode 100644 index 0000000000..f1f0fa062b --- /dev/null +++ b/crates/dojo-world/src/contracts/abi/world.json @@ -0,0 +1,775 @@ +[ + { + "type": "impl", + "name": "World", + "interface_name": "dojo::world::IWorld" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::felt252" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::>" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::IWorld", + "items": [ + { + "type": "function", + "name": "metadata_uri", + "inputs": [ + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_metadata_uri", + "inputs": [ + { + "name": "resource", + "type": "core::felt252" + }, + { + "name": "uri", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "model", + "inputs": [ + { + "name": "name", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "register_model", + "inputs": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "deploy_contract", + "inputs": [ + { + "name": "salt", + "type": "core::felt252" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "upgrade_contract", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "uuid", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "emit", + "inputs": [ + { + "name": "keys", + "type": "core::array::Array::" + }, + { + "name": "values", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "view" + }, + { + "type": "function", + "name": "entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "offset", + "type": "core::integer::u8" + }, + { + "name": "length", + "type": "core::integer::u32" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "offset", + "type": "core::integer::u8" + }, + { + "name": "values", + "type": "core::array::Span::" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "entities", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "index", + "type": "core::option::Option::" + }, + { + "name": "values", + "type": "core::array::Span::" + }, + { + "name": "values_length", + "type": "core::integer::u32" + }, + { + "name": "values_layout", + "type": "core::array::Span::" + } + ], + "outputs": [ + { + "type": "(core::array::Span::, core::array::Span::>)" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "entity_ids", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_executor", + "inputs": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "executor", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "base", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::class_hash::ClassHash" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "delete_entity", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "keys", + "type": "core::array::Span::" + }, + { + "name": "layout", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "is_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "grant_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "revoke_owner", + "inputs": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "resource", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "is_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "grant_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "revoke_writer", + "inputs": [ + { + "name": "model", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "UpgradeableWorld", + "interface_name": "dojo::world::IUpgradeableWorld" + }, + { + "type": "interface", + "name": "dojo::world::IUpgradeableWorld", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "executor", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "contract_base", + "type": "core::starknet::class_hash::ClassHash" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WorldSpawned", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ContractDeployed", + "kind": "struct", + "members": [ + { + "name": "salt", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ContractUpgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WorldUpgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::MetadataUpdate", + "kind": "struct", + "members": [ + { + "name": "resource", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "uri", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ModelRegistered", + "kind": "struct", + "members": [ + { + "name": "name", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + }, + { + "name": "prev_class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::StoreSetRecord", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "keys", + "type": "core::array::Span::", + "kind": "data" + }, + { + "name": "offset", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "values", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::StoreDelRecord", + "kind": "struct", + "members": [ + { + "name": "table", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "keys", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::WriterUpdated", + "kind": "struct", + "members": [ + { + "name": "model", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "value", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::OwnerUpdated", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "resource", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "value", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::ExecutorUpdated", + "kind": "struct", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "prev_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::world::world::Event", + "kind": "enum", + "variants": [ + { + "name": "WorldSpawned", + "type": "dojo::world::world::WorldSpawned", + "kind": "nested" + }, + { + "name": "ContractDeployed", + "type": "dojo::world::world::ContractDeployed", + "kind": "nested" + }, + { + "name": "ContractUpgraded", + "type": "dojo::world::world::ContractUpgraded", + "kind": "nested" + }, + { + "name": "WorldUpgraded", + "type": "dojo::world::world::WorldUpgraded", + "kind": "nested" + }, + { + "name": "MetadataUpdate", + "type": "dojo::world::world::MetadataUpdate", + "kind": "nested" + }, + { + "name": "ModelRegistered", + "type": "dojo::world::world::ModelRegistered", + "kind": "nested" + }, + { + "name": "StoreSetRecord", + "type": "dojo::world::world::StoreSetRecord", + "kind": "nested" + }, + { + "name": "StoreDelRecord", + "type": "dojo::world::world::StoreDelRecord", + "kind": "nested" + }, + { + "name": "WriterUpdated", + "type": "dojo::world::world::WriterUpdated", + "kind": "nested" + }, + { + "name": "OwnerUpdated", + "type": "dojo::world::world::OwnerUpdated", + "kind": "nested" + }, + { + "name": "ExecutorUpdated", + "type": "dojo::world::world::ExecutorUpdated", + "kind": "nested" + } + ] + } +] diff --git a/crates/dojo-world/src/contracts/cairo_utils.rs b/crates/dojo-world/src/contracts/cairo_utils.rs new file mode 100644 index 0000000000..b43ff5be7d --- /dev/null +++ b/crates/dojo-world/src/contracts/cairo_utils.rs @@ -0,0 +1,26 @@ +use anyhow::{anyhow, Result}; +use http::uri::Uri; +use starknet::core::types::FieldElement; +use starknet::core::utils::cairo_short_string_to_felt; + +pub fn str_to_felt(string: &str) -> Result { + cairo_short_string_to_felt(string).map_err(|e| { + anyhow!(format!("Failed to convert string `{}` to cairo short string: {}", string, e)) + }) +} + +pub fn encode_uri(uri: &str) -> Result> { + let parsed: Uri = + uri.try_into().map_err(|e| anyhow!("Failed to encode URI `{}`: {}", uri, e))?; + + Ok(parsed + .to_string() + .chars() + .collect::>() + .chunks(31) + .map(|chunk| { + let s: String = chunk.iter().collect(); + cairo_short_string_to_felt(&s) + }) + .collect::, _>>()?) +} diff --git a/crates/dojo-world/src/contracts/mod.rs b/crates/dojo-world/src/contracts/mod.rs index 8d122a0dd3..3c09618fc4 100644 --- a/crates/dojo-world/src/contracts/mod.rs +++ b/crates/dojo-world/src/contracts/mod.rs @@ -1,4 +1,5 @@ +pub mod cairo_utils; pub mod model; pub mod world; -pub use world::{WorldContract, WorldContractError, WorldContractReader}; +pub use world::{WorldContract, WorldContractReader}; diff --git a/crates/dojo-world/src/contracts/model.rs b/crates/dojo-world/src/contracts/model.rs index 433f3b8cd4..b0ac6e37ed 100644 --- a/crates/dojo-world/src/contracts/model.rs +++ b/crates/dojo-world/src/contracts/model.rs @@ -1,10 +1,11 @@ use std::vec; use async_trait::async_trait; +use cainome::cairo_serde::Error as CainomeError; use dojo_types::packing::{parse_ty, unpack, PackingError, ParseError}; use dojo_types::primitive::PrimitiveError; use dojo_types::schema::Ty; -use starknet::core::types::{FieldElement, FunctionCall, StarknetError}; +use starknet::core::types::{FieldElement, StarknetError}; use starknet::core::utils::{ cairo_short_string_to_felt, get_selector_from_name, CairoShortStringToFeltError, ParseCairoShortStringError, @@ -13,9 +14,8 @@ use starknet::macros::short_string; use starknet::providers::{Provider, ProviderError}; use starknet_crypto::poseidon_hash_many; -use crate::contracts::world::{ContractReaderError, WorldContractReader}; +use crate::contracts::WorldContractReader; -const WORLD_MODEL_SELECTOR_STR: &str = "model"; const SCHEMA_SELECTOR_STR: &str = "schema"; const LAYOUT_SELECTOR_STR: &str = "layout"; const PACKED_SIZE_SELECTOR_STR: &str = "packed_size"; @@ -36,13 +36,13 @@ pub enum ModelError { #[error(transparent)] CairoShortStringToFeltError(#[from] CairoShortStringToFeltError), #[error(transparent)] - ContractReaderError(#[from] ContractReaderError), - #[error(transparent)] CairoTypeError(#[from] PrimitiveError), #[error(transparent)] Parse(#[from] ParseError), #[error(transparent)] Packing(#[from] PackingError), + #[error(transparent)] + Cainome(#[from] CainomeError), } #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -55,7 +55,7 @@ pub trait ModelReader { async fn layout(&self) -> Result, E>; } -pub struct ModelRPCReader<'a, P: Sync + Send> { +pub struct ModelRPCReader<'a, P: Provider + Sync + Send> { /// The name of the model name: FieldElement, /// The class hash of the model @@ -74,26 +74,15 @@ where ) -> Result, ModelError> { let name = cairo_short_string_to_felt(name)?; - let class_hash = world - .provider() - .call( - FunctionCall { - calldata: vec![name], - contract_address: world.address(), - entry_point_selector: get_selector_from_name(WORLD_MODEL_SELECTOR_STR).unwrap(), - }, - world.block_id(), - ) - .await - .map(|res| res[0]) - .map_err(|err| match err { - ProviderError::StarknetError(StarknetError::ContractNotFound) => { - ModelError::ModelNotFound - } + let class_hash = + world.model(&name).block_id(world.block_id).call().await.map_err(|err| match err { + CainomeError::Provider(ProviderError::StarknetError( + StarknetError::ContractNotFound, + )) => ModelError::ModelNotFound, err => err.into(), })?; - Ok(Self { world_reader: world, class_hash, name }) + Ok(Self { world_reader: world, class_hash: class_hash.into(), name }) } pub async fn entity_storage( @@ -112,9 +101,9 @@ where .world_reader .provider() .get_storage_at( - self.world_reader.address(), + self.world_reader.address, key + slot.into(), - self.world_reader.block_id(), + self.world_reader.block_id, ) .await?; @@ -152,44 +141,37 @@ where async fn schema(&self) -> Result { let entrypoint = get_selector_from_name(SCHEMA_SELECTOR_STR).unwrap(); - let res = self - .world_reader - .executor_call(self.class_hash, vec![entrypoint, FieldElement::ZERO]) - .await?; + let res = self.world_reader.executor_call(self.class_hash, entrypoint, vec![]).await?; - Ok(parse_ty(&res[1..])?) + Ok(parse_ty(&res)?) } async fn packed_size(&self) -> Result { let entrypoint = get_selector_from_name(PACKED_SIZE_SELECTOR_STR).unwrap(); - let res = self - .world_reader - .executor_call(self.class_hash, vec![entrypoint, FieldElement::ZERO]) - .await?; + let res = self.world_reader.executor_call(self.class_hash, entrypoint, vec![]).await?; - Ok(res[1]) + Ok(res[0]) } async fn unpacked_size(&self) -> Result { let entrypoint = get_selector_from_name(UNPACKED_SIZE_SELECTOR_STR).unwrap(); - let res = self - .world_reader - .executor_call(self.class_hash, vec![entrypoint, FieldElement::ZERO]) - .await?; + let res = self.world_reader.executor_call(self.class_hash, entrypoint, vec![]).await?; - Ok(res[1]) + Ok(res[0]) } async fn layout(&self) -> Result, ModelError> { let entrypoint = get_selector_from_name(LAYOUT_SELECTOR_STR).unwrap(); - let res = self - .world_reader - .executor_call(self.class_hash, vec![entrypoint, FieldElement::ZERO]) - .await?; + let res = self.world_reader.executor_call(self.class_hash, entrypoint, vec![]).await?; - Ok(res[2..].into()) + // Layout entrypoint expanded by the #[model] attribute returns a + // `Span`. So cainome generated code will deserialize the result + // of `executor.call()` which is a Vec. + // So inside the vec, we skip the first element, which is the length + // of the span returned by `layout` entrypoint of the model code. + Ok(res[1..].into()) } } diff --git a/crates/dojo-world/src/contracts/model_test.rs b/crates/dojo-world/src/contracts/model_test.rs index cd235080da..efab444182 100644 --- a/crates/dojo-world/src/contracts/model_test.rs +++ b/crates/dojo-world/src/contracts/model_test.rs @@ -24,7 +24,7 @@ async fn test_model() { .await; let world = WorldContractReader::new(world_address, provider); - let position = world.model("Position").await.unwrap(); + let position = world.model_reader("Position").await.unwrap(); let schema = position.schema().await.unwrap(); assert_eq!( @@ -68,7 +68,7 @@ async fn test_model() { .unwrap() ); - let moves = world.model("Moves").await.unwrap(); + let moves = world.model_reader("Moves").await.unwrap(); let schema = moves.schema().await.unwrap(); assert_eq!( diff --git a/crates/dojo-world/src/contracts/world.rs b/crates/dojo-world/src/contracts/world.rs index 93bd56d8c7..b8bcfe9d2d 100644 --- a/crates/dojo-world/src/contracts/world.rs +++ b/crates/dojo-world/src/contracts/world.rs @@ -1,15 +1,9 @@ use std::result::Result; -use http::uri::{InvalidUri, Uri}; -use starknet::accounts::{AccountError, Call, ConnectedAccount}; -use starknet::core::types::{ - BlockId, BlockTag, FieldElement, FunctionCall, InvokeTransactionResult, -}; -use starknet::core::utils::{ - cairo_short_string_to_felt, get_selector_from_name, CairoShortStringToFeltError, -}; -use starknet::macros::selector; -use starknet::providers::{Provider, ProviderError}; +pub use abigen::world::{WorldContract, WorldContractReader}; +use cainome::cairo_serde::Result as CainomeResult; +use starknet::core::types::FieldElement; +use starknet::providers::Provider; use super::model::{ModelError, ModelRPCReader}; @@ -17,318 +11,62 @@ use super::model::{ModelError, ModelRPCReader}; #[path = "world_test.rs"] pub(crate) mod test; -#[derive(Debug, thiserror::Error)] -pub enum WorldContractError { - #[error(transparent)] - ProviderError(#[from] ProviderError), - #[error(transparent)] - AccountError(#[from] AccountError), - #[error(transparent)] - CairoShortStringToFeltError(#[from] CairoShortStringToFeltError), - #[error(transparent)] - ContractReaderError(#[from] ContractReaderError), - #[error("Invalid metadata uri")] - InvalidMetadataUri(#[from] InvalidUri), -} - -pub struct WorldContract<'a, A> -where - A: ConnectedAccount, -{ - account: &'a A, - reader: WorldContractReader<&'a ::Provider>, -} - -impl<'a, A> WorldContract<'a, A> -where - A: ConnectedAccount, -{ - pub fn new(address: FieldElement, account: &'a A) -> Self { - Self { account, reader: WorldContractReader::new(address, account.provider()) } +#[cfg(not(doctest))] +pub mod abigen { + pub mod world { + use cainome::rs::abigen; + abigen!(WorldContract, "crates/dojo-world/src/contracts/abi/world.json"); } - pub fn account(&self) -> &A { - self.account + pub mod executor { + use cainome::rs::abigen; + abigen!(ExecutorContract, "crates/dojo-world/src/contracts/abi/executor.json"); } } -impl<'a, A> WorldContract<'a, A> -where - A: ConnectedAccount + Sync, -{ - pub async fn set_executor( - &self, - executor: FieldElement, - ) -> Result> { - self.account - .execute(vec![Call { - to: self.reader.address, - calldata: vec![executor], - selector: selector!("set_executor"), - }]) - .send() - .await - } - - pub async fn set_metadata_uri( - &self, - resource: FieldElement, - metadata_uri: String, - ) -> Result> { - let parsed: Uri = - metadata_uri.try_into().map_err(WorldContractError::InvalidMetadataUri)?; - - let mut encoded = parsed - .to_string() - .chars() - .collect::>() - .chunks(31) - .map(|chunk| { - let s: String = chunk.iter().collect(); - cairo_short_string_to_felt(&s).unwrap() - }) - .collect::>(); - - encoded.insert(0, encoded.len().into()); - encoded.insert(0, resource); - - self.account - .execute(vec![Call { - calldata: encoded, - to: self.reader.address, - selector: get_selector_from_name("set_metadata_uri").unwrap(), - }]) - .send() - .await - .map_err(WorldContractError::AccountError) - } - - pub async fn grant_writer( - &self, - model: &str, - contract: FieldElement, - ) -> Result> { - let model = cairo_short_string_to_felt(model) - .map_err(WorldContractError::CairoShortStringToFeltError)?; - - self.account - .execute(vec![Call { - calldata: vec![model, contract], - to: self.reader.address, - selector: get_selector_from_name("grant_writer").unwrap(), - }]) - .send() - .await - .map_err(WorldContractError::AccountError) - } - - pub async fn register_models( - &self, - models: &[FieldElement], - ) -> Result> { - let calls = models - .iter() - .map(|c| Call { - to: self.reader.address, - selector: selector!("register_model"), - calldata: vec![*c], - }) - .collect::>(); - - self.account.execute(calls).send().await +#[cfg(doctest)] +pub mod abigen { + pub mod world { + use cainome::rs::abigen; + abigen!(WorldContract, "src/contracts/abi/world.json"); } - pub async fn deploy_contract( - &self, - salt: &FieldElement, - class_hash: &FieldElement, - ) -> Result> { - self.account - .execute(vec![Call { - to: self.reader.address, - selector: selector!("deploy_contract"), - calldata: vec![*salt, *class_hash], - }]) - .send() - .await + pub mod executor { + use cainome::rs::abigen; + abigen!(ExecutorContract, "src/contracts/abi/executor.json"); } - - pub async fn executor(&self) -> Result { - self.reader.executor().await - } - - pub async fn base(&self) -> Result { - self.reader.base().await - } - - pub async fn model( - &'a self, - name: &str, - ) -> Result, ModelError> { - self.reader.model(name).await - } -} - -#[derive(Debug, thiserror::Error)] -pub enum ContractReaderError { - #[error(transparent)] - ProviderError(#[from] ProviderError), - #[error(transparent)] - CairoShortStringToFeltError(#[from] CairoShortStringToFeltError), -} - -pub struct WorldContractReader

{ - provider: P, - block_id: BlockId, - address: FieldElement, } impl

WorldContractReader

where - P: Provider, + P: Provider + Sync + Send, { - pub fn new(address: FieldElement, provider: P) -> Self { - Self { address, provider, block_id: BlockId::Tag(BlockTag::Latest) } - } - - pub fn with_block(self, block: BlockId) -> Self { - Self { block_id: block, ..self } - } - - pub fn address(&self) -> FieldElement { - self.address - } - - pub fn provider(&self) -> &P { - &self.provider - } - - pub fn block_id(&self) -> BlockId { - self.block_id + pub async fn model_reader(&self, name: &str) -> Result, ModelError> { + ModelRPCReader::new(name, self).await } } impl

WorldContractReader

where - P: Provider, + P: Provider + Sync + Send, { - pub async fn is_authorized( - &self, - system: &str, - model: &str, - execution_role: &str, - ) -> Result { - let res = self - .provider - .call( - FunctionCall { - calldata: vec![ - cairo_short_string_to_felt(system)?, - cairo_short_string_to_felt(model)?, - cairo_short_string_to_felt(execution_role)?, - ], - contract_address: self.address, - entry_point_selector: selector!("is_authorized"), - }, - self.block_id, - ) - .await?; - - Ok(res[0] == FieldElement::ONE) - } - - pub async fn is_account_admin(&self) -> Result { - let res = self - .provider - .call( - FunctionCall { - calldata: vec![], - contract_address: self.address, - entry_point_selector: selector!("is_account_admin"), - }, - self.block_id, - ) - .await?; - - Ok(res[0] == FieldElement::ONE) - } - - pub async fn executor(&self) -> Result { - let res = self - .provider - .call( - FunctionCall { - calldata: vec![], - contract_address: self.address, - entry_point_selector: selector!("executor"), - }, - self.block_id, - ) - .await?; - - Ok(res[0]) - } - - pub async fn metadata_uri(&self) -> Result { - let res = self - .provider - .call( - FunctionCall { - calldata: vec![], - contract_address: self.address, - entry_point_selector: selector!("metadata_uri"), - }, - self.block_id, - ) - .await?; - - Ok(res[0]) - } - - pub async fn base(&self) -> Result { - let res = self - .provider - .call( - FunctionCall { - calldata: vec![], - contract_address: self.address, - entry_point_selector: selector!("base"), - }, - self.block_id, - ) - .await?; - - Ok(res[0]) - } - pub async fn executor_call( &self, class_hash: FieldElement, - mut calldata: Vec, - ) -> Result, ContractReaderError> { - calldata.insert(0, class_hash); - - let res = self - .provider - .call( - FunctionCall { - calldata, - contract_address: self.executor().await?, - entry_point_selector: selector!("call"), - }, - self.block_id, - ) + entry_point: FieldElement, + calldata: Vec, + ) -> CainomeResult> { + let executor_address = self.executor().block_id(self.block_id).call().await?; + + let executor = + abigen::executor::ExecutorContractReader::new(executor_address.into(), &self.provider); + + let res = executor + .call(&class_hash.into(), &entry_point, &calldata) + .block_id(self.block_id) + .call() .await?; Ok(res) } } - -impl<'a, P> WorldContractReader

-where - P: Provider + Sync + Send, -{ - pub async fn model(&'a self, name: &str) -> Result, ModelError> { - ModelRPCReader::new(name, self).await - } -} diff --git a/crates/dojo-world/src/contracts/world_test.rs b/crates/dojo-world/src/contracts/world_test.rs index 2e41ef6e2e..2028fad8b8 100644 --- a/crates/dojo-world/src/contracts/world_test.rs +++ b/crates/dojo-world/src/contracts/world_test.rs @@ -4,7 +4,7 @@ use camino::Utf8PathBuf; use dojo_test_utils::sequencer::{ get_default_test_starknet_config, SequencerConfig, TestSequencer, }; -use starknet::accounts::ConnectedAccount; +use starknet::accounts::{Account, ConnectedAccount}; use starknet::core::types::FieldElement; use super::{WorldContract, WorldContractReader}; @@ -26,9 +26,9 @@ async fn test_world_contract_reader() { .await; let world = WorldContractReader::new(world_address, provider); - let executor = world.executor().await.unwrap(); + let executor = world.executor().call().await.unwrap(); - assert_eq!(executor, executor_address); + assert_eq!(FieldElement::from(executor), executor_address); } pub async fn deploy_world( @@ -82,10 +82,14 @@ pub async fn deploy_world( // wait for the tx to be mined tokio::time::sleep(Duration::from_millis(250)).await; - let _ = WorldContract::new(world_address, &account) - .register_models(&declare_output.iter().map(|o| o.class_hash).collect::>()) - .await - .unwrap(); + let world = WorldContract::new(world_address, &account); + + let calls = declare_output + .iter() + .map(|o| world.register_model_getcall(&o.class_hash.into())) + .collect::>(); + + let _ = account.execute(calls).send().await.unwrap(); // wait for the tx to be mined tokio::time::sleep(Duration::from_millis(250)).await; diff --git a/crates/dojo-world/src/manifest.rs b/crates/dojo-world/src/manifest.rs index 5854b7110f..75dfac5135 100644 --- a/crates/dojo-world/src/manifest.rs +++ b/crates/dojo-world/src/manifest.rs @@ -3,6 +3,7 @@ use std::fs; use std::path::Path; use ::serde::{Deserialize, Serialize}; +use cainome::cairo_serde::Error as CainomeError; use cairo_lang_starknet::abi; use serde_with::serde_as; use smol_str::SmolStr; @@ -19,7 +20,6 @@ use starknet::providers::{Provider, ProviderError}; use thiserror::Error; use crate::contracts::model::ModelError; -use crate::contracts::world::ContractReaderError; use crate::contracts::WorldContractReader; #[cfg(test)] @@ -45,7 +45,7 @@ pub enum ManifestError { #[error(transparent)] Provider(#[from] ProviderError), #[error(transparent)] - ContractRead(#[from] ContractReaderError), + ContractRead(#[from] CainomeError), #[error(transparent)] Model(#[from] ModelError), } @@ -172,13 +172,14 @@ impl Manifest { err => err.into(), })?; - let world = WorldContractReader::new(world_address, &provider).with_block(BLOCK_ID); + let world = WorldContractReader::new(world_address, provider); - let executor_address = world.executor().await?; - let base_class_hash = world.base().await?; + let executor_address = world.executor().block_id(BLOCK_ID).call().await?; + let base_class_hash = world.base().block_id(BLOCK_ID).call().await?; - let executor_class_hash = provider - .get_class_hash_at(BLOCK_ID, executor_address) + let executor_class_hash = world + .provider() + .get_class_hash_at(BLOCK_ID, FieldElement::from(executor_address)) .await .map_err(|err| match err { ProviderError::StarknetError(StarknetError::ContractNotFound) => { @@ -187,7 +188,8 @@ impl Manifest { err => err.into(), })?; - let (models, contracts) = get_remote_models_and_contracts(world_address, provider).await?; + let (models, contracts) = + get_remote_models_and_contracts(world_address, &world.provider()).await?; Ok(Manifest { models, @@ -200,13 +202,13 @@ impl Manifest { }, executor: Contract { name: EXECUTOR_CONTRACT_NAME.into(), - address: Some(executor_address), + address: Some(executor_address.into()), class_hash: executor_class_hash, ..Default::default() }, base: Class { name: BASE_CONTRACT_NAME.into(), - class_hash: base_class_hash, + class_hash: base_class_hash.into(), ..Default::default() }, }) diff --git a/crates/sozo/src/ops/auth.rs b/crates/sozo/src/ops/auth.rs index 27125e9d6b..e2757f59e6 100644 --- a/crates/sozo/src/ops/auth.rs +++ b/crates/sozo/src/ops/auth.rs @@ -1,4 +1,5 @@ use anyhow::{Context, Result}; +use dojo_world::contracts::cairo_utils; use dojo_world::contracts::world::WorldContract; use dojo_world::metadata::Environment; @@ -14,7 +15,8 @@ pub async fn execute(command: AuthCommand, env_metadata: Option) -> let world = WorldContract::new(world_address, &account); let res = world - .grant_writer(&model, contract) + .grant_writer(&cairo_utils::str_to_felt(&model)?, &contract.into()) + .send() .await .with_context(|| "Failed to send transaction")?; diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index 4b8fc8b851..1fbfb96b29 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -1,6 +1,7 @@ use std::path::Path; use anyhow::{anyhow, bail, Context, Result}; +use dojo_world::contracts::cairo_utils; use dojo_world::contracts::world::WorldContract; use dojo_world::manifest::{Manifest, ManifestError}; use dojo_world::metadata::dojo_metadata_from_workspace; @@ -292,7 +293,8 @@ where let addr = strategy.world_address()?; let InvokeTransactionResult { transaction_hash } = WorldContract::new(addr, &migrator) - .set_executor(executor.contract_address) + .set_executor(&executor.contract_address.into()) + .send() .await?; TransactionWaiter::new(transaction_hash, migrator.provider()).await?; @@ -343,9 +345,12 @@ where if let Some(meta) = metadata.as_ref().and_then(|inner| inner.world()) { match meta.upload().await { Ok(hash) => { + let encoded_uri = cairo_utils::encode_uri(&format!("ipfs://{hash}"))?; + let InvokeTransactionResult { transaction_hash } = WorldContract::new(world.contract_address, migrator) - .set_metadata_uri(FieldElement::ZERO, format!("ipfs://{hash}")) + .set_metadata_uri(&FieldElement::ZERO, &encoded_uri) + .send() .await .map_err(|e| anyhow!("Failed to set World metadata: {e}"))?; @@ -459,9 +464,16 @@ where } let world_address = strategy.world_address()?; + let world = WorldContract::new(world_address, migrator); + + let calls = models + .iter() + .map(|c| world.register_model_getcall(&c.diff.local.into())) + .collect::>(); - let InvokeTransactionResult { transaction_hash } = WorldContract::new(world_address, migrator) - .register_models(&models.iter().map(|c| c.diff.local).collect::>()) + let InvokeTransactionResult { transaction_hash } = migrator + .execute(calls) + .send() .await .map_err(|e| anyhow!("Failed to register models to World: {e}"))?; diff --git a/crates/sozo/src/ops/model.rs b/crates/sozo/src/ops/model.rs index c22404dcec..a6cce2444d 100644 --- a/crates/sozo/src/ops/model.rs +++ b/crates/sozo/src/ops/model.rs @@ -15,7 +15,7 @@ pub async fn execute(command: ModelCommands, env_metadata: Option) let world = WorldContractReader::new(world_address, &provider) .with_block(BlockId::Tag(BlockTag::Pending)); - let model = world.model(&name).await?; + let model = world.model_reader(&name).await?; println!("{:#x}", model.class_hash()); } @@ -27,7 +27,7 @@ pub async fn execute(command: ModelCommands, env_metadata: Option) let world = WorldContractReader::new(world_address, &provider) .with_block(BlockId::Tag(BlockTag::Pending)); - let model = world.model(&name).await?; + let model = world.model_reader(&name).await?; let schema = model.schema().await?; if to_json { @@ -44,7 +44,7 @@ pub async fn execute(command: ModelCommands, env_metadata: Option) let world = WorldContractReader::new(world_address, &provider) .with_block(BlockId::Tag(BlockTag::Pending)); - let model = world.model(&name).await?; + let model = world.model_reader(&name).await?; let entity = model.entity(&keys).await?; println!("{entity}") diff --git a/crates/sozo/src/ops/register.rs b/crates/sozo/src/ops/register.rs index e91a97a7f3..5906a90fc6 100644 --- a/crates/sozo/src/ops/register.rs +++ b/crates/sozo/src/ops/register.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Result}; -use dojo_world::contracts::world::WorldContract; +use dojo_world::contracts::WorldContract; use dojo_world::metadata::Environment; +use starknet::accounts::Account; use crate::commands::register::RegisterCommand; @@ -13,8 +14,14 @@ pub async fn execute(command: RegisterCommand, env_metadata: Option let account = account.account(provider, env_metadata.as_ref()).await?; let world = WorldContract::new(world_address, &account); - let res = world - .register_models(&models) + let calls = models + .iter() + .map(|c| world.register_model_getcall(&(*c).into())) + .collect::>(); + + let res = account + .execute(calls) + .send() .await .with_context(|| "Failed to send transaction")?; diff --git a/crates/torii/client/src/client/mod.rs b/crates/torii/client/src/client/mod.rs index a79ba11ac5..6f231a447a 100644 --- a/crates/torii/client/src/client/mod.rs +++ b/crates/torii/client/src/client/mod.rs @@ -71,7 +71,7 @@ impl Client { // TODO: change this to querying the gRPC url instead let subbed_models = subbed_models.models_keys.read().clone(); for keys in subbed_models { - let model_reader = world_reader.model(&keys.model).await?; + let model_reader = world_reader.model_reader(&keys.model).await?; let values = model_reader.entity_storage(&keys.keys).await?; client_storage.set_model_storage( @@ -137,7 +137,7 @@ impl Client { }; if !self.subscribed_models.is_synced(keys) { - let model = self.world_reader.model(&keys.model).await?; + let model = self.world_reader.model_reader(&keys.model).await?; return Ok(Some(model.entity(&keys.keys).await?)); } @@ -232,7 +232,7 @@ impl Client { } async fn initiate_model(&self, model: &str, keys: Vec) -> Result<(), Error> { - let model_reader = self.world_reader.model(model).await?; + let model_reader = self.world_reader.model_reader(model).await?; let values = model_reader.entity_storage(&keys).await?; self.storage.set_model_storage( cairo_short_string_to_felt(model).map_err(ParseError::CairoShortStringToFelt)?, diff --git a/crates/torii/core/src/engine.rs b/crates/torii/core/src/engine.rs index 6f4724e7c5..55e6a57114 100644 --- a/crates/torii/core/src/engine.rs +++ b/crates/torii/core/src/engine.rs @@ -178,7 +178,7 @@ impl<'db, P: Provider + Sync> Engine<'db, P> { let mut world_event = false; for (event_idx, event) in invoke_receipt.events.iter().enumerate() { - if event.from_address != self.world.address() { + if event.from_address != self.world.address { continue; } diff --git a/crates/torii/core/src/processors/mod.rs b/crates/torii/core/src/processors/mod.rs index e8cb64da42..d503671b7d 100644 --- a/crates/torii/core/src/processors/mod.rs +++ b/crates/torii/core/src/processors/mod.rs @@ -14,7 +14,7 @@ pub mod store_transaction; #[async_trait] pub trait EventProcessor

where - P: Provider, + P: Provider + Sync, { fn event_key(&self) -> String; diff --git a/crates/torii/core/src/processors/register_model.rs b/crates/torii/core/src/processors/register_model.rs index 54b01f946d..1771605f6c 100644 --- a/crates/torii/core/src/processors/register_model.rs +++ b/crates/torii/core/src/processors/register_model.rs @@ -45,7 +45,7 @@ where ) -> Result<(), Error> { let name = parse_cairo_short_string(&event.data[0])?; - let model = world.model(&name).await?; + let model = world.model_reader(&name).await?; let schema = model.schema().await?; let layout = model.layout().await?; diff --git a/examples/spawn-and-move/Scarb.lock b/examples/spawn-and-move/Scarb.lock index 9474cc125c..883898be30 100644 --- a/examples/spawn-and-move/Scarb.lock +++ b/examples/spawn-and-move/Scarb.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "dojo_examples" -version = "0.4.0-rc0" +version = "0.4.1" dependencies = [ "dojo", ] From 945db9bdd4065aeba010c7877f85c5339ee74d49 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 20 Dec 2023 12:57:41 -0700 Subject: [PATCH 36/42] Update release flow --- .github/workflows/release-dispatch.yml | 6 ----- .github/workflows/release.yml | 34 ++++++++++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index c8ec5c6845..cd43bbf812 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -28,11 +28,6 @@ jobs: run: | cargo install cargo-get echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - - id: changelog - uses: mikepenz/release-changelog-builder-action@v4.1.0 - with: - fromTag: v${{ steps.current_release_info.outputs.version }} - toTag: main - uses: peter-evans/create-pull-request@v5 with: # We have to use a PAT in order to trigger ci @@ -42,4 +37,3 @@ jobs: branch: prepare-release base: main delete-branch: true - body: ${{steps.changelog.outputs.changelog}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe9d0d75a0..7ddd1751b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -118,19 +118,8 @@ jobs: fi shell: bash - # Creates the release for this specific version - - name: Create release - uses: softprops/action-gh-release@v1 - with: - name: ${{ github.event.pull_request.title }} - tag_name: ${{ needs.prepare.outputs.tag_name }} - body: ${{ github.event.pull_request.body }} - files: | - ${{ steps.artifacts.outputs.file_name }} - # We move binaries so they match $TARGETPLATFORM in the Docker build - name: Move Binaries - if: ${{ env.PLATFORM_NAME == 'linux' }} run: | mkdir -p $PLATFORM_NAME/$ARCH mv target/$TARGET/release/katana $PLATFORM_NAME/$ARCH @@ -146,8 +135,24 @@ jobs: path: ${{ env.PLATFORM_NAME }} retention-days: 1 + create-draft-release: + runs-on: ubuntu-latest-4-cores + needs: [prepare, release] + env: + GITHUB_USER: ${{ github.repository_owner }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v3 + with: + name: binaries + path: artifacts + - name: Display structure of downloaded files + run: ls -R artifacts + - run: gh release create --generate-notes --draft ./artifacts + docker-build-and-push: - name: Build and push docker image runs-on: ubuntu-latest-4-cores needs: [prepare, release] @@ -159,7 +164,10 @@ jobs: uses: actions/download-artifact@v3 with: name: binaries - path: artifacts/linux + path: artifacts + + - name: Display structure of downloaded files + run: ls -R artifacts - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 From cb2e3be93fc5f2f94f460e738b54476c66ec5c88 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 20 Dec 2023 15:20:56 -0500 Subject: [PATCH 37/42] Prepare release: v0.4.2 (#1322) --- Cargo.lock | 62 +++++++++++++++--------------- Cargo.toml | 2 +- crates/dojo-core/Scarb.lock | 2 +- crates/dojo-core/Scarb.toml | 2 +- crates/torii/types-test/Scarb.lock | 2 +- crates/torii/types-test/Scarb.toml | 2 +- examples/spawn-and-move/Scarb.lock | 2 +- examples/spawn-and-move/Scarb.toml | 2 +- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1ecb5a4b1..6d66fe6cca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -801,7 +801,7 @@ dependencies = [ [[package]] name = "benches" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "clap_builder", @@ -2670,15 +2670,15 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dojo-core" -version = "0.4.1" +version = "0.4.2" [[package]] name = "dojo-examples-spawn-and-move" -version = "0.4.1" +version = "0.4.2" [[package]] name = "dojo-lang" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2726,7 +2726,7 @@ dependencies = [ [[package]] name = "dojo-language-server" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "cairo-lang-compiler", @@ -2748,7 +2748,7 @@ dependencies = [ [[package]] name = "dojo-signers" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "starknet", @@ -2756,7 +2756,7 @@ dependencies = [ [[package]] name = "dojo-test-utils" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -2787,7 +2787,7 @@ dependencies = [ [[package]] name = "dojo-types" -version = "0.4.1" +version = "0.4.2" dependencies = [ "crypto-bigint", "hex", @@ -2802,7 +2802,7 @@ dependencies = [ [[package]] name = "dojo-world" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -5441,7 +5441,7 @@ dependencies = [ [[package]] name = "katana" -version = "0.4.1" +version = "0.4.2" dependencies = [ "assert_matches", "clap", @@ -5449,7 +5449,7 @@ dependencies = [ "console", "katana-core", "katana-rpc", - "metrics 0.4.1", + "metrics 0.4.2", "metrics-process", "serde_json", "starknet_api", @@ -5461,7 +5461,7 @@ dependencies = [ [[package]] name = "katana-codecs" -version = "0.4.1" +version = "0.4.2" dependencies = [ "bytes", "katana-primitives", @@ -5469,7 +5469,7 @@ dependencies = [ [[package]] name = "katana-codecs-derive" -version = "0.4.1" +version = "0.4.2" dependencies = [ "proc-macro2", "quote", @@ -5479,7 +5479,7 @@ dependencies = [ [[package]] name = "katana-core" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_matches", @@ -5512,7 +5512,7 @@ dependencies = [ [[package]] name = "katana-db" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "bincode 1.3.3", @@ -5535,7 +5535,7 @@ dependencies = [ [[package]] name = "katana-executor" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "blockifier", @@ -5551,7 +5551,7 @@ dependencies = [ [[package]] name = "katana-primitives" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "blockifier", @@ -5569,7 +5569,7 @@ dependencies = [ [[package]] name = "katana-provider" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "auto_impl", @@ -5591,7 +5591,7 @@ dependencies = [ [[package]] name = "katana-rpc" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_matches", @@ -5623,7 +5623,7 @@ dependencies = [ [[package]] name = "katana-rpc-types" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "derive_more", @@ -5636,7 +5636,7 @@ dependencies = [ [[package]] name = "katana-rpc-types-builder" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "katana-executor", @@ -5648,7 +5648,7 @@ dependencies = [ [[package]] name = "katana-runner" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "home", @@ -5939,7 +5939,7 @@ dependencies = [ [[package]] name = "metrics" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "hyper", @@ -8608,7 +8608,7 @@ dependencies = [ [[package]] name = "sozo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "assert_fs", @@ -9802,7 +9802,7 @@ dependencies = [ [[package]] name = "torii-client" -version = "0.4.1" +version = "0.4.2" dependencies = [ "async-trait", "camino", @@ -9828,7 +9828,7 @@ dependencies = [ [[package]] name = "torii-core" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", @@ -9864,7 +9864,7 @@ dependencies = [ [[package]] name = "torii-graphql" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-graphql", @@ -9903,7 +9903,7 @@ dependencies = [ [[package]] name = "torii-grpc" -version = "0.4.1" +version = "0.4.2" dependencies = [ "bytes", "crypto-bigint", @@ -9942,7 +9942,7 @@ dependencies = [ [[package]] name = "torii-server" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "async-trait", @@ -9961,7 +9961,7 @@ dependencies = [ "hyper-reverse-proxy", "indexmap 1.9.3", "lazy_static", - "metrics 0.4.1", + "metrics 0.4.2", "metrics-process", "scarb", "serde", @@ -10229,7 +10229,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types-test" -version = "0.4.1" +version = "0.4.2" [[package]] name = "ucd-trie" diff --git a/Cargo.toml b/Cargo.toml index d50ab59a7e..1ece9cfe98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ edition = "2021" license = "Apache-2.0" license-file = "LICENSE" repository = "https://github.com/dojoengine/dojo/" -version = "0.4.1" +version = "0.4.2" [profile.performance] codegen-units = 1 diff --git a/crates/dojo-core/Scarb.lock b/crates/dojo-core/Scarb.lock index ee17c212ea..14d33d1dbb 100644 --- a/crates/dojo-core/Scarb.lock +++ b/crates/dojo-core/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/crates/dojo-core/Scarb.toml b/crates/dojo-core/Scarb.toml index a8809ef181..ef1080e43a 100644 --- a/crates/dojo-core/Scarb.toml +++ b/crates/dojo-core/Scarb.toml @@ -2,7 +2,7 @@ cairo-version = "2.4.0" description = "The Dojo Core library for autonomous worlds." name = "dojo" -version = "0.4.1" +version = "0.4.2" [dependencies] dojo_plugin = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.11" } diff --git a/crates/torii/types-test/Scarb.lock b/crates/torii/types-test/Scarb.lock index 4f2d7aa41c..736f84366b 100644 --- a/crates/torii/types-test/Scarb.lock +++ b/crates/torii/types-test/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/crates/torii/types-test/Scarb.toml b/crates/torii/types-test/Scarb.toml index 3bb6831b41..ac5bfa187f 100644 --- a/crates/torii/types-test/Scarb.toml +++ b/crates/torii/types-test/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "types_test" -version = "0.4.1" +version = "0.4.2" [cairo] sierra-replace-ids = true diff --git a/examples/spawn-and-move/Scarb.lock b/examples/spawn-and-move/Scarb.lock index 883898be30..48750706e3 100644 --- a/examples/spawn-and-move/Scarb.lock +++ b/examples/spawn-and-move/Scarb.lock @@ -3,7 +3,7 @@ version = 1 [[package]] name = "dojo" -version = "0.4.1" +version = "0.4.2" dependencies = [ "dojo_plugin", ] diff --git a/examples/spawn-and-move/Scarb.toml b/examples/spawn-and-move/Scarb.toml index 35969ed10f..2383af1a8e 100644 --- a/examples/spawn-and-move/Scarb.toml +++ b/examples/spawn-and-move/Scarb.toml @@ -1,7 +1,7 @@ [package] cairo-version = "2.4.0" name = "dojo_examples" -version = "0.4.1" +version = "0.4.2" # Use the prelude with the less imports as possible # from corelib. edition = "2023_10" From 490dab093672ffc52dd7aa5ee8a9251b6123cfc6 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Thu, 21 Dec 2023 04:33:18 +0800 Subject: [PATCH 38/42] feat(katana-provider): implement a DB provider (#1299) * wip * wip * add test for de/compress contact class * wip * update * update * update test * impl state update provider + tests * update * increase code coverage --- Cargo.lock | 55 +- crates/katana/primitives/src/block.rs | 2 +- crates/katana/primitives/src/state.rs | 2 +- crates/katana/storage/db/Cargo.toml | 7 +- crates/katana/storage/db/benches/codec.rs | 2 +- .../katana/storage/db/src/codecs/postcard.rs | 11 +- crates/katana/storage/db/src/mdbx/cursor.rs | 13 +- crates/katana/storage/db/src/mdbx/mod.rs | 9 +- crates/katana/storage/db/src/models/class.rs | 500 ++++++++++ .../katana/storage/db/src/models/contract.rs | 486 +--------- crates/katana/storage/db/src/models/mod.rs | 1 + .../katana/storage/db/src/models/storage.rs | 103 ++- crates/katana/storage/db/src/tables.rs | 72 +- crates/katana/storage/provider/Cargo.toml | 1 + .../storage/provider/src/providers/db/mod.rs | 864 ++++++++++++++++++ .../provider/src/providers/db/state.rs | 337 +++++++ .../storage/provider/src/providers/mod.rs | 1 + .../provider/src/traits/transaction.rs | 5 + crates/katana/storage/provider/tests/block.rs | 141 ++- crates/katana/storage/provider/tests/class.rs | 23 + .../katana/storage/provider/tests/contract.rs | 25 +- .../katana/storage/provider/tests/fixtures.rs | 101 +- .../katana/storage/provider/tests/storage.rs | 23 + 23 files changed, 2225 insertions(+), 559 deletions(-) create mode 100644 crates/katana/storage/db/src/models/class.rs create mode 100644 crates/katana/storage/provider/src/providers/db/mod.rs create mode 100644 crates/katana/storage/provider/src/providers/db/state.rs diff --git a/Cargo.lock b/Cargo.lock index 6d66fe6cca..10d5c7b210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,15 +827,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bincode" version = "2.0.0-rc.3" @@ -1727,7 +1718,7 @@ version = "0.8.2" source = "git+https://github.com/dojoengine/cairo-rs.git?rev=262b7eb4b11ab165a2a936a5f914e78aa732d4a2#262b7eb4b11ab165a2a936a5f914e78aa732d4a2" dependencies = [ "anyhow", - "bincode 2.0.0-rc.3", + "bincode", "bitvec", "cairo-felt", "generic-array", @@ -1888,9 +1879,9 @@ dependencies = [ [[package]] name = "clap-verbosity-flag" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c90e95e5bd4e8ac34fa6f37c774b0c6f8ed06ea90c79931fd448fcf941a9767" +checksum = "e5fdbb015d790cfb378aca82caf9cc52a38be96a7eecdb92f31b4366a8afc019" dependencies = [ "clap", "log", @@ -2074,9 +2065,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.6" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "const_format" @@ -2969,9 +2960,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adbf0983fe06bd3a5c19c8477a637c2389feb0994eca7a59e3b961054aa7c0a" +checksum = "a3286168faae03a0e583f6fde17c02c8b8bba2dcc2061d0f7817066e5b0af706" dependencies = [ "serde", ] @@ -3344,9 +3335,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" dependencies = [ "indenter", "once_cell", @@ -4286,9 +4277,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.39.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2069adc212cf7f3317ef55f6444abd06c50f28479dbbac5a86acf3b05cbbfe" +checksum = "1ac23ed741583c792f573c028785db683496a6dfcd672ec701ee54ba6a77e1ff" dependencies = [ "gix-actor", "gix-date", @@ -4756,11 +4747,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -5515,7 +5506,6 @@ name = "katana-db" version = "0.4.2" dependencies = [ "anyhow", - "bincode 1.3.3", "blockifier", "cairo-lang-starknet", "cairo-vm", @@ -5583,6 +5573,7 @@ dependencies = [ "rstest", "rstest_reuse", "starknet", + "tempfile", "thiserror", "tokio", "tracing", @@ -9363,18 +9354,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.51" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.51" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -10975,18 +10966,18 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" dependencies = [ "proc-macro2", "quote", diff --git a/crates/katana/primitives/src/block.rs b/crates/katana/primitives/src/block.rs index b451dbc3f1..f5f762f462 100644 --- a/crates/katana/primitives/src/block.rs +++ b/crates/katana/primitives/src/block.rs @@ -115,7 +115,7 @@ pub struct Block { } /// A block with only the transaction hashes. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct BlockWithTxHashes { pub header: Header, pub body: Vec, diff --git a/crates/katana/primitives/src/state.rs b/crates/katana/primitives/src/state.rs index ed95f1a682..65cfa8341a 100644 --- a/crates/katana/primitives/src/state.rs +++ b/crates/katana/primitives/src/state.rs @@ -8,7 +8,7 @@ use crate::contract::{ /// State updates. /// /// Represents all the state updates after performing some executions on a state. -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct StateUpdates { /// A mapping of contract addresses to their updated nonces. diff --git a/crates/katana/storage/db/Cargo.toml b/crates/katana/storage/db/Cargo.toml index 75870a70fd..87de9a249d 100644 --- a/crates/katana/storage/db/Cargo.toml +++ b/crates/katana/storage/db/Cargo.toml @@ -10,7 +10,6 @@ version.workspace = true katana-primitives = { path = "../../primitives" } anyhow.workspace = true -bincode = "1.3.3" page_size = "0.6.0" parking_lot.workspace = true serde.workspace = true @@ -23,7 +22,11 @@ cairo-vm.workspace = true starknet_api.workspace = true # codecs -postcard = { version = "1.0.8", optional = true, default-features = false, features = [ "use-std" ] } +[dependencies.postcard] +default-features = false +features = [ "use-std" ] +optional = true +version = "1.0.8" [dependencies.libmdbx] git = "https://github.com/paradigmxyz/reth.git" diff --git a/crates/katana/storage/db/benches/codec.rs b/crates/katana/storage/db/benches/codec.rs index e74344ec92..183667a021 100644 --- a/crates/katana/storage/db/benches/codec.rs +++ b/crates/katana/storage/db/benches/codec.rs @@ -2,7 +2,7 @@ use blockifier::execution::contract_class::ContractClassV1; use cairo_lang_starknet::casm_contract_class::CasmContractClass; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use katana_db::codecs::{Compress, Decompress}; -use katana_db::models::contract::StoredContractClass; +use katana_db::models::class::StoredContractClass; use katana_primitives::contract::CompiledContractClass; fn compress_contract(contract: CompiledContractClass) -> Vec { diff --git a/crates/katana/storage/db/src/codecs/postcard.rs b/crates/katana/storage/db/src/codecs/postcard.rs index 0564dc3370..66a7ccddc7 100644 --- a/crates/katana/storage/db/src/codecs/postcard.rs +++ b/crates/katana/storage/db/src/codecs/postcard.rs @@ -1,4 +1,4 @@ -use katana_primitives::block::Header; +use katana_primitives::block::{BlockNumber, Header}; use katana_primitives::contract::{ContractAddress, GenericContractInfo, SierraClass}; use katana_primitives::receipt::Receipt; use katana_primitives::transaction::Tx; @@ -7,7 +7,8 @@ use katana_primitives::FieldElement; use super::{Compress, Decompress}; use crate::error::CodecError; use crate::models::block::StoredBlockBodyIndices; -use crate::models::contract::StoredContractClass; +use crate::models::class::StoredContractClass; +use crate::models::contract::ContractInfoChangeList; macro_rules! impl_compress_and_decompress_for_table_values { ($($name:ty),*) => { @@ -21,7 +22,7 @@ macro_rules! impl_compress_and_decompress_for_table_values { impl Decompress for $name { fn decompress>(bytes: B) -> Result { - postcard::from_bytes(bytes.as_ref()).map_err(|e| CodecError::Decode(e.to_string())) + postcard::from_bytes(bytes.as_ref()).map_err(|e| CodecError::Decompress(e.to_string())) } } )* @@ -36,7 +37,9 @@ impl_compress_and_decompress_for_table_values!( SierraClass, FieldElement, ContractAddress, + Vec, StoredContractClass, GenericContractInfo, - StoredBlockBodyIndices + StoredBlockBodyIndices, + ContractInfoChangeList ); diff --git a/crates/katana/storage/db/src/mdbx/cursor.rs b/crates/katana/storage/db/src/mdbx/cursor.rs index 943d92c3df..9cac3876e3 100644 --- a/crates/katana/storage/db/src/mdbx/cursor.rs +++ b/crates/katana/storage/db/src/mdbx/cursor.rs @@ -141,7 +141,7 @@ impl Cursor { &mut self, key: Option, subkey: Option, - ) -> Result, DatabaseError> { + ) -> Result>, DatabaseError> { let start = match (key, subkey) { (Some(key), Some(subkey)) => { // encode key and decode it after. @@ -154,10 +154,17 @@ impl Cursor { (Some(key), None) => { let key: Vec = key.encode().into(); - self.inner + + let Some(start) = self + .inner .set(key.as_ref()) .map_err(DatabaseError::Read)? .map(|val| decoder::((Cow::Owned(key), val))) + else { + return Ok(None); + }; + + Some(start) } (None, Some(subkey)) => { @@ -175,7 +182,7 @@ impl Cursor { (None, None) => self.first().transpose(), }; - Ok(DupWalker::new(self, start)) + Ok(Some(DupWalker::new(self, start))) } } diff --git a/crates/katana/storage/db/src/mdbx/mod.rs b/crates/katana/storage/db/src/mdbx/mod.rs index 76fc9b1cf3..3b31ba0507 100644 --- a/crates/katana/storage/db/src/mdbx/mod.rs +++ b/crates/katana/storage/db/src/mdbx/mod.rs @@ -112,18 +112,17 @@ impl DbEnv { #[cfg(any(test, feature = "test-utils"))] pub mod test_utils { use std::path::Path; - use std::sync::Arc; use super::{DbEnv, DbEnvKind}; const ERROR_DB_CREATION: &str = "Not able to create the mdbx file."; /// Create database for testing - pub fn create_test_db(kind: DbEnvKind) -> Arc { - Arc::new(create_test_db_with_path( + pub fn create_test_db(kind: DbEnvKind) -> DbEnv { + create_test_db_with_path( kind, &tempfile::TempDir::new().expect("Failed to create temp dir.").into_path(), - )) + ) } /// Create database for testing with specified path @@ -392,7 +391,7 @@ mod tests { { let tx = env.tx().expect(ERROR_INIT_TX); let mut cursor = tx.cursor::().unwrap(); - let mut walker = cursor.walk_dup(Some(key), Some(felt!("1"))).unwrap(); + let mut walker = cursor.walk_dup(Some(key), Some(felt!("1"))).unwrap().unwrap(); assert_eq!( (key, value11), diff --git a/crates/katana/storage/db/src/models/class.rs b/crates/katana/storage/db/src/models/class.rs new file mode 100644 index 0000000000..b30ae84ed6 --- /dev/null +++ b/crates/katana/storage/db/src/models/class.rs @@ -0,0 +1,500 @@ +//! Serializable without using custome functions + +use std::collections::HashMap; +use std::sync::Arc; + +use blockifier::execution::contract_class::{ + ContractClass, ContractClassV0, ContractClassV0Inner, ContractClassV1, ContractClassV1Inner, +}; +use cairo_vm::felt::Felt252; +use cairo_vm::hint_processor::hint_processor_definition::HintReference; +use cairo_vm::serde::deserialize_program::{ + ApTracking, Attribute, BuiltinName, FlowTrackingData, HintParams, Identifier, + InstructionLocation, Member, OffsetValue, +}; +use cairo_vm::types::program::{Program, SharedProgramData}; +use cairo_vm::types::relocatable::MaybeRelocatable; +use serde::{Deserialize, Serialize}; +use starknet_api::core::EntryPointSelector; +use starknet_api::deprecated_contract_class::{EntryPoint, EntryPointOffset, EntryPointType}; + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum StoredContractClass { + V0(StoredContractClassV0), + V1(StoredContractClassV1), +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub struct StoredContractClassV0 { + pub program: SerializableProgram, + pub entry_points_by_type: HashMap>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub struct StoredContractClassV1 { + pub program: SerializableProgram, + pub hints: HashMap>, + pub entry_points_by_type: HashMap>, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableEntryPoint { + pub selector: EntryPointSelector, + pub offset: SerializableEntryPointOffset, +} + +impl From for SerializableEntryPoint { + fn from(value: EntryPoint) -> Self { + Self { selector: value.selector, offset: value.offset.into() } + } +} + +impl From for EntryPoint { + fn from(value: SerializableEntryPoint) -> Self { + Self { selector: value.selector, offset: value.offset.into() } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableEntryPointOffset(pub usize); + +impl From for SerializableEntryPointOffset { + fn from(value: EntryPointOffset) -> Self { + Self(value.0) + } +} + +impl From for EntryPointOffset { + fn from(value: SerializableEntryPointOffset) -> Self { + Self(value.0) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableEntryPointV1 { + pub selector: EntryPointSelector, + pub offset: SerializableEntryPointOffset, + pub builtins: Vec, +} + +impl From for blockifier::execution::contract_class::EntryPointV1 { + fn from(value: SerializableEntryPointV1) -> Self { + blockifier::execution::contract_class::EntryPointV1 { + selector: value.selector, + offset: value.offset.into(), + builtins: value.builtins, + } + } +} + +impl From for SerializableEntryPointV1 { + fn from(value: blockifier::execution::contract_class::EntryPointV1) -> Self { + SerializableEntryPointV1 { + selector: value.selector, + offset: value.offset.into(), + builtins: value.builtins, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableProgram { + pub shared_program_data: SerializableSharedProgramData, + pub constants: HashMap, + pub builtins: Vec, +} + +impl From for SerializableProgram { + fn from(value: Program) -> Self { + Self { + shared_program_data: value.shared_program_data.as_ref().clone().into(), + constants: value.constants, + builtins: value.builtins, + } + } +} + +impl From for Program { + fn from(value: SerializableProgram) -> Self { + Self { + shared_program_data: Arc::new(value.shared_program_data.into()), + constants: value.constants, + builtins: value.builtins, + } + } +} + +// Fields of `SerializableProgramData` must not rely on `deserialize_any` +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableSharedProgramData { + pub data: Vec, + pub hints: HashMap>, + pub main: Option, + pub start: Option, + pub end: Option, + pub error_message_attributes: Vec, + pub instruction_locations: Option>, + pub identifiers: HashMap, + pub reference_manager: Vec, +} + +impl From for SerializableSharedProgramData { + fn from(value: SharedProgramData) -> Self { + Self { + data: value.data, + hints: value + .hints + .into_iter() + .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) + .collect(), + main: value.main, + start: value.start, + end: value.end, + error_message_attributes: value + .error_message_attributes + .into_iter() + .map(|a| a.into()) + .collect(), + instruction_locations: value.instruction_locations, + identifiers: value.identifiers.into_iter().map(|(k, v)| (k, v.into())).collect(), + reference_manager: value.reference_manager.into_iter().map(|r| r.into()).collect(), + } + } +} + +impl From for SharedProgramData { + fn from(value: SerializableSharedProgramData) -> Self { + Self { + data: value.data, + hints: value + .hints + .into_iter() + .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) + .collect(), + main: value.main, + start: value.start, + end: value.end, + error_message_attributes: value + .error_message_attributes + .into_iter() + .map(|a| a.into()) + .collect(), + instruction_locations: value.instruction_locations, + identifiers: value.identifiers.into_iter().map(|(k, v)| (k, v.into())).collect(), + reference_manager: value.reference_manager.into_iter().map(|r| r.into()).collect(), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableHintParams { + pub code: String, + pub accessible_scopes: Vec, + pub flow_tracking_data: SerializableFlowTrackingData, +} + +impl From for SerializableHintParams { + fn from(value: HintParams) -> Self { + Self { + code: value.code, + accessible_scopes: value.accessible_scopes, + flow_tracking_data: value.flow_tracking_data.into(), + } + } +} + +impl From for HintParams { + fn from(value: SerializableHintParams) -> Self { + Self { + code: value.code, + accessible_scopes: value.accessible_scopes, + flow_tracking_data: value.flow_tracking_data.into(), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableIdentifier { + pub pc: Option, + pub type_: Option, + pub value: Option, + pub full_name: Option, + pub members: Option>, + pub cairo_type: Option, +} + +impl From for SerializableIdentifier { + fn from(value: Identifier) -> Self { + Self { + pc: value.pc, + type_: value.type_, + value: value.value, + full_name: value.full_name, + members: value.members, + cairo_type: value.cairo_type, + } + } +} + +impl From for Identifier { + fn from(value: SerializableIdentifier) -> Self { + Self { + pc: value.pc, + type_: value.type_, + value: value.value, + full_name: value.full_name, + members: value.members, + cairo_type: value.cairo_type, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableHintReference { + pub offset1: OffsetValue, + pub offset2: OffsetValue, + pub dereference: bool, + pub ap_tracking_data: Option, + pub cairo_type: Option, +} + +impl From for SerializableHintReference { + fn from(value: HintReference) -> Self { + Self { + offset1: value.offset1, + offset2: value.offset2, + dereference: value.dereference, + ap_tracking_data: value.ap_tracking_data, + cairo_type: value.cairo_type, + } + } +} + +impl From for HintReference { + fn from(value: SerializableHintReference) -> Self { + Self { + offset1: value.offset1, + offset2: value.offset2, + dereference: value.dereference, + ap_tracking_data: value.ap_tracking_data, + cairo_type: value.cairo_type, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableAttribute { + pub name: String, + pub start_pc: usize, + pub end_pc: usize, + pub value: String, + pub flow_tracking_data: Option, +} + +impl From for SerializableAttribute { + fn from(value: Attribute) -> Self { + Self { + name: value.name, + start_pc: value.start_pc, + end_pc: value.end_pc, + value: value.value, + flow_tracking_data: value.flow_tracking_data.map(|d| d.into()), + } + } +} + +impl From for Attribute { + fn from(value: SerializableAttribute) -> Self { + Self { + name: value.name, + start_pc: value.start_pc, + end_pc: value.end_pc, + value: value.value, + flow_tracking_data: value.flow_tracking_data.map(|d| d.into()), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SerializableFlowTrackingData { + pub ap_tracking: ApTracking, + pub reference_ids: HashMap, +} + +impl From for SerializableFlowTrackingData { + fn from(value: FlowTrackingData) -> Self { + Self { ap_tracking: value.ap_tracking, reference_ids: value.reference_ids } + } +} + +impl From for FlowTrackingData { + fn from(value: SerializableFlowTrackingData) -> Self { + Self { ap_tracking: value.ap_tracking, reference_ids: value.reference_ids } + } +} + +impl From for ContractClass { + fn from(value: StoredContractClass) -> Self { + match value { + StoredContractClass::V0(v0) => { + ContractClass::V0(ContractClassV0(Arc::new(ContractClassV0Inner { + program: v0.program.into(), + entry_points_by_type: v0 + .entry_points_by_type + .into_iter() + .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) + .collect(), + }))) + } + StoredContractClass::V1(v1) => { + ContractClass::V1(ContractClassV1(Arc::new(ContractClassV1Inner { + hints: v1 + .hints + .clone() + .into_iter() + .map(|(k, v)| (k, serde_json::from_slice(&v).expect("valid hint"))) + .collect(), + program: v1.program.into(), + entry_points_by_type: v1 + .entry_points_by_type + .into_iter() + .map(|(k, v)| { + ( + k, + v.into_iter() + .map(Into::into) + .collect::>(), + ) + }) + .collect::>(), + }))) + } + } + } +} + +impl From for StoredContractClass { + fn from(value: ContractClass) -> Self { + match value { + ContractClass::V0(v0) => { + let entry_points_by_type = v0 + .entry_points_by_type + .clone() + .into_iter() + .map(|(k, v)| (k, v.into_iter().map(SerializableEntryPoint::from).collect())) + .collect(); + + StoredContractClass::V0(StoredContractClassV0 { + program: v0.program.clone().into(), + entry_points_by_type, + }) + } + + ContractClass::V1(v1) => StoredContractClass::V1(StoredContractClassV1 { + program: v1.program.clone().into(), + entry_points_by_type: v1 + .entry_points_by_type + .clone() + .into_iter() + .map(|(k, v)| { + ( + k, + v.into_iter() + .map(Into::into) + .collect::>(), + ) + }) + .collect::>(), + hints: v1 + .hints + .clone() + .into_iter() + .map(|(k, v)| (k, serde_json::to_vec(&v).expect("valid hint"))) + .collect(), + }), + } + } +} + +#[cfg(test)] +mod tests { + use cairo_lang_starknet::casm_contract_class::CasmContractClass; + use katana_primitives::contract::CompiledContractClass; + use starknet_api::hash::StarkFelt; + use starknet_api::stark_felt; + + use super::*; + use crate::codecs::{Compress, Decompress}; + + #[test] + fn serialize_deserialize_legacy_entry_points() { + let non_serde = vec![ + EntryPoint { + offset: EntryPointOffset(0x25f), + selector: EntryPointSelector(stark_felt!( + "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3" + )), + }, + EntryPoint { + offset: EntryPointOffset(0x1b2), + selector: EntryPointSelector(stark_felt!( + "0x29e211664c0b63c79638fbea474206ca74016b3e9a3dc4f9ac300ffd8bdf2cd" + )), + }, + EntryPoint { + offset: EntryPointOffset(0x285), + selector: EntryPointSelector(stark_felt!( + "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895" + )), + }, + ]; + + // convert to serde and back + let serde: Vec = + non_serde.iter().map(|e| e.clone().into()).collect(); + + // convert to json + let json = serde_json::to_vec(&serde).unwrap(); + let serde: Vec = serde_json::from_slice(&json).unwrap(); + + let same_non_serde: Vec = serde.iter().map(|e| e.clone().into()).collect(); + + assert_eq!(non_serde, same_non_serde); + } + + #[test] + fn compress_and_decompress_contract_class() { + let class = + serde_json::from_slice(include_bytes!("../../benches/artifacts/dojo_world_240.json")) + .unwrap(); + + let class = CasmContractClass::from_contract_class(class, true).unwrap(); + let class = CompiledContractClass::V1(ContractClassV1::try_from(class).unwrap()); + + let compressed = StoredContractClass::from(class.clone()).compress(); + let decompressed = ::decompress(compressed).unwrap(); + + let actual_class = CompiledContractClass::from(decompressed); + + assert_eq!(class, actual_class); + } + + #[test] + fn compress_and_decompress_legacy_contract_class() { + let class: ContractClassV0 = serde_json::from_slice(include_bytes!( + "../../../../core/contracts/compiled/account.json" + )) + .unwrap(); + + let class = CompiledContractClass::V0(class); + + let compressed = StoredContractClass::from(class.clone()).compress(); + let decompressed = ::decompress(compressed).unwrap(); + + let actual_class = CompiledContractClass::from(decompressed); + + assert_eq!(class, actual_class); + } +} diff --git a/crates/katana/storage/db/src/models/contract.rs b/crates/katana/storage/db/src/models/contract.rs index 92894bb601..25c9818671 100644 --- a/crates/katana/storage/db/src/models/contract.rs +++ b/crates/katana/storage/db/src/models/contract.rs @@ -1,463 +1,65 @@ -//! Serializable without using custome functions - -use std::collections::HashMap; -use std::sync::Arc; - -use blockifier::execution::contract_class::{ - ContractClass, ContractClassV0, ContractClassV0Inner, ContractClassV1, ContractClassV1Inner, -}; -use cairo_vm::felt::Felt252; -use cairo_vm::hint_processor::hint_processor_definition::HintReference; -use cairo_vm::serde::deserialize_program::{ - ApTracking, Attribute, BuiltinName, FlowTrackingData, HintParams, Identifier, - InstructionLocation, Member, OffsetValue, -}; -use cairo_vm::types::program::{Program, SharedProgramData}; -use cairo_vm::types::relocatable::MaybeRelocatable; +use katana_primitives::block::BlockNumber; +use katana_primitives::contract::{ClassHash, ContractAddress, Nonce}; use serde::{Deserialize, Serialize}; -use starknet_api::core::EntryPointSelector; -use starknet_api::deprecated_contract_class::{EntryPoint, EntryPointOffset, EntryPointType}; - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub enum StoredContractClass { - V0(StoredContractClassV0), - V1(StoredContractClassV1), -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct StoredContractClassV0 { - pub program: SerializableProgram, - pub entry_points_by_type: HashMap>, -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct StoredContractClassV1 { - pub program: SerializableProgram, - pub hints: HashMap>, - pub entry_points_by_type: HashMap>, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableEntryPoint { - pub selector: EntryPointSelector, - pub offset: SerializableEntryPointOffset, -} - -impl From for SerializableEntryPoint { - fn from(value: EntryPoint) -> Self { - Self { selector: value.selector, offset: value.offset.into() } - } -} - -impl From for EntryPoint { - fn from(value: SerializableEntryPoint) -> Self { - Self { selector: value.selector, offset: value.offset.into() } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableEntryPointOffset(pub usize); - -impl From for SerializableEntryPointOffset { - fn from(value: EntryPointOffset) -> Self { - Self(value.0) - } -} - -impl From for EntryPointOffset { - fn from(value: SerializableEntryPointOffset) -> Self { - Self(value.0) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableEntryPointV1 { - pub selector: EntryPointSelector, - pub offset: SerializableEntryPointOffset, - pub builtins: Vec, -} - -impl From for blockifier::execution::contract_class::EntryPointV1 { - fn from(value: SerializableEntryPointV1) -> Self { - blockifier::execution::contract_class::EntryPointV1 { - selector: value.selector, - offset: value.offset.into(), - builtins: value.builtins, - } - } -} - -impl From for SerializableEntryPointV1 { - fn from(value: blockifier::execution::contract_class::EntryPointV1) -> Self { - SerializableEntryPointV1 { - selector: value.selector, - offset: value.offset.into(), - builtins: value.builtins, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableProgram { - pub shared_program_data: SerializableSharedProgramData, - pub constants: HashMap, - pub builtins: Vec, -} - -impl From for SerializableProgram { - fn from(value: Program) -> Self { - Self { - shared_program_data: value.shared_program_data.as_ref().clone().into(), - constants: value.constants, - builtins: value.builtins, - } - } -} - -impl From for Program { - fn from(value: SerializableProgram) -> Self { - Self { - shared_program_data: Arc::new(value.shared_program_data.into()), - constants: value.constants, - builtins: value.builtins, - } - } -} - -// Fields of `SerializableProgramData` must not rely on `deserialize_any` -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableSharedProgramData { - pub data: Vec, - pub hints: HashMap>, - pub main: Option, - pub start: Option, - pub end: Option, - pub error_message_attributes: Vec, - pub instruction_locations: Option>, - pub identifiers: HashMap, - pub reference_manager: Vec, -} - -impl From for SerializableSharedProgramData { - fn from(value: SharedProgramData) -> Self { - Self { - data: value.data, - hints: value - .hints - .into_iter() - .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) - .collect(), - main: value.main, - start: value.start, - end: value.end, - error_message_attributes: value - .error_message_attributes - .into_iter() - .map(|a| a.into()) - .collect(), - instruction_locations: value.instruction_locations, - identifiers: value.identifiers.into_iter().map(|(k, v)| (k, v.into())).collect(), - reference_manager: value.reference_manager.into_iter().map(|r| r.into()).collect(), - } - } -} - -impl From for SharedProgramData { - fn from(value: SerializableSharedProgramData) -> Self { - Self { - data: value.data, - hints: value - .hints - .into_iter() - .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) - .collect(), - main: value.main, - start: value.start, - end: value.end, - error_message_attributes: value - .error_message_attributes - .into_iter() - .map(|a| a.into()) - .collect(), - instruction_locations: value.instruction_locations, - identifiers: value.identifiers.into_iter().map(|(k, v)| (k, v.into())).collect(), - reference_manager: value.reference_manager.into_iter().map(|r| r.into()).collect(), - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableHintParams { - pub code: String, - pub accessible_scopes: Vec, - pub flow_tracking_data: SerializableFlowTrackingData, -} - -impl From for SerializableHintParams { - fn from(value: HintParams) -> Self { - Self { - code: value.code, - accessible_scopes: value.accessible_scopes, - flow_tracking_data: value.flow_tracking_data.into(), - } - } -} - -impl From for HintParams { - fn from(value: SerializableHintParams) -> Self { - Self { - code: value.code, - accessible_scopes: value.accessible_scopes, - flow_tracking_data: value.flow_tracking_data.into(), - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableIdentifier { - pub pc: Option, - pub type_: Option, - pub value: Option, - pub full_name: Option, - pub members: Option>, - pub cairo_type: Option, -} - -impl From for SerializableIdentifier { - fn from(value: Identifier) -> Self { - Self { - pc: value.pc, - type_: value.type_, - value: value.value, - full_name: value.full_name, - members: value.members, - cairo_type: value.cairo_type, - } - } -} - -impl From for Identifier { - fn from(value: SerializableIdentifier) -> Self { - Self { - pc: value.pc, - type_: value.type_, - value: value.value, - full_name: value.full_name, - members: value.members, - cairo_type: value.cairo_type, - } - } -} -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableHintReference { - pub offset1: OffsetValue, - pub offset2: OffsetValue, - pub dereference: bool, - pub ap_tracking_data: Option, - pub cairo_type: Option, -} +use crate::codecs::{Compress, Decode, Decompress, Encode}; -impl From for SerializableHintReference { - fn from(value: HintReference) -> Self { - Self { - offset1: value.offset1, - offset2: value.offset2, - dereference: value.dereference, - ap_tracking_data: value.ap_tracking_data, - cairo_type: value.cairo_type, - } - } -} +pub type BlockList = Vec; -impl From for HintReference { - fn from(value: SerializableHintReference) -> Self { - Self { - offset1: value.offset1, - offset2: value.offset2, - dereference: value.dereference, - ap_tracking_data: value.ap_tracking_data, - cairo_type: value.cairo_type, - } - } +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ContractInfoChangeList { + pub class_change_list: BlockList, + pub nonce_change_list: BlockList, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableAttribute { - pub name: String, - pub start_pc: usize, - pub end_pc: usize, - pub value: String, - pub flow_tracking_data: Option, +#[derive(Debug)] +pub struct ContractClassChange { + pub contract_address: ContractAddress, + /// The updated class hash of `contract_address`. + pub class_hash: ClassHash, } -impl From for SerializableAttribute { - fn from(value: Attribute) -> Self { - Self { - name: value.name, - start_pc: value.start_pc, - end_pc: value.end_pc, - value: value.value, - flow_tracking_data: value.flow_tracking_data.map(|d| d.into()), - } +impl Compress for ContractClassChange { + type Compressed = Vec; + fn compress(self) -> Self::Compressed { + let mut buf = Vec::new(); + buf.extend_from_slice(self.contract_address.encode().as_ref()); + buf.extend_from_slice(self.class_hash.compress().as_ref()); + buf } } -impl From for Attribute { - fn from(value: SerializableAttribute) -> Self { - Self { - name: value.name, - start_pc: value.start_pc, - end_pc: value.end_pc, - value: value.value, - flow_tracking_data: value.flow_tracking_data.map(|d| d.into()), - } +impl Decompress for ContractClassChange { + fn decompress>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + let contract_address = ContractAddress::decode(&bytes[0..32])?; + let class_hash = ClassHash::decompress(&bytes[32..])?; + Ok(Self { contract_address, class_hash }) } } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SerializableFlowTrackingData { - pub ap_tracking: ApTracking, - pub reference_ids: HashMap, +#[derive(Debug)] +pub struct ContractNonceChange { + pub contract_address: ContractAddress, + /// The updated nonce value of `contract_address`. + pub nonce: Nonce, } -impl From for SerializableFlowTrackingData { - fn from(value: FlowTrackingData) -> Self { - Self { ap_tracking: value.ap_tracking, reference_ids: value.reference_ids } +impl Compress for ContractNonceChange { + type Compressed = Vec; + fn compress(self) -> Self::Compressed { + let mut buf = Vec::new(); + buf.extend_from_slice(&self.contract_address.encode()); + buf.extend_from_slice(&self.nonce.compress()); + buf } } -impl From for FlowTrackingData { - fn from(value: SerializableFlowTrackingData) -> Self { - Self { ap_tracking: value.ap_tracking, reference_ids: value.reference_ids } - } -} - -impl From for ContractClass { - fn from(value: StoredContractClass) -> Self { - match value { - StoredContractClass::V0(v0) => { - ContractClass::V0(ContractClassV0(Arc::new(ContractClassV0Inner { - program: v0.program.into(), - entry_points_by_type: v0 - .entry_points_by_type - .into_iter() - .map(|(k, v)| (k, v.into_iter().map(|h| h.into()).collect())) - .collect(), - }))) - } - StoredContractClass::V1(v1) => { - ContractClass::V1(ContractClassV1(Arc::new(ContractClassV1Inner { - hints: v1 - .hints - .clone() - .into_iter() - .map(|(k, v)| (k, serde_json::from_slice(&v).expect("valid hint"))) - .collect(), - program: v1.program.into(), - entry_points_by_type: v1 - .entry_points_by_type - .into_iter() - .map(|(k, v)| { - ( - k, - v.into_iter() - .map(Into::into) - .collect::>(), - ) - }) - .collect::>(), - }))) - } - } - } -} - -impl From for StoredContractClass { - fn from(value: ContractClass) -> Self { - match value { - ContractClass::V0(v0) => { - let entry_points_by_type = v0 - .entry_points_by_type - .clone() - .into_iter() - .map(|(k, v)| (k, v.into_iter().map(SerializableEntryPoint::from).collect())) - .collect(); - - StoredContractClass::V0(StoredContractClassV0 { - program: v0.program.clone().into(), - entry_points_by_type, - }) - } - - ContractClass::V1(v1) => StoredContractClass::V1(StoredContractClassV1 { - program: v1.program.clone().into(), - entry_points_by_type: v1 - .entry_points_by_type - .clone() - .into_iter() - .map(|(k, v)| { - ( - k, - v.into_iter() - .map(Into::into) - .collect::>(), - ) - }) - .collect::>(), - hints: v1 - .hints - .clone() - .into_iter() - .map(|(k, v)| (k, serde_json::to_vec(&v).expect("valid hint"))) - .collect(), - }), - } - } -} - -#[cfg(test)] -mod tests { - use starknet_api::hash::StarkFelt; - use starknet_api::stark_felt; - - use super::*; - - #[test] - fn serialize_deserialize_legacy_entry_points() { - let non_serde = vec![ - EntryPoint { - offset: EntryPointOffset(0x25f), - selector: EntryPointSelector(stark_felt!( - "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3" - )), - }, - EntryPoint { - offset: EntryPointOffset(0x1b2), - selector: EntryPointSelector(stark_felt!( - "0x29e211664c0b63c79638fbea474206ca74016b3e9a3dc4f9ac300ffd8bdf2cd" - )), - }, - EntryPoint { - offset: EntryPointOffset(0x285), - selector: EntryPointSelector(stark_felt!( - "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895" - )), - }, - ]; - - // convert to serde and back - let serde: Vec = - non_serde.iter().map(|e| e.clone().into()).collect(); - - // convert to json - let json = serde_json::to_vec(&serde).unwrap(); - let serde: Vec = serde_json::from_slice(&json).unwrap(); - - let same_non_serde: Vec = serde.iter().map(|e| e.clone().into()).collect(); - - assert_eq!(non_serde, same_non_serde); +impl Decompress for ContractNonceChange { + fn decompress>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + let contract_address = ContractAddress::decode(&bytes[0..32])?; + let nonce = Nonce::decompress(&bytes[32..])?; + Ok(Self { contract_address, nonce }) } } diff --git a/crates/katana/storage/db/src/models/mod.rs b/crates/katana/storage/db/src/models/mod.rs index 656ed6c7a2..66150ed28b 100644 --- a/crates/katana/storage/db/src/models/mod.rs +++ b/crates/katana/storage/db/src/models/mod.rs @@ -1,3 +1,4 @@ pub mod block; +pub mod class; pub mod contract; pub mod storage; diff --git a/crates/katana/storage/db/src/models/storage.rs b/crates/katana/storage/db/src/models/storage.rs index c4350421b9..6b1c3da54d 100644 --- a/crates/katana/storage/db/src/models/storage.rs +++ b/crates/katana/storage/db/src/models/storage.rs @@ -1,6 +1,7 @@ -use katana_primitives::contract::{StorageKey, StorageValue}; +use katana_primitives::block::BlockNumber; +use katana_primitives::contract::{ContractAddress, StorageKey, StorageValue}; -use crate::codecs::{Compress, Decompress}; +use crate::codecs::{Compress, Decode, Decompress, Encode}; use crate::error::CodecError; /// Represents a contract storage entry. @@ -33,3 +34,101 @@ impl Decompress for StorageEntry { Ok(Self { key, value }) } } + +#[derive(Debug)] +pub struct StorageEntryChangeList { + pub key: StorageKey, + pub block_list: Vec, +} + +impl Compress for StorageEntryChangeList { + type Compressed = Vec; + fn compress(self) -> Self::Compressed { + let mut buf = Vec::new(); + buf.extend_from_slice(&self.key.encode()); + buf.extend_from_slice(&self.block_list.compress()); + buf + } +} + +impl Decompress for StorageEntryChangeList { + fn decompress>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + let key = StorageKey::decode(&bytes[0..32])?; + let blocks = Vec::::decompress(&bytes[32..])?; + Ok(Self { key, block_list: blocks }) + } +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct ContractStorageKey { + pub contract_address: ContractAddress, + pub key: StorageKey, +} + +impl Encode for ContractStorageKey { + type Encoded = [u8; 64]; + fn encode(self) -> Self::Encoded { + let mut buf = [0u8; 64]; + buf[0..32].copy_from_slice(&self.contract_address.encode()); + buf[32..64].copy_from_slice(&self.key.encode()); + buf + } +} + +impl Decode for ContractStorageKey { + fn decode>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + let contract_address = ContractAddress::decode(&bytes[0..32])?; + let key = StorageKey::decode(&bytes[32..])?; + Ok(Self { contract_address, key }) + } +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct ContractStorageEntry { + pub key: ContractStorageKey, + pub value: StorageValue, +} + +impl Compress for ContractStorageEntry { + type Compressed = Vec; + fn compress(self) -> Self::Compressed { + let mut buf = Vec::with_capacity(64); + buf.extend_from_slice(self.key.encode().as_ref()); + buf.extend_from_slice(self.value.compress().as_ref()); + buf + } +} + +impl Decompress for ContractStorageEntry { + fn decompress>(bytes: B) -> Result { + let bytes = bytes.as_ref(); + let key = ContractStorageKey::decode(&bytes[0..64])?; + let value = StorageValue::decompress(&bytes[64..])?; + Ok(Self { key, value }) + } +} + +#[cfg(test)] +mod tests { + use starknet::macros::felt; + + use crate::codecs::{Compress, Decompress}; + + #[test] + fn compress_and_decompress_account_entry() { + let account_storage_entry = super::ContractStorageEntry { + key: super::ContractStorageKey { + contract_address: felt!("0x1234").into(), + key: felt!("0x111"), + }, + value: felt!("0x99"), + }; + + let compressed = account_storage_entry.clone().compress(); + let actual_value = super::ContractStorageEntry::decompress(compressed).unwrap(); + + assert_eq!(account_storage_entry, actual_value); + } +} diff --git a/crates/katana/storage/db/src/tables.rs b/crates/katana/storage/db/src/tables.rs index 6ec43b55c8..df6facb002 100644 --- a/crates/katana/storage/db/src/tables.rs +++ b/crates/katana/storage/db/src/tables.rs @@ -7,8 +7,11 @@ use katana_primitives::transaction::{Tx, TxHash, TxNumber}; use crate::codecs::{Compress, Decode, Decompress, Encode}; use crate::models::block::StoredBlockBodyIndices; -use crate::models::contract::StoredContractClass; -use crate::models::storage::StorageEntry; +use crate::models::class::StoredContractClass; +use crate::models::contract::{ContractClassChange, ContractInfoChangeList, ContractNonceChange}; +use crate::models::storage::{ + ContractStorageEntry, ContractStorageKey, StorageEntry, StorageEntryChangeList, +}; pub trait Key: Encode + Decode + Clone + std::fmt::Debug {} pub trait Value: Compress + Decompress + std::fmt::Debug {} @@ -43,7 +46,7 @@ pub enum TableType { DupSort, } -pub const NUM_TABLES: usize = 17; +pub const NUM_TABLES: usize = 22; /// Macro to declare `libmdbx` tables. #[macro_export] @@ -158,9 +161,14 @@ define_tables_enum! {[ (CompiledContractClasses, TableType::Table), (SierraClasses, TableType::Table), (ContractInfo, TableType::Table), - (ContractDeployments, TableType::DupSort), + (ContractStorage, TableType::DupSort), + (ClassDeclarationBlock, TableType::Table), (ClassDeclarations, TableType::DupSort), - (ContractStorage, TableType::DupSort) + (ContractInfoChangeSet, TableType::Table), + (NonceChanges, TableType::DupSort), + (ContractClassChanges, TableType::DupSort), + (StorageChanges, TableType::DupSort), + (StorageChangeSet, TableType::DupSort) ]} tables! { @@ -195,8 +203,58 @@ tables! { ContractInfo: (ContractAddress) => GenericContractInfo, /// Store contract storage ContractStorage: (ContractAddress, StorageKey) => StorageEntry, + + + /// Stores the block number where the class hash was declared. + ClassDeclarationBlock: (ClassHash) => BlockNumber, /// Stores the list of class hashes according to the block number it was declared in. ClassDeclarations: (BlockNumber, ClassHash) => ClassHash, - /// Store the list of contracts deployed in a block according to its block number. - ContractDeployments: (BlockNumber, ContractAddress) => ContractAddress + + /// Generic contract info change set. + /// + /// Stores the list of blocks where the contract info (nonce / class hash) has changed. + ContractInfoChangeSet: (ContractAddress) => ContractInfoChangeList, + + /// Contract nonce changes by block. + NonceChanges: (BlockNumber, ContractAddress) => ContractNonceChange, + /// Contract class hash changes by block. + ContractClassChanges: (BlockNumber, ContractAddress) => ContractClassChange, + + /// storage change set + StorageChangeSet: (ContractAddress, StorageKey) => StorageEntryChangeList, + /// Account storage change set + StorageChanges: (BlockNumber, ContractStorageKey) => ContractStorageEntry + +} + +#[cfg(test)] +mod tests { + #[test] + fn test_tables() { + use super::*; + + assert_eq!(Tables::ALL.len(), NUM_TABLES); + assert_eq!(Tables::ALL[0].name(), Headers::NAME); + assert_eq!(Tables::ALL[1].name(), BlockHashes::NAME); + assert_eq!(Tables::ALL[2].name(), BlockNumbers::NAME); + assert_eq!(Tables::ALL[3].name(), BlockBodyIndices::NAME); + assert_eq!(Tables::ALL[4].name(), BlockStatusses::NAME); + assert_eq!(Tables::ALL[5].name(), TxNumbers::NAME); + assert_eq!(Tables::ALL[6].name(), TxBlocks::NAME); + assert_eq!(Tables::ALL[7].name(), TxHashes::NAME); + assert_eq!(Tables::ALL[8].name(), Transactions::NAME); + assert_eq!(Tables::ALL[9].name(), Receipts::NAME); + assert_eq!(Tables::ALL[10].name(), CompiledClassHashes::NAME); + assert_eq!(Tables::ALL[11].name(), CompiledContractClasses::NAME); + assert_eq!(Tables::ALL[12].name(), SierraClasses::NAME); + assert_eq!(Tables::ALL[13].name(), ContractInfo::NAME); + assert_eq!(Tables::ALL[14].name(), ContractStorage::NAME); + assert_eq!(Tables::ALL[15].name(), ClassDeclarationBlock::NAME); + assert_eq!(Tables::ALL[16].name(), ClassDeclarations::NAME); + assert_eq!(Tables::ALL[17].name(), ContractInfoChangeSet::NAME); + assert_eq!(Tables::ALL[18].name(), NonceChanges::NAME); + assert_eq!(Tables::ALL[19].name(), ContractClassChanges::NAME); + assert_eq!(Tables::ALL[20].name(), StorageChanges::NAME); + assert_eq!(Tables::ALL[21].name(), StorageChangeSet::NAME); + } } diff --git a/crates/katana/storage/provider/Cargo.toml b/crates/katana/storage/provider/Cargo.toml index af9d492a08..5b4e4145da 100644 --- a/crates/katana/storage/provider/Cargo.toml +++ b/crates/katana/storage/provider/Cargo.toml @@ -33,4 +33,5 @@ rand = "0.8.5" rstest = "0.18.2" rstest_reuse = "0.6.0" starknet.workspace = true +tempfile = "3.8.1" url.workspace = true diff --git a/crates/katana/storage/provider/src/providers/db/mod.rs b/crates/katana/storage/provider/src/providers/db/mod.rs new file mode 100644 index 0000000000..14568e8bd2 --- /dev/null +++ b/crates/katana/storage/provider/src/providers/db/mod.rs @@ -0,0 +1,864 @@ +pub mod state; + +use std::collections::HashMap; +use std::fmt::Debug; +use std::ops::{Range, RangeInclusive}; + +use anyhow::Result; +use katana_db::error::DatabaseError; +use katana_db::mdbx::{self, DbEnv}; +use katana_db::models::block::StoredBlockBodyIndices; +use katana_db::models::contract::{ + ContractClassChange, ContractInfoChangeList, ContractNonceChange, +}; +use katana_db::models::storage::{ + ContractStorageEntry, ContractStorageKey, StorageEntry, StorageEntryChangeList, +}; +use katana_db::tables::{ + BlockBodyIndices, BlockHashes, BlockNumbers, BlockStatusses, ClassDeclarationBlock, + ClassDeclarations, CompiledClassHashes, CompiledContractClasses, ContractClassChanges, + ContractInfo, ContractInfoChangeSet, ContractStorage, DupSort, Headers, NonceChanges, Receipts, + SierraClasses, StorageChangeSet, StorageChanges, Table, Transactions, TxBlocks, TxHashes, + TxNumbers, +}; +use katana_db::utils::KeyValue; +use katana_primitives::block::{ + Block, BlockHash, BlockHashOrNumber, BlockNumber, BlockWithTxHashes, FinalityStatus, Header, + SealedBlockWithStatus, +}; +use katana_primitives::contract::{ + ClassHash, CompiledClassHash, ContractAddress, GenericContractInfo, Nonce, StorageKey, + StorageValue, +}; +use katana_primitives::receipt::Receipt; +use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; +use katana_primitives::transaction::{TxHash, TxNumber, TxWithHash}; +use katana_primitives::FieldElement; + +use crate::traits::block::{ + BlockHashProvider, BlockNumberProvider, BlockProvider, BlockStatusProvider, BlockWriter, + HeaderProvider, +}; +use crate::traits::state::{StateFactoryProvider, StateProvider, StateRootProvider}; +use crate::traits::state_update::StateUpdateProvider; +use crate::traits::transaction::{ + ReceiptProvider, TransactionProvider, TransactionStatusProvider, TransactionsProviderExt, +}; + +/// A provider implementation that uses a database as a backend. +#[derive(Debug)] +pub struct DbProvider(DbEnv); + +impl DbProvider { + /// Creates a new [`DbProvider`] from the given [`DbEnv`]. + pub fn new(db: DbEnv) -> Self { + Self(db) + } +} + +impl StateFactoryProvider for DbProvider { + fn latest(&self) -> Result> { + Ok(Box::new(self::state::LatestStateProvider::new(self.0.tx()?))) + } + + fn historical(&self, block_id: BlockHashOrNumber) -> Result>> { + let block_number = match block_id { + BlockHashOrNumber::Num(num) => { + let latest_num = self.latest_number()?; + + match num.cmp(&latest_num) { + std::cmp::Ordering::Less => Some(num), + std::cmp::Ordering::Greater => return Ok(None), + std::cmp::Ordering::Equal => return self.latest().map(Some), + } + } + + BlockHashOrNumber::Hash(hash) => self.block_number_by_hash(hash)?, + }; + + let Some(num) = block_number else { return Ok(None) }; + + Ok(Some(Box::new(self::state::HistoricalStateProvider::new(self.0.tx()?, num)))) + } +} + +impl BlockNumberProvider for DbProvider { + fn block_number_by_hash(&self, hash: BlockHash) -> Result> { + let db_tx = self.0.tx()?; + let block_num = db_tx.get::(hash)?; + db_tx.commit()?; + Ok(block_num) + } + + fn latest_number(&self) -> Result { + let db_tx = self.0.tx()?; + let total_blocks = db_tx.entries::()? as u64; + db_tx.commit()?; + Ok(if total_blocks == 0 { 0 } else { total_blocks - 1 }) + } +} + +impl BlockHashProvider for DbProvider { + fn latest_hash(&self) -> Result { + let db_tx = self.0.tx()?; + let total_blocks = db_tx.entries::()? as u64; + let latest_block = if total_blocks == 0 { 0 } else { total_blocks - 1 }; + let latest_hash = db_tx.get::(latest_block)?.expect("block hash should exist"); + db_tx.commit()?; + Ok(latest_hash) + } + + fn block_hash_by_num(&self, num: BlockNumber) -> Result> { + let db_tx = self.0.tx()?; + let block_hash = db_tx.get::(num)?; + db_tx.commit()?; + Ok(block_hash) + } +} + +impl HeaderProvider for DbProvider { + fn header(&self, id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + let num = match id { + BlockHashOrNumber::Num(num) => Some(num), + BlockHashOrNumber::Hash(hash) => db_tx.get::(hash)?, + }; + + if let Some(num) = num { + let header = db_tx.get::(num)?.expect("should exist"); + db_tx.commit()?; + Ok(Some(header)) + } else { + Ok(None) + } + } +} + +impl BlockProvider for DbProvider { + fn block_body_indices(&self, id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + let block_num = match id { + BlockHashOrNumber::Num(num) => Some(num), + BlockHashOrNumber::Hash(hash) => db_tx.get::(hash)?, + }; + + if let Some(num) = block_num { + let indices = db_tx.get::(num)?; + db_tx.commit()?; + Ok(indices) + } else { + Ok(None) + } + } + + fn block(&self, id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + if let Some(header) = self.header(id)? { + let body = self.transactions_by_block(id)?.expect("should exist"); + db_tx.commit()?; + Ok(Some(Block { header, body })) + } else { + Ok(None) + } + } + + fn block_with_tx_hashes(&self, id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + let block_num = match id { + BlockHashOrNumber::Num(num) => Some(num), + BlockHashOrNumber::Hash(hash) => db_tx.get::(hash)?, + }; + + let Some(block_num) = block_num else { return Ok(None) }; + + if let Some(header) = db_tx.get::(block_num)? { + let body_indices = db_tx.get::(block_num)?.expect("should exist"); + let body = self.transaction_hashes_in_range(Range::from(body_indices))?; + let block = BlockWithTxHashes { header, body }; + + db_tx.commit()?; + + Ok(Some(block)) + } else { + Ok(None) + } + } + + fn blocks_in_range(&self, range: RangeInclusive) -> Result> { + let db_tx = self.0.tx()?; + + let total = range.end() - range.start() + 1; + let mut blocks = Vec::with_capacity(total as usize); + + for num in range { + if let Some(header) = db_tx.get::(num)? { + let body_indices = db_tx.get::(num)?.expect("should exist"); + let body = self.transaction_in_range(Range::from(body_indices))?; + blocks.push(Block { header, body }) + } + } + + db_tx.commit()?; + Ok(blocks) + } +} + +impl BlockStatusProvider for DbProvider { + fn block_status(&self, id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + let block_num = match id { + BlockHashOrNumber::Num(num) => Some(num), + BlockHashOrNumber::Hash(hash) => self.block_number_by_hash(hash)?, + }; + + if let Some(block_num) = block_num { + let status = db_tx.get::(block_num)?.expect("should exist"); + db_tx.commit()?; + Ok(Some(status)) + } else { + Ok(None) + } + } +} + +impl StateRootProvider for DbProvider { + fn state_root(&self, block_id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + + let block_num = match block_id { + BlockHashOrNumber::Num(num) => Some(num), + BlockHashOrNumber::Hash(hash) => db_tx.get::(hash)?, + }; + + if let Some(block_num) = block_num { + let header = db_tx.get::(block_num)?; + db_tx.commit()?; + Ok(header.map(|h| h.state_root)) + } else { + Ok(None) + } + } +} + +impl StateUpdateProvider for DbProvider { + fn state_update(&self, block_id: BlockHashOrNumber) -> Result> { + // A helper function that iterates over all entries in a dupsort table and collects the + // results into `V`. If `key` is not found, `V::default()` is returned. + fn dup_entries( + db_tx: &mdbx::tx::TxRO, + key: ::Key, + f: impl FnMut(Result, DatabaseError>) -> Result, + ) -> Result + where + Tb: DupSort + Debug, + V: FromIterator + Default, + { + Ok(db_tx + .cursor::()? + .walk_dup(Some(key), None)? + .map(|walker| walker.map(f).collect::>()) + .transpose()? + .unwrap_or_default()) + } + + let db_tx = self.0.tx()?; + let block_num = self.block_number_by_id(block_id)?; + + if let Some(block_num) = block_num { + let nonce_updates = dup_entries::, _>( + &db_tx, + block_num, + |entry| { + let (_, ContractNonceChange { contract_address, nonce }) = entry?; + Ok((contract_address, nonce)) + }, + )?; + + let contract_updates = dup_entries::< + ContractClassChanges, + HashMap, + _, + >(&db_tx, block_num, |entry| { + let (_, ContractClassChange { contract_address, class_hash }) = entry?; + Ok((contract_address, class_hash)) + })?; + + let declared_classes = dup_entries::< + ClassDeclarations, + HashMap, + _, + >(&db_tx, block_num, |entry| { + let (_, class_hash) = entry?; + let compiled_hash = + db_tx.get::(class_hash)?.expect("qed; must exist"); + Ok((class_hash, compiled_hash)) + })?; + + let storage_updates = { + let entries = dup_entries::< + StorageChanges, + Vec<(ContractAddress, (StorageKey, StorageValue))>, + _, + >(&db_tx, block_num, |entry| { + let (_, ContractStorageEntry { key, value }) = entry?; + Ok::<_, DatabaseError>((key.contract_address, (key.key, value))) + })?; + + let mut map: HashMap<_, HashMap> = HashMap::new(); + + entries.into_iter().for_each(|(addr, (key, value))| { + map.entry(addr).or_default().insert(key, value); + }); + + map + }; + + db_tx.commit()?; + Ok(Some(StateUpdates { + nonce_updates, + storage_updates, + contract_updates, + declared_classes, + })) + } else { + Ok(None) + } + } +} + +impl TransactionProvider for DbProvider { + fn transaction_by_hash(&self, hash: TxHash) -> Result> { + let db_tx = self.0.tx()?; + + if let Some(num) = db_tx.get::(hash)? { + let transaction = db_tx.get::(num)?.expect("transaction should exist"); + let transaction = TxWithHash { hash, transaction }; + db_tx.commit()?; + + Ok(Some(transaction)) + } else { + Ok(None) + } + } + + fn transactions_by_block( + &self, + block_id: BlockHashOrNumber, + ) -> Result>> { + if let Some(indices) = self.block_body_indices(block_id)? { + Ok(Some(self.transaction_in_range(Range::from(indices))?)) + } else { + Ok(None) + } + } + + fn transaction_in_range(&self, range: Range) -> Result> { + let db_tx = self.0.tx()?; + + let total = range.end - range.start; + let mut transactions = Vec::with_capacity(total as usize); + + for i in range { + if let Some(transaction) = db_tx.get::(i)? { + let hash = db_tx.get::(i)?.expect("should exist"); + transactions.push(TxWithHash { hash, transaction }); + }; + } + + db_tx.commit()?; + Ok(transactions) + } + + fn transaction_block_num_and_hash( + &self, + hash: TxHash, + ) -> Result> { + let db_tx = self.0.tx()?; + if let Some(num) = db_tx.get::(hash)? { + let block_num = db_tx.get::(num)?.expect("should exist"); + let block_hash = db_tx.get::(block_num)?.expect("should exist"); + db_tx.commit()?; + Ok(Some((block_num, block_hash))) + } else { + Ok(None) + } + } + + fn transaction_by_block_and_idx( + &self, + block_id: BlockHashOrNumber, + idx: u64, + ) -> Result> { + let db_tx = self.0.tx()?; + + match self.block_body_indices(block_id)? { + // make sure the requested idx is within the range of the block tx count + Some(indices) if idx < indices.tx_count => { + let num = indices.tx_offset + idx; + let hash = db_tx.get::(num)?.expect("should exist"); + let transaction = db_tx.get::(num)?.expect("should exist"); + let transaction = TxWithHash { hash, transaction }; + db_tx.commit()?; + Ok(Some(transaction)) + } + + _ => Ok(None), + } + } + + fn transaction_count_by_block(&self, block_id: BlockHashOrNumber) -> Result> { + let db_tx = self.0.tx()?; + if let Some(indices) = self.block_body_indices(block_id)? { + db_tx.commit()?; + Ok(Some(indices.tx_count)) + } else { + Ok(None) + } + } +} + +impl TransactionsProviderExt for DbProvider { + fn transaction_hashes_in_range(&self, range: Range) -> Result> { + let db_tx = self.0.tx()?; + + let total = range.end - range.start; + let mut hashes = Vec::with_capacity(total as usize); + + for i in range { + if let Some(hash) = db_tx.get::(i)? { + hashes.push(hash); + } + } + + db_tx.commit()?; + Ok(hashes) + } +} + +impl TransactionStatusProvider for DbProvider { + fn transaction_status(&self, hash: TxHash) -> Result> { + let db_tx = self.0.tx()?; + if let Some(tx_num) = db_tx.get::(hash)? { + let block_num = db_tx.get::(tx_num)?.expect("should exist"); + let status = db_tx.get::(block_num)?.expect("should exist"); + db_tx.commit()?; + Ok(Some(status)) + } else { + Ok(None) + } + } +} + +impl ReceiptProvider for DbProvider { + fn receipt_by_hash(&self, hash: TxHash) -> Result> { + let db_tx = self.0.tx()?; + if let Some(num) = db_tx.get::(hash)? { + let receipt = db_tx.get::(num)?.expect("should exist"); + db_tx.commit()?; + Ok(Some(receipt)) + } else { + Ok(None) + } + } + + fn receipts_by_block(&self, block_id: BlockHashOrNumber) -> Result>> { + if let Some(indices) = self.block_body_indices(block_id)? { + let db_tx = self.0.tx()?; + let mut receipts = Vec::with_capacity(indices.tx_count as usize); + + let range = indices.tx_offset..indices.tx_offset + indices.tx_count; + for i in range { + if let Some(receipt) = db_tx.get::(i)? { + receipts.push(receipt); + } + } + + db_tx.commit()?; + Ok(Some(receipts)) + } else { + Ok(None) + } + } +} + +impl BlockWriter for DbProvider { + fn insert_block_with_states_and_receipts( + &self, + block: SealedBlockWithStatus, + states: StateUpdatesWithDeclaredClasses, + receipts: Vec, + ) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + let block_hash = block.block.header.hash; + let block_number = block.block.header.header.number; + + let block_header = block.block.header.header; + let transactions = block.block.body; + + let tx_count = transactions.len() as u64; + let tx_offset = db_tx.entries::()? as u64; + let block_body_indices = StoredBlockBodyIndices { tx_offset, tx_count }; + + db_tx.put::(block_number, block_hash)?; + db_tx.put::(block_hash, block_number)?; + db_tx.put::(block_number, block.status)?; + + db_tx.put::(block_number, block_header)?; + db_tx.put::(block_number, block_body_indices)?; + + for (i, (transaction, receipt)) in transactions.into_iter().zip(receipts).enumerate() { + let tx_number = tx_offset + i as u64; + let tx_hash = transaction.hash; + + db_tx.put::(tx_number, tx_hash)?; + db_tx.put::(tx_hash, tx_number)?; + db_tx.put::(tx_number, block_number)?; + db_tx.put::(tx_number, transaction.transaction)?; + db_tx.put::(tx_number, receipt)?; + } + + // insert classes + + for (class_hash, compiled_hash) in states.state_updates.declared_classes { + db_tx.put::(class_hash, compiled_hash)?; + + db_tx.put::(class_hash, block_number)?; + db_tx.put::(block_number, class_hash)? + } + + for (hash, compiled_class) in states.declared_compiled_classes { + db_tx.put::(hash, compiled_class.into())?; + } + + for (class_hash, sierra_class) in states.declared_sierra_classes { + db_tx.put::(class_hash, sierra_class)?; + } + + // insert storage changes + { + let mut storage_cursor = db_tx.cursor::()?; + for (addr, entries) in states.state_updates.storage_updates { + let entries = + entries.into_iter().map(|(key, value)| StorageEntry { key, value }); + + for entry in entries { + match storage_cursor.seek_by_key_subkey(addr, entry.key)? { + Some(current) if current.key == entry.key => { + storage_cursor.delete_current()?; + } + + _ => {} + } + + let mut change_set_cursor = db_tx.cursor::()?; + let new_block_list = + match change_set_cursor.seek_by_key_subkey(addr, entry.key)? { + Some(StorageEntryChangeList { mut block_list, key }) + if key == entry.key => + { + change_set_cursor.delete_current()?; + + block_list.push(block_number); + block_list.sort(); + block_list + } + + _ => { + vec![block_number] + } + }; + + change_set_cursor.upsert( + addr, + StorageEntryChangeList { key: entry.key, block_list: new_block_list }, + )?; + storage_cursor.upsert(addr, entry)?; + + let storage_change_sharded_key = + ContractStorageKey { contract_address: addr, key: entry.key }; + + db_tx.put::( + block_number, + ContractStorageEntry { + key: storage_change_sharded_key, + value: entry.value, + }, + )?; + } + } + } + + // update contract info + + for (addr, class_hash) in states.state_updates.contract_updates { + let value = if let Some(info) = db_tx.get::(addr)? { + GenericContractInfo { class_hash, ..info } + } else { + GenericContractInfo { class_hash, ..Default::default() } + }; + + let new_change_set = + if let Some(mut change_set) = db_tx.get::(addr)? { + change_set.class_change_list.push(block_number); + change_set.class_change_list.sort(); + change_set + } else { + ContractInfoChangeList { + class_change_list: vec![block_number], + ..Default::default() + } + }; + + db_tx.put::(addr, value)?; + + let class_change_key = ContractClassChange { contract_address: addr, class_hash }; + db_tx.put::(block_number, class_change_key)?; + db_tx.put::(addr, new_change_set)?; + } + + for (addr, nonce) in states.state_updates.nonce_updates { + let value = if let Some(info) = db_tx.get::(addr)? { + GenericContractInfo { nonce, ..info } + } else { + GenericContractInfo { nonce, ..Default::default() } + }; + + let new_change_set = + if let Some(mut change_set) = db_tx.get::(addr)? { + change_set.nonce_change_list.push(block_number); + change_set.nonce_change_list.sort(); + change_set + } else { + ContractInfoChangeList { + nonce_change_list: vec![block_number], + ..Default::default() + } + }; + + db_tx.put::(addr, value)?; + + let nonce_change_key = ContractNonceChange { contract_address: addr, nonce }; + db_tx.put::(block_number, nonce_change_key)?; + db_tx.put::(addr, new_change_set)?; + } + + Ok(()) + })? + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use katana_db::mdbx::DbEnvKind; + use katana_primitives::block::{ + Block, BlockHashOrNumber, FinalityStatus, Header, SealedBlockWithStatus, + }; + use katana_primitives::contract::ContractAddress; + use katana_primitives::receipt::Receipt; + use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; + use katana_primitives::transaction::{Tx, TxHash, TxWithHash}; + use starknet::macros::felt; + + use super::DbProvider; + use crate::traits::block::{ + BlockHashProvider, BlockNumberProvider, BlockProvider, BlockStatusProvider, BlockWriter, + }; + use crate::traits::state::StateFactoryProvider; + use crate::traits::transaction::TransactionProvider; + + fn create_dummy_block() -> SealedBlockWithStatus { + let header = Header { parent_hash: 199u8.into(), number: 0, ..Default::default() }; + let block = Block { + header, + body: vec![TxWithHash { + hash: 24u8.into(), + transaction: Tx::Invoke(Default::default()), + }], + } + .seal(); + SealedBlockWithStatus { block, status: FinalityStatus::AcceptedOnL2 } + } + + fn create_dummy_state_updates() -> StateUpdatesWithDeclaredClasses { + StateUpdatesWithDeclaredClasses { + state_updates: StateUpdates { + nonce_updates: HashMap::from([ + (ContractAddress::from(felt!("1")), felt!("1")), + (ContractAddress::from(felt!("2")), felt!("2")), + ]), + contract_updates: HashMap::from([ + (ContractAddress::from(felt!("1")), felt!("3")), + (ContractAddress::from(felt!("2")), felt!("4")), + ]), + declared_classes: HashMap::from([ + (felt!("3"), felt!("89")), + (felt!("4"), felt!("90")), + ]), + storage_updates: HashMap::from([( + ContractAddress::from(felt!("1")), + HashMap::from([(felt!("1"), felt!("1")), (felt!("2"), felt!("2"))]), + )]), + }, + ..Default::default() + } + } + + fn create_dummy_state_updates_2() -> StateUpdatesWithDeclaredClasses { + StateUpdatesWithDeclaredClasses { + state_updates: StateUpdates { + nonce_updates: HashMap::from([ + (ContractAddress::from(felt!("1")), felt!("5")), + (ContractAddress::from(felt!("2")), felt!("6")), + ]), + contract_updates: HashMap::from([ + (ContractAddress::from(felt!("1")), felt!("77")), + (ContractAddress::from(felt!("2")), felt!("66")), + ]), + storage_updates: HashMap::from([( + ContractAddress::from(felt!("1")), + HashMap::from([(felt!("1"), felt!("100")), (felt!("2"), felt!("200"))]), + )]), + ..Default::default() + }, + ..Default::default() + } + } + + fn create_db_provider() -> DbProvider { + DbProvider(katana_db::mdbx::test_utils::create_test_db(DbEnvKind::RW)) + } + + #[test] + fn insert_block() { + let provider = create_db_provider(); + + let block = create_dummy_block(); + let state_updates = create_dummy_state_updates(); + + // insert block + BlockWriter::insert_block_with_states_and_receipts( + &provider, + block.clone(), + state_updates, + vec![Receipt::Invoke(Default::default())], + ) + .expect("failed to insert block"); + + // get values + + let block_id: BlockHashOrNumber = block.block.header.hash.into(); + + let latest_number = provider.latest_number().unwrap(); + let latest_hash = provider.latest_hash().unwrap(); + + let actual_block = provider.block(block_id).unwrap().unwrap(); + let tx_count = provider.transaction_count_by_block(block_id).unwrap().unwrap(); + let block_status = provider.block_status(block_id).unwrap().unwrap(); + let body_indices = provider.block_body_indices(block_id).unwrap().unwrap(); + + let tx_hash: TxHash = 24u8.into(); + let tx = provider.transaction_by_hash(tx_hash).unwrap().unwrap(); + + let state_prov = StateFactoryProvider::latest(&provider).unwrap(); + + let nonce1 = state_prov.nonce(ContractAddress::from(felt!("1"))).unwrap().unwrap(); + let nonce2 = state_prov.nonce(ContractAddress::from(felt!("2"))).unwrap().unwrap(); + + let class_hash1 = state_prov.class_hash_of_contract(felt!("1").into()).unwrap().unwrap(); + let class_hash2 = state_prov.class_hash_of_contract(felt!("2").into()).unwrap().unwrap(); + + let compiled_hash1 = + state_prov.compiled_class_hash_of_class_hash(class_hash1).unwrap().unwrap(); + let compiled_hash2 = + state_prov.compiled_class_hash_of_class_hash(class_hash2).unwrap().unwrap(); + + let storage1 = + state_prov.storage(ContractAddress::from(felt!("1")), felt!("1")).unwrap().unwrap(); + let storage2 = + state_prov.storage(ContractAddress::from(felt!("1")), felt!("2")).unwrap().unwrap(); + + // assert values are populated correctly + + assert_eq!(tx_hash, tx.hash); + assert_eq!(tx.transaction, Tx::Invoke(Default::default())); + + assert_eq!(tx_count, 1); + assert_eq!(body_indices.tx_offset, 0); + assert_eq!(body_indices.tx_count, tx_count); + + assert_eq!(block_status, FinalityStatus::AcceptedOnL2); + assert_eq!(block.block.header.hash, latest_hash); + assert_eq!(block.block.body.len() as u64, tx_count); + assert_eq!(block.block.header.header.number, latest_number); + assert_eq!(block.block.unseal(), actual_block); + + assert_eq!(nonce1, felt!("1")); + assert_eq!(nonce2, felt!("2")); + assert_eq!(class_hash1, felt!("3")); + assert_eq!(class_hash2, felt!("4")); + + assert_eq!(compiled_hash1, felt!("89")); + assert_eq!(compiled_hash2, felt!("90")); + + assert_eq!(storage1, felt!("1")); + assert_eq!(storage2, felt!("2")); + } + + #[test] + fn storage_updated_correctly() { + let provider = create_db_provider(); + + let block = create_dummy_block(); + let state_updates1 = create_dummy_state_updates(); + let state_updates2 = create_dummy_state_updates_2(); + + // insert block + BlockWriter::insert_block_with_states_and_receipts( + &provider, + block.clone(), + state_updates1, + vec![Receipt::Invoke(Default::default())], + ) + .expect("failed to insert block"); + + // insert another block + BlockWriter::insert_block_with_states_and_receipts( + &provider, + block, + state_updates2, + vec![Receipt::Invoke(Default::default())], + ) + .expect("failed to insert block"); + + // assert storage is updated correctly + + let state_prov = StateFactoryProvider::latest(&provider).unwrap(); + + let nonce1 = state_prov.nonce(ContractAddress::from(felt!("1"))).unwrap().unwrap(); + let nonce2 = state_prov.nonce(ContractAddress::from(felt!("2"))).unwrap().unwrap(); + + let class_hash1 = state_prov.class_hash_of_contract(felt!("1").into()).unwrap().unwrap(); + let class_hash2 = state_prov.class_hash_of_contract(felt!("2").into()).unwrap().unwrap(); + + let storage1 = + state_prov.storage(ContractAddress::from(felt!("1")), felt!("1")).unwrap().unwrap(); + let storage2 = + state_prov.storage(ContractAddress::from(felt!("1")), felt!("2")).unwrap().unwrap(); + + assert_eq!(nonce1, felt!("5")); + assert_eq!(nonce2, felt!("6")); + + assert_eq!(class_hash1, felt!("77")); + assert_eq!(class_hash2, felt!("66")); + + assert_eq!(storage1, felt!("100")); + assert_eq!(storage2, felt!("200")); + } +} diff --git a/crates/katana/storage/provider/src/providers/db/state.rs b/crates/katana/storage/provider/src/providers/db/state.rs new file mode 100644 index 0000000000..0230ade4e5 --- /dev/null +++ b/crates/katana/storage/provider/src/providers/db/state.rs @@ -0,0 +1,337 @@ +use std::cmp::Ordering; + +use anyhow::Result; +use katana_db::mdbx::{self}; +use katana_db::models::contract::{ + ContractClassChange, ContractInfoChangeList, ContractNonceChange, +}; +use katana_db::models::storage::{ContractStorageEntry, ContractStorageKey, StorageEntry}; +use katana_db::tables::{ + ClassDeclarationBlock, CompiledClassHashes, CompiledContractClasses, ContractClassChanges, + ContractInfo, ContractInfoChangeSet, ContractStorage, NonceChanges, SierraClasses, + StorageChangeSet, StorageChanges, +}; +use katana_primitives::block::BlockNumber; +use katana_primitives::contract::{ + ClassHash, CompiledClassHash, CompiledContractClass, ContractAddress, GenericContractInfo, + Nonce, SierraClass, StorageKey, StorageValue, +}; + +use super::DbProvider; +use crate::traits::contract::{ContractClassProvider, ContractClassWriter}; +use crate::traits::state::{StateProvider, StateWriter}; + +impl StateWriter for DbProvider { + fn set_nonce(&self, address: ContractAddress, nonce: Nonce) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + let value = if let Some(info) = db_tx.get::(address)? { + GenericContractInfo { nonce, ..info } + } else { + GenericContractInfo { nonce, ..Default::default() } + }; + db_tx.put::(address, value)?; + Ok(()) + })? + } + + fn set_storage( + &self, + address: ContractAddress, + storage_key: StorageKey, + storage_value: StorageValue, + ) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + let mut cursor = db_tx.cursor::()?; + let entry = cursor.seek_by_key_subkey(address, storage_key)?; + + match entry { + Some(entry) if entry.key == storage_key => { + cursor.delete_current()?; + } + _ => {} + } + + cursor.upsert(address, StorageEntry { key: storage_key, value: storage_value })?; + Ok(()) + })? + } + + fn set_class_hash_of_contract( + &self, + address: ContractAddress, + class_hash: ClassHash, + ) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + let value = if let Some(info) = db_tx.get::(address)? { + GenericContractInfo { class_hash, ..info } + } else { + GenericContractInfo { class_hash, ..Default::default() } + }; + db_tx.put::(address, value)?; + Ok(()) + })? + } +} + +impl ContractClassWriter for DbProvider { + fn set_class(&self, hash: ClassHash, class: CompiledContractClass) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + db_tx.put::(hash, class.into())?; + Ok(()) + })? + } + + fn set_compiled_class_hash_of_class_hash( + &self, + hash: ClassHash, + compiled_hash: CompiledClassHash, + ) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + db_tx.put::(hash, compiled_hash)?; + Ok(()) + })? + } + + fn set_sierra_class(&self, hash: ClassHash, sierra: SierraClass) -> Result<()> { + self.0.update(move |db_tx| -> Result<()> { + db_tx.put::(hash, sierra)?; + Ok(()) + })? + } +} + +/// A state provider that provides the latest states from the database. +pub(super) struct LatestStateProvider(mdbx::tx::TxRO); + +impl LatestStateProvider { + pub fn new(tx: mdbx::tx::TxRO) -> Self { + Self(tx) + } +} + +impl ContractClassProvider for LatestStateProvider { + fn class(&self, hash: ClassHash) -> Result> { + let class = self.0.get::(hash)?; + Ok(class.map(CompiledContractClass::from)) + } + + fn compiled_class_hash_of_class_hash( + &self, + hash: ClassHash, + ) -> Result> { + let hash = self.0.get::(hash)?; + Ok(hash) + } + + fn sierra_class(&self, hash: ClassHash) -> Result> { + let class = self.0.get::(hash)?; + Ok(class) + } +} + +impl StateProvider for LatestStateProvider { + fn nonce(&self, address: ContractAddress) -> Result> { + let info = self.0.get::(address)?; + Ok(info.map(|info| info.nonce)) + } + + fn class_hash_of_contract( + &self, + address: ContractAddress, + ) -> Result> { + let info = self.0.get::(address)?; + Ok(info.map(|info| info.class_hash)) + } + + fn storage( + &self, + address: ContractAddress, + storage_key: StorageKey, + ) -> Result> { + let mut cursor = self.0.cursor::()?; + let entry = cursor.seek_by_key_subkey(address, storage_key)?; + match entry { + Some(entry) if entry.key == storage_key => Ok(Some(entry.value)), + _ => Ok(None), + } + } +} + +/// A historical state provider. +pub(super) struct HistoricalStateProvider { + /// The database transaction used to read the database. + tx: mdbx::tx::TxRO, + /// The block number of the state. + block_number: u64, +} + +impl HistoricalStateProvider { + pub fn new(tx: mdbx::tx::TxRO, block_number: u64) -> Self { + Self { tx, block_number } + } + + // This looks ugly but it works and I will most likely forget how it works + // if I don't document it. But im lazy. + fn recent_block_change_relative_to_pinned_block_num( + block_number: BlockNumber, + block_list: &[BlockNumber], + ) -> Option { + if block_list.first().is_some_and(|num| block_number < *num) { + return None; + } + + // if the pinned block number is smaller than the first block number in the list, + // then that means there is no change happening before the pinned block number. + let pos = { + if let Some(pos) = block_list.last().and_then(|num| { + if block_number >= *num { Some(block_list.len() - 1) } else { None } + }) { + Some(pos) + } else { + block_list.iter().enumerate().find_map(|(i, num)| match block_number.cmp(num) { + Ordering::Equal => Some(i), + Ordering::Greater => None, + Ordering::Less => { + if i == 0 || block_number == 0 { + None + } else { + Some(i - 1) + } + } + }) + } + }?; + + block_list.get(pos).copied() + } +} + +impl ContractClassProvider for HistoricalStateProvider { + fn compiled_class_hash_of_class_hash( + &self, + hash: ClassHash, + ) -> Result> { + // check that the requested class hash was declared before the pinned block number + if !self.tx.get::(hash)?.is_some_and(|num| num <= self.block_number) + { + return Ok(None); + }; + + Ok(self.tx.get::(hash)?) + } + + fn class(&self, hash: ClassHash) -> Result> { + self.compiled_class_hash_of_class_hash(hash).and_then(|_| { + let contract = self.tx.get::(hash)?; + Ok(contract.map(CompiledContractClass::from)) + }) + } + + fn sierra_class(&self, hash: ClassHash) -> Result> { + self.compiled_class_hash_of_class_hash(hash) + .and_then(|_| self.tx.get::(hash).map_err(|e| e.into())) + } +} + +impl StateProvider for HistoricalStateProvider { + fn nonce(&self, address: ContractAddress) -> Result> { + let change_list = self.tx.get::(address)?; + + if let Some(num) = change_list.and_then(|entry| { + Self::recent_block_change_relative_to_pinned_block_num( + self.block_number, + &entry.nonce_change_list, + ) + }) { + let mut cursor = self.tx.cursor::()?; + let ContractNonceChange { contract_address, nonce } = cursor + .seek_by_key_subkey(num, address)? + .expect("if block number is in the block set, change entry must exist"); + + if contract_address == address { + return Ok(Some(nonce)); + } + } + + Ok(None) + } + + fn class_hash_of_contract(&self, address: ContractAddress) -> Result> { + let change_list: Option = + self.tx.get::(address)?; + + if let Some(num) = change_list.and_then(|entry| { + Self::recent_block_change_relative_to_pinned_block_num( + self.block_number, + &entry.class_change_list, + ) + }) { + let mut cursor = self.tx.cursor::()?; + let ContractClassChange { contract_address, class_hash } = cursor + .seek_by_key_subkey(num, address)? + .expect("if block number is in the block set, change entry must exist"); + + if contract_address == address { + return Ok(Some(class_hash)); + } + } + + Ok(None) + } + + fn storage( + &self, + address: ContractAddress, + storage_key: StorageKey, + ) -> Result> { + let mut cursor = self.tx.cursor::()?; + + if let Some(num) = cursor.seek_by_key_subkey(address, storage_key)?.and_then(|entry| { + Self::recent_block_change_relative_to_pinned_block_num( + self.block_number, + &entry.block_list, + ) + }) { + let mut cursor = self.tx.cursor::()?; + let sharded_key = ContractStorageKey { contract_address: address, key: storage_key }; + + let ContractStorageEntry { key, value } = cursor + .seek_by_key_subkey(num, sharded_key)? + .expect("if block number is in the block set, change entry must exist"); + + if key.contract_address == address && key.key == storage_key { + return Ok(Some(value)); + } + } + + Ok(None) + } +} + +#[cfg(test)] +mod tests { + use super::HistoricalStateProvider; + + const BLOCK_LIST: [u64; 5] = [1, 2, 5, 6, 10]; + + #[rstest::rstest] + #[case(0, None)] + #[case(1, Some(1))] + #[case(3, Some(2))] + #[case(5, Some(5))] + #[case(9, Some(6))] + #[case(10, Some(10))] + #[case(11, Some(10))] + fn position_of_most_recent_block_in_block_list( + #[case] block_num: u64, + #[case] expected_block_num: Option, + ) { + assert_eq!( + HistoricalStateProvider::recent_block_change_relative_to_pinned_block_num( + block_num, + &BLOCK_LIST, + ), + expected_block_num + ); + } +} diff --git a/crates/katana/storage/provider/src/providers/mod.rs b/crates/katana/storage/provider/src/providers/mod.rs index 0c2dc27d17..d565e76a9a 100644 --- a/crates/katana/storage/provider/src/providers/mod.rs +++ b/crates/katana/storage/provider/src/providers/mod.rs @@ -1,3 +1,4 @@ +pub mod db; #[cfg(feature = "fork")] pub mod fork; #[cfg(feature = "in-memory")] diff --git a/crates/katana/storage/provider/src/traits/transaction.rs b/crates/katana/storage/provider/src/traits/transaction.rs index 8023d86568..c7dbee6be1 100644 --- a/crates/katana/storage/provider/src/traits/transaction.rs +++ b/crates/katana/storage/provider/src/traits/transaction.rs @@ -29,6 +29,11 @@ pub trait TransactionProvider: Send + Sync { &self, hash: TxHash, ) -> Result>; + + /// Retrieves all the transactions at the given range. + fn transaction_in_range(&self, _range: Range) -> Result> { + todo!() + } } #[auto_impl::auto_impl(&, Box, Arc)] diff --git a/crates/katana/storage/provider/tests/block.rs b/crates/katana/storage/provider/tests/block.rs index 03b8a4cecc..e62efa89e6 100644 --- a/crates/katana/storage/provider/tests/block.rs +++ b/crates/katana/storage/provider/tests/block.rs @@ -1,15 +1,29 @@ -use katana_primitives::block::BlockHashOrNumber; +use anyhow::Result; +use katana_primitives::block::{ + Block, BlockHashOrNumber, BlockNumber, BlockWithTxHashes, FinalityStatus, +}; +use katana_primitives::state::StateUpdates; +use katana_provider::providers::db::DbProvider; use katana_provider::providers::fork::ForkedProvider; use katana_provider::providers::in_memory::InMemoryProvider; -use katana_provider::traits::block::{BlockProvider, BlockWriter}; -use katana_provider::traits::transaction::{ReceiptProvider, TransactionProvider}; +use katana_provider::traits::block::{ + BlockHashProvider, BlockProvider, BlockStatusProvider, BlockWriter, +}; +use katana_provider::traits::state::StateRootProvider; +use katana_provider::traits::state_update::StateUpdateProvider; +use katana_provider::traits::transaction::{ + ReceiptProvider, TransactionProvider, TransactionStatusProvider, +}; use katana_provider::BlockchainProvider; use rstest_reuse::{self, *}; mod fixtures; mod utils; -use fixtures::{fork_provider, in_memory_provider}; +use fixtures::{ + db_provider, fork_provider, fork_provider_with_spawned_fork_network, in_memory_provider, + mock_state_updates, provider_with_states, +}; use utils::generate_dummy_blocks_and_receipts; #[template] @@ -24,7 +38,7 @@ fn insert_block_cases(#[case] block_count: u64) {} fn insert_block_with_in_memory_provider( #[from(in_memory_provider)] provider: BlockchainProvider, #[case] block_count: u64, -) -> anyhow::Result<()> { +) -> Result<()> { insert_block_test_impl(provider, block_count) } @@ -32,13 +46,25 @@ fn insert_block_with_in_memory_provider( fn insert_block_with_fork_provider( #[from(fork_provider)] provider: BlockchainProvider, #[case] block_count: u64, -) -> anyhow::Result<()> { +) -> Result<()> { insert_block_test_impl(provider, block_count) } -fn insert_block_test_impl(provider: BlockchainProvider, count: u64) -> anyhow::Result<()> +#[apply(insert_block_cases)] +fn insert_block_with_db_provider( + #[from(db_provider)] provider: BlockchainProvider, + #[case] block_count: u64, +) -> Result<()> { + insert_block_test_impl(provider, block_count) +} + +fn insert_block_test_impl(provider: BlockchainProvider, count: u64) -> Result<()> where - Db: BlockProvider + BlockWriter + ReceiptProvider, + Db: BlockProvider + + BlockWriter + + ReceiptProvider + + StateRootProvider + + TransactionStatusProvider, { let blocks = generate_dummy_blocks_and_receipts(count); @@ -50,23 +76,120 @@ where )?; } + let actual_blocks_in_range = provider.blocks_in_range(0..=count)?; + + assert_eq!(actual_blocks_in_range.len(), count as usize); + assert_eq!( + actual_blocks_in_range, + blocks.clone().into_iter().map(|b| b.0.block.unseal()).collect::>() + ); + for (block, receipts) in blocks { let block_id = BlockHashOrNumber::Hash(block.block.header.hash); + + let expected_block_num = block.block.header.header.number; + let expected_block_hash = block.block.header.hash; let expected_block = block.block.unseal(); + let actual_block_hash = provider.block_hash_by_num(expected_block_num)?; + let actual_block = provider.block(block_id)?; let actual_block_txs = provider.transactions_by_block(block_id)?; - let actual_block_tx_count = provider.transaction_count_by_block(block_id)?; + let actual_status = provider.block_status(block_id)?; + let actual_state_root = provider.state_root(block_id)?; + let actual_block_tx_count = provider.transaction_count_by_block(block_id)?; let actual_receipts = provider.receipts_by_block(block_id)?; + let expected_block_with_tx_hashes = BlockWithTxHashes { + header: expected_block.header.clone(), + body: expected_block.body.clone().into_iter().map(|t| t.hash).collect(), + }; + + let actual_block_with_tx_hashes = provider.block_with_tx_hashes(block_id)?; + + assert_eq!(actual_status, Some(FinalityStatus::AcceptedOnL2)); + assert_eq!(actual_block_with_tx_hashes, Some(expected_block_with_tx_hashes)); + + for (idx, tx) in expected_block.body.iter().enumerate() { + let actual_receipt = provider.receipt_by_hash(tx.hash)?; + let actual_tx = provider.transaction_by_hash(tx.hash)?; + let actual_tx_status = provider.transaction_status(tx.hash)?; + let actual_tx_block_num_hash = provider.transaction_block_num_and_hash(tx.hash)?; + let actual_tx_by_block_idx = + provider.transaction_by_block_and_idx(block_id, idx as u64)?; + + assert_eq!(actual_tx_block_num_hash, Some((expected_block_num, expected_block_hash))); + assert_eq!(actual_tx_status, Some(FinalityStatus::AcceptedOnL2)); + assert_eq!(actual_receipt, Some(receipts[idx].clone())); + assert_eq!(actual_tx_by_block_idx, Some(tx.clone())); + assert_eq!(actual_tx, Some(tx.clone())); + } + assert_eq!(actual_receipts.as_ref().map(|r| r.len()), Some(expected_block.body.len())); assert_eq!(actual_receipts, Some(receipts)); assert_eq!(actual_block_tx_count, Some(expected_block.body.len() as u64)); + assert_eq!(actual_state_root, Some(expected_block.header.state_root)); assert_eq!(actual_block_txs, Some(expected_block.body.clone())); + assert_eq!(actual_block_hash, Some(expected_block_hash)); assert_eq!(actual_block, Some(expected_block)); } Ok(()) } + +#[template] +#[rstest::rstest] +#[case::state_update_at_block_1(1, mock_state_updates().0)] +#[case::state_update_at_block_2(2, mock_state_updates().1)] +#[case::state_update_at_block_3(3, StateUpdates::default())] +#[case::state_update_at_block_5(5, mock_state_updates().2)] +fn test_read_state_update( + #[from(provider_with_states)] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_state_update: StateUpdates, +) { +} + +#[apply(test_read_state_update)] +fn test_read_state_update_with_in_memory_provider( + #[with(in_memory_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_state_update: StateUpdates, +) -> Result<()> { + test_read_state_update_impl(provider, block_num, expected_state_update) +} + +#[apply(test_read_state_update)] +fn test_read_state_update_with_fork_provider( + #[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider< + ForkedProvider, + >, + #[case] block_num: BlockNumber, + #[case] expected_state_update: StateUpdates, +) -> Result<()> { + test_read_state_update_impl(provider, block_num, expected_state_update) +} + +#[apply(test_read_state_update)] +fn test_read_state_update_with_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_state_update: StateUpdates, +) -> Result<()> { + test_read_state_update_impl(provider, block_num, expected_state_update) +} + +fn test_read_state_update_impl( + provider: BlockchainProvider, + block_num: BlockNumber, + expected_state_update: StateUpdates, +) -> Result<()> +where + Db: StateUpdateProvider, +{ + let actual_state_update = provider.state_update(BlockHashOrNumber::from(block_num))?; + assert_eq!(actual_state_update, Some(expected_state_update)); + Ok(()) +} diff --git a/crates/katana/storage/provider/tests/class.rs b/crates/katana/storage/provider/tests/class.rs index 68a2959843..58f399fc0f 100644 --- a/crates/katana/storage/provider/tests/class.rs +++ b/crates/katana/storage/provider/tests/class.rs @@ -23,7 +23,10 @@ fn assert_state_provider_class( } mod latest { + use katana_provider::providers::db::DbProvider; + use super::*; + use crate::fixtures::db_provider; fn assert_latest_class( provider: BlockchainProvider, @@ -65,10 +68,21 @@ mod latest { ) -> Result<()> { assert_latest_class(provider, expected_class) } + + #[apply(test_latest_class_read)] + fn read_class_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_latest_class(provider, expected_class) + } } mod historical { + use katana_provider::providers::db::DbProvider; + use super::*; + use crate::fixtures::db_provider; fn assert_historical_class( provider: BlockchainProvider, @@ -143,4 +157,13 @@ mod historical { ) -> Result<()> { assert_historical_class(provider, block_num, expected_class) } + + #[apply(test_historical_class_read)] + fn read_class_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_class: Vec<(ClassHash, Option)>, + ) -> Result<()> { + assert_historical_class(provider, block_num, expected_class) + } } diff --git a/crates/katana/storage/provider/tests/contract.rs b/crates/katana/storage/provider/tests/contract.rs index 3b54fdff78..57a6f428fd 100644 --- a/crates/katana/storage/provider/tests/contract.rs +++ b/crates/katana/storage/provider/tests/contract.rs @@ -1,7 +1,9 @@ mod fixtures; use anyhow::Result; -use fixtures::{fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states}; +use fixtures::{ + db_provider, fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states, +}; use katana_primitives::block::{BlockHashOrNumber, BlockNumber}; use katana_primitives::contract::{ClassHash, ContractAddress, Nonce}; use katana_provider::providers::fork::ForkedProvider; @@ -27,6 +29,8 @@ fn assert_state_provider_contract_info( } mod latest { + use katana_provider::providers::db::DbProvider; + use super::*; fn assert_latest_contract_info( @@ -68,9 +72,19 @@ mod latest { ) -> Result<()> { assert_latest_contract_info(provider, expected_contract_info) } + + #[apply(test_latest_contract_info_read)] + fn read_storage_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_latest_contract_info(provider, expected_contract_info) + } } mod historical { + use katana_provider::providers::db::DbProvider; + use super::*; fn assert_historical_contract_info( @@ -142,4 +156,13 @@ mod historical { ) -> Result<()> { assert_historical_contract_info(provider, block_num, expected_contract_info) } + + #[apply(test_historical_storage_read)] + fn read_storage_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_contract_info: Vec<(ContractAddress, Option, Option)>, + ) -> Result<()> { + assert_historical_contract_info(provider, block_num, expected_contract_info) + } } diff --git a/crates/katana/storage/provider/tests/fixtures.rs b/crates/katana/storage/provider/tests/fixtures.rs index 4021ab3672..3f0a685001 100644 --- a/crates/katana/storage/provider/tests/fixtures.rs +++ b/crates/katana/storage/provider/tests/fixtures.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; use std::sync::Arc; +use katana_db::mdbx; use katana_primitives::block::{ BlockHashOrNumber, FinalityStatus, Header, SealedBlock, SealedBlockWithStatus, SealedHeader, }; use katana_primitives::contract::ContractAddress; use katana_primitives::state::{StateUpdates, StateUpdatesWithDeclaredClasses}; +use katana_provider::providers::db::DbProvider; use katana_provider::providers::fork::ForkedProvider; use katana_provider::providers::in_memory::InMemoryProvider; use katana_provider::traits::block::BlockWriter; @@ -50,13 +52,13 @@ pub fn fork_provider_with_spawned_fork_network( } #[rstest::fixture] -#[default(BlockchainProvider)] -pub fn provider_with_states( - #[default(in_memory_provider())] provider: BlockchainProvider, -) -> BlockchainProvider -where - Db: BlockWriter + StateFactoryProvider, -{ +pub fn db_provider() -> BlockchainProvider { + let env = mdbx::test_utils::create_test_db(mdbx::DbEnvKind::RW); + BlockchainProvider::new(DbProvider::new(env)) +} + +#[rstest::fixture] +pub fn mock_state_updates() -> (StateUpdates, StateUpdates, StateUpdates) { let address_1 = ContractAddress::from(felt!("1")); let address_2 = ContractAddress::from(felt!("2")); @@ -69,54 +71,55 @@ where let class_hash_3 = felt!("33"); let compiled_class_hash_3 = felt!("3000"); - let state_update_at_block_1 = StateUpdatesWithDeclaredClasses { - state_updates: StateUpdates { - nonce_updates: HashMap::from([(address_1, 1u8.into()), (address_2, 1u8.into())]), - storage_updates: HashMap::from([ - ( - address_1, - HashMap::from([(1u8.into(), 100u32.into()), (2u8.into(), 101u32.into())]), - ), - ( - address_2, - HashMap::from([(1u8.into(), 200u32.into()), (2u8.into(), 201u32.into())]), - ), - ]), - declared_classes: HashMap::from([(class_hash_1, compiled_class_hash_1)]), - contract_updates: HashMap::from([(address_1, class_hash_1), (address_2, class_hash_1)]), - }, - ..Default::default() + let state_update_1 = StateUpdates { + nonce_updates: HashMap::from([(address_1, 1u8.into()), (address_2, 1u8.into())]), + storage_updates: HashMap::from([ + (address_1, HashMap::from([(1u8.into(), 100u32.into()), (2u8.into(), 101u32.into())])), + (address_2, HashMap::from([(1u8.into(), 200u32.into()), (2u8.into(), 201u32.into())])), + ]), + declared_classes: HashMap::from([(class_hash_1, compiled_class_hash_1)]), + contract_updates: HashMap::from([(address_1, class_hash_1), (address_2, class_hash_1)]), }; - let state_update_at_block_2 = StateUpdatesWithDeclaredClasses { - state_updates: StateUpdates { - nonce_updates: HashMap::from([(address_1, 2u8.into())]), - storage_updates: HashMap::from([( - address_1, - HashMap::from([(felt!("1"), felt!("111")), (felt!("2"), felt!("222"))]), - )]), - declared_classes: HashMap::from([(class_hash_2, compiled_class_hash_2)]), - contract_updates: HashMap::from([(address_2, class_hash_2)]), - }, - ..Default::default() + let state_update_2 = StateUpdates { + nonce_updates: HashMap::from([(address_1, 2u8.into())]), + storage_updates: HashMap::from([( + address_1, + HashMap::from([(felt!("1"), felt!("111")), (felt!("2"), felt!("222"))]), + )]), + declared_classes: HashMap::from([(class_hash_2, compiled_class_hash_2)]), + contract_updates: HashMap::from([(address_2, class_hash_2)]), }; - let state_update_at_block_5 = StateUpdatesWithDeclaredClasses { - state_updates: StateUpdates { - nonce_updates: HashMap::from([(address_1, 3u8.into()), (address_2, 2u8.into())]), - storage_updates: HashMap::from([ - (address_1, HashMap::from([(3u8.into(), 77u32.into())])), - ( - address_2, - HashMap::from([(1u8.into(), 12u32.into()), (2u8.into(), 13u32.into())]), - ), - ]), - contract_updates: HashMap::from([(address_1, class_hash_2), (address_2, class_hash_3)]), - declared_classes: HashMap::from([(class_hash_3, compiled_class_hash_3)]), - }, - ..Default::default() + let state_update_3 = StateUpdates { + nonce_updates: HashMap::from([(address_1, 3u8.into()), (address_2, 2u8.into())]), + storage_updates: HashMap::from([ + (address_1, HashMap::from([(3u8.into(), 77u32.into())])), + (address_2, HashMap::from([(1u8.into(), 12u32.into()), (2u8.into(), 13u32.into())])), + ]), + contract_updates: HashMap::from([(address_1, class_hash_2), (address_2, class_hash_3)]), + declared_classes: HashMap::from([(class_hash_3, compiled_class_hash_3)]), }; + (state_update_1, state_update_2, state_update_3) +} + +#[rstest::fixture] +#[default(BlockchainProvider)] +pub fn provider_with_states( + #[default(in_memory_provider())] provider: BlockchainProvider, + #[from(mock_state_updates)] state_updates: (StateUpdates, StateUpdates, StateUpdates), +) -> BlockchainProvider +where + Db: BlockWriter + StateFactoryProvider, +{ + let state_update_at_block_1 = + StateUpdatesWithDeclaredClasses { state_updates: state_updates.0, ..Default::default() }; + let state_update_at_block_2 = + StateUpdatesWithDeclaredClasses { state_updates: state_updates.1, ..Default::default() }; + let state_update_at_block_5 = + StateUpdatesWithDeclaredClasses { state_updates: state_updates.2, ..Default::default() }; + // Fill provider with states. for i in 0..=5 { diff --git a/crates/katana/storage/provider/tests/storage.rs b/crates/katana/storage/provider/tests/storage.rs index 4f12e8f5d8..07afc2e457 100644 --- a/crates/katana/storage/provider/tests/storage.rs +++ b/crates/katana/storage/provider/tests/storage.rs @@ -23,7 +23,10 @@ fn assert_state_provider_storage( } mod latest { + use katana_provider::providers::db::DbProvider; + use super::*; + use crate::fixtures::db_provider; fn assert_latest_storage_value( provider: BlockchainProvider, @@ -67,10 +70,21 @@ mod latest { ) -> Result<()> { assert_latest_storage_value(provider, expected_storage_entry) } + + #[apply(test_latest_storage_read)] + fn read_storage_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_latest_storage_value(provider, expected_storage_entry) + } } mod historical { + use katana_provider::providers::db::DbProvider; + use super::*; + use crate::fixtures::db_provider; fn assert_historical_storage_value( provider: BlockchainProvider, @@ -150,4 +164,13 @@ mod historical { ) -> Result<()> { assert_historical_storage_value(provider, block_num, expected_storage_entry) } + + #[apply(test_historical_storage_read)] + fn read_storage_from_db_provider( + #[with(db_provider())] provider: BlockchainProvider, + #[case] block_num: BlockNumber, + #[case] expected_storage_entry: Vec<(ContractAddress, StorageKey, Option)>, + ) -> Result<()> { + assert_historical_storage_value(provider, block_num, expected_storage_entry) + } } From 3b8252dc64c2ec2c5df17f2922c5a5abab668cf3 Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 20 Dec 2023 13:58:11 -0700 Subject: [PATCH 39/42] Release job fix --- .github/workflows/release-dispatch.yml | 10 +++------- .github/workflows/release.yml | 26 ++++++++++++++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml index cd43bbf812..1306b4c466 100644 --- a/.github/workflows/release-dispatch.yml +++ b/.github/workflows/release-dispatch.yml @@ -19,12 +19,8 @@ jobs: # Workaround described here: https://github.com/actions/checkout/issues/760 - uses: actions/checkout@v3 - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - - id: current_release_info - run: | - cargo install cargo-get - echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm - - id: next_release_info + - id: version_info run: | cargo install cargo-get echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT @@ -32,8 +28,8 @@ jobs: with: # We have to use a PAT in order to trigger ci token: ${{ secrets.CREATE_PR_TOKEN }} - title: "Prepare release: v${{ steps.next_release_info.outputs.version }}" - commit-message: "Prepare release: v${{ steps.next_release_info.outputs.version }}" + title: "Prepare release: v${{ steps.version_info.outputs.version }}" + commit-message: "Prepare release: v${{ steps.version_info.outputs.version }}" branch: prepare-release base: main delete-branch: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ddd1751b4..84edcb2558 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,7 @@ name: release on: + workflow_dispatch: pull_request: types: [closed] branches: @@ -13,7 +14,7 @@ env: jobs: prepare: - if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release' + if: (github.event_name == 'workflow_dispatch') || (github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release') runs-on: ubuntu-latest outputs: tag_name: ${{ steps.release_info.outputs.tag_name }} @@ -120,6 +121,7 @@ jobs: # We move binaries so they match $TARGETPLATFORM in the Docker build - name: Move Binaries + if: ${{ env.PLATFORM_NAME == 'linux' }} run: | mkdir -p $PLATFORM_NAME/$ARCH mv target/$TARGET/release/katana $PLATFORM_NAME/$ARCH @@ -128,13 +130,20 @@ jobs: shell: bash # Upload these for use with the Docker build later - - name: Upload binaries + - name: Upload docker binaries uses: actions/upload-artifact@v3 with: name: binaries path: ${{ env.PLATFORM_NAME }} retention-days: 1 + - name: Upload release artifacts + uses: actions/upload-artifact@v3 + with: + name: artifacts + path: ${{ steps.artifacts.outputs.file_name }} + retention-days: 1 + create-draft-release: runs-on: ubuntu-latest-4-cores needs: [prepare, release] @@ -146,11 +155,15 @@ jobs: - uses: actions/checkout@v2 - uses: actions/download-artifact@v3 with: - name: binaries + name: artifacts path: artifacts + - id: version_info + run: | + cargo install cargo-get + echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT - name: Display structure of downloaded files run: ls -R artifacts - - run: gh release create --generate-notes --draft ./artifacts + - run: gh release create v${{ steps.version_info.outputs.version }} ./artifacts/*.gz --generate-notes --draft docker-build-and-push: runs-on: ubuntu-latest-4-cores @@ -164,10 +177,7 @@ jobs: uses: actions/download-artifact@v3 with: name: binaries - path: artifacts - - - name: Display structure of downloaded files - run: ls -R artifacts + path: artifacts/linux - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 From 3e63ce03246b644d595ab2709df0670b562ad93b Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 20 Dec 2023 14:47:44 -0700 Subject: [PATCH 40/42] Document release flow --- .github/workflows/release.yml | 3 +-- README.md | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84edcb2558..c15be5138a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,6 @@ name: release on: - workflow_dispatch: pull_request: types: [closed] branches: @@ -14,7 +13,7 @@ env: jobs: prepare: - if: (github.event_name == 'workflow_dispatch') || (github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release') + if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release' runs-on: ubuntu-latest outputs: tag_name: ${{ steps.release_info.outputs.tag_name }} diff --git a/README.md b/README.md index e310d4ab83..354ff142ef 100644 --- a/README.md +++ b/README.md @@ -37,4 +37,10 @@ We welcome contributions of all kinds from anyone. See our [Contribution Guide]( ## ✏️ Enviroment -See our [Enviroment setup](https://book.dojoengine.org/getting-started/setup.html) for more information. \ No newline at end of file +See our [Enviroment setup](https://book.dojoengine.org/getting-started/setup.html) for more information. + +## Releasing + +Propose a new release by manually triggering the `release-dispatch` github action. The version value can be an semver or a level: `[patch, minor, major]`. + +Once run, the workflow will create a PR with the versioned repo which will trigger the release flow and the creation of a draft release on merge. From 90aeb26c1e6cd686c0b059a0463fafc8349ca8fb Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 20 Dec 2023 14:53:26 -0700 Subject: [PATCH 41/42] Fix tag prefix --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c15be5138a..d5b8d295ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,7 +100,7 @@ jobs: - name: Archive binaries id: artifacts env: - VERSION_NAME: ${{ needs.prepare.outputs.tag_name }} + VERSION_NAME: v${{ needs.prepare.outputs.tag_name }} run: | if [ "$PLATFORM_NAME" == "linux" ]; then tar -czvf "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" -C ./target/${TARGET}/release katana sozo torii dojo-language-server @@ -192,7 +192,7 @@ jobs: uses: docker/build-push-action@v3 with: push: true - tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:${{ needs.prepare.outputs.tag_name }} + tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:v${{ needs.prepare.outputs.tag_name }} platforms: linux/amd64,linux/arm64 build-contexts: | artifacts=artifacts From e351f0f568ecc0717c62b68b8f01505669a0d95c Mon Sep 17 00:00:00 2001 From: glihm Date: Wed, 20 Dec 2023 15:54:36 -0600 Subject: [PATCH 42/42] fix(dojo-lang): ensure a model has at least one attribute that is not a key (#1323) fix: ensure a model has at least one attribute that is not a key --- crates/dojo-lang/src/introspect.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/dojo-lang/src/introspect.rs b/crates/dojo-lang/src/introspect.rs index 662d8d4fbc..1370bf7470 100644 --- a/crates/dojo-lang/src/introspect.rs +++ b/crates/dojo-lang/src/introspect.rs @@ -279,6 +279,14 @@ fn handle_introspect_internal( size.push(format!("{}", size_precompute)); } + if size.is_empty() { + panic!( + "The model `{}` has only keys, ensure you have at least one field without the #[key] \ + attribute.", + name + ); + } + RewriteNode::interpolate_patched( " impl $name$Introspect<$generics$> of \