From b7644b85200e51616cae6b963f62347af1fa7b42 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:17:19 +0530 Subject: [PATCH 01/63] chore : switch to asset-id evm --- .../src/functions/delegate.rs | 77 ++++++----- pallets/multi-asset-delegation/src/lib.rs | 109 +++++++--------- pallets/multi-asset-delegation/src/mock.rs | 123 +++++++++--------- pallets/multi-asset-delegation/src/types.rs | 2 + .../multi-asset-delegation/src/types/asset.rs | 66 ++++++++++ .../src/types/delegator.rs | 57 ++++---- .../src/types/operator.rs | 41 +++--- 7 files changed, 272 insertions(+), 203 deletions(-) create mode 100644 pallets/multi-asset-delegation/src/types/asset.rs diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 19225533..dd9a704d 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -32,7 +32,7 @@ impl Pallet { /// /// * `who` - The account ID of the delegator. /// * `operator` - The account ID of the operator. - /// * `asset_id` - The ID of the asset to be delegated. + /// * `asset` - The asset to be delegated. /// * `amount` - The amount to be delegated. /// /// # Errors @@ -42,7 +42,7 @@ impl Pallet { pub fn process_delegate( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, ) -> DispatchResult { @@ -50,21 +50,20 @@ impl Pallet { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; // Ensure enough deposited balance - let balance = - metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; + let balance = metadata.deposits.get_mut(&asset).ok_or(Error::::InsufficientBalance)?; ensure!(*balance >= amount, Error::::InsufficientBalance); // Reduce the balance in deposits *balance = balance.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; if *balance == Zero::zero() { - metadata.deposits.remove(&asset_id); + metadata.deposits.remove(&asset); } // Check if the delegation exists and update it, otherwise create a new delegation if let Some(delegation) = metadata .delegations .iter_mut() - .find(|d| d.operator == operator && d.asset_id == asset_id) + .find(|d| d.operator == operator && d.asset == asset) { delegation.amount += amount; } else { @@ -72,7 +71,7 @@ impl Pallet { let new_delegation = BondInfoDelegator { operator: operator.clone(), amount, - asset_id, + asset, blueprint_selection, }; @@ -96,13 +95,13 @@ impl Pallet { ); // Create and push the new delegation bond - let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; + let delegation = DelegatorBond { delegator: who.clone(), amount, asset }; let mut delegations = operator_metadata.delegations.clone(); // Check if delegation already exists if let Some(existing_delegation) = - delegations.iter_mut().find(|d| d.delegator == who && d.asset_id == asset_id) + delegations.iter_mut().find(|d| d.delegator == who && d.asset == asset) { existing_delegation.amount += amount; } else { @@ -131,7 +130,7 @@ impl Pallet { /// /// * `who` - The account ID of the delegator. /// * `operator` - The account ID of the operator. - /// * `asset_id` - The ID of the asset to be reduced. + /// * `asset` - The asset to be reduced. /// * `amount` - The amount to be reduced. /// /// # Errors @@ -141,7 +140,7 @@ impl Pallet { pub fn process_schedule_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -151,7 +150,7 @@ impl Pallet { let delegation_index = metadata .delegations .iter() - .position(|d| d.operator == operator && d.asset_id == asset_id) + .position(|d| d.operator == operator && d.asset == asset) .ok_or(Error::::NoActiveDelegation)?; // Get the delegation and clone necessary data @@ -168,7 +167,7 @@ impl Pallet { unstake_requests .try_push(BondLessRequest { operator: operator.clone(), - asset_id, + asset, amount, requested_round: current_round, blueprint_selection, @@ -190,7 +189,7 @@ impl Pallet { let operator_delegation_index = operator_metadata .delegations .iter() - .position(|d| d.delegator == who && d.asset_id == asset_id) + .position(|d| d.delegator == who && d.asset == asset) .ok_or(Error::::NoActiveDelegation)?; let operator_delegation = @@ -240,7 +239,7 @@ impl Pallet { // Add the amount back to the delegator's deposits metadata .deposits - .entry(request.asset_id) + .entry(request.asset) .and_modify(|e| *e += request.amount) .or_insert(request.amount); executed_requests.push(request.clone()); @@ -262,7 +261,8 @@ impl Pallet { /// # Arguments /// /// * `who` - The account ID of the delegator. - /// * `asset_id` - The ID of the asset for which to cancel the unstake request. + /// * `operator` - The account ID of the operator. + /// * `asset` - The asset for which to cancel the unstake request. /// * `amount` - The amount of the unstake request to cancel. /// /// # Errors @@ -272,7 +272,7 @@ impl Pallet { pub fn process_cancel_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -282,9 +282,7 @@ impl Pallet { let request_index = metadata .delegator_unstake_requests .iter() - .position(|r| { - r.asset_id == asset_id && r.amount == amount && r.operator == operator - }) + .position(|r| r.asset == asset && r.amount == amount && r.operator == operator) .ok_or(Error::::NoBondLessRequest)?; let unstake_request = metadata.delegator_unstake_requests.remove(request_index); @@ -301,12 +299,12 @@ impl Pallet { let mut delegations = operator_metadata.delegations.clone(); if let Some(delegation) = delegations .iter_mut() - .find(|d| d.asset_id == asset_id && d.delegator == who.clone()) + .find(|d| d.asset == asset && d.delegator == who.clone()) { delegation.amount += amount; } else { delegations - .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) + .try_push(DelegatorBond { delegator: who.clone(), amount, asset }) .map_err(|_| Error::::MaxDelegationsExceeded)?; // Increase the delegation count only when a new delegation is added @@ -323,7 +321,7 @@ impl Pallet { // If a similar delegation exists, increase the amount if let Some(delegation) = delegations.iter_mut().find(|d| { - d.operator == unstake_request.operator && d.asset_id == unstake_request.asset_id + d.operator == unstake_request.operator && d.asset == unstake_request.asset }) { delegation.amount += unstake_request.amount; } else { @@ -332,7 +330,7 @@ impl Pallet { .try_push(BondInfoDelegator { operator: unstake_request.operator.clone(), amount: unstake_request.amount, - asset_id: unstake_request.asset_id, + asset: unstake_request.asset, blueprint_selection: unstake_request.blueprint_selection, }) .map_err(|_| Error::::MaxDelegationsExceeded)?; @@ -388,14 +386,29 @@ impl Pallet { .checked_sub(&slash_amount) .ok_or(Error::::InsufficientStakeRemaining)?; - // Transfer slashed amount to the treasury - let _ = T::Fungibles::transfer( - delegation.asset_id, - &Self::pallet_account(), - &T::SlashedAmountRecipient::get(), - slash_amount, - Preservation::Expendable, - ); + // Handle the slashed amount based on asset type + match delegation.asset { + Asset::Custom(asset_id) => { + // For custom assets, transfer to the treasury + let _ = T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &T::SlashedAmountRecipient::get(), + slash_amount, + Preservation::Expendable, + ); + }, + Asset::Erc20(contract_address) => { + // For ERC20 tokens, we need to handle differently + // This would typically involve interacting with the EVM to transfer tokens + // For now, we'll just emit an event + Self::deposit_event(Event::Erc20Slashed { + who: delegator.clone(), + contract_address, + amount: slash_amount, + }); + }, + } // emit event Self::deposit_event(Event::DelegatorSlashed { diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index bfb50073..ab6d0ebd 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -99,97 +99,82 @@ pub mod pallet { /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; - /// The currency type used for managing balances. - type Currency: Currency - + ReservableCurrency - + LockableCurrency; - - /// Type representing the unique ID of an asset. - type AssetId: Parameter - + Member - + Copy - + MaybeSerializeDeserialize - + Ord - + Default - + MaxEncodedLen - + TypeInfo; - - /// Type representing the unique ID of a vault. - type VaultId: Parameter - + Member - + Copy - + MaybeSerializeDeserialize - + Ord - + Default - + MaxEncodedLen - + TypeInfo; - - /// The maximum number of blueprints a delegator can have in Fixed mode. + /// The currency type for native token operations. + type Currency: Currency + ReservableCurrency + LockableCurrency; + + /// The minimum amount that an operator must bond. #[pallet::constant] - type MaxDelegatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + type MinOperatorBondAmount: Get>; - /// The maximum number of blueprints an operator can support. + /// The duration of the bond. #[pallet::constant] - type MaxOperatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + type BondDuration: Get; - /// The maximum number of withdraw requests a delegator can have. + /// The service manager type. + type ServiceManager: ServiceManager>; + + /// The number of rounds that must pass before an operator can leave. #[pallet::constant] - type MaxWithdrawRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + type LeaveOperatorsDelay: Get; - /// The maximum number of delegations a delegator can have. + /// The number of rounds that must pass before an operator can reduce their bond. #[pallet::constant] - type MaxDelegations: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + type OperatorBondLessDelay: Get; - /// The maximum number of unstake requests a delegator can have. + /// The number of rounds that must pass before a delegator can leave. #[pallet::constant] - type MaxUnstakeRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + type LeaveDelegatorsDelay: Get; - /// The minimum amount of stake required for an operator. + /// The number of rounds that must pass before a delegator can reduce their bond. #[pallet::constant] - type MinOperatorBondAmount: Get>; + type DelegationBondLessDelay: Get; - /// The minimum amount of stake required for a delegate. + /// The minimum amount that can be delegated. #[pallet::constant] type MinDelegateAmount: Get>; - /// The duration for which the stake is locked. - #[pallet::constant] - type BondDuration: Get; + /// The fungibles instance for handling multi-asset operations. + type Fungibles: fungibles::Inspect + fungibles::Mutate + fungibles::Transfer; - /// The service manager that manages active services. - type ServiceManager: ServiceManager>; + /// The base asset ID type. + type AssetId: Member + Parameter + Default + Copy + MaybeSerializeDeserialize + Debug + MaxEncodedLen; - /// Number of rounds that operators remain bonded before the exit request is executable. - #[pallet::constant] - type LeaveOperatorsDelay: Get; + /// The vault ID type. + type VaultId: Member + Parameter + Default + Copy + MaybeSerializeDeserialize + Debug + MaxEncodedLen; - /// Number of rounds operator requests to decrease self-stake must wait to be executable. + /// The origin that can force certain operations. + type ForceOrigin: EnsureOrigin; + + /// The pallet ID. #[pallet::constant] - type OperatorBondLessDelay: Get; + type PalletId: Get; - /// Number of rounds that delegators remain bonded before the exit request is executable. + /// The maximum number of blueprints a delegator can select. #[pallet::constant] - type LeaveDelegatorsDelay: Get; + type MaxDelegatorBlueprints: Get; - /// Number of rounds that delegation unstake requests must wait before being executable. + /// The maximum number of blueprints an operator can select. #[pallet::constant] - type DelegationBondLessDelay: Get; + type MaxOperatorBlueprints: Get; - /// The fungibles trait used for managing fungible assets. - type Fungibles: fungibles::Inspect> - + fungibles::Mutate; + /// The maximum number of withdraw requests. + #[pallet::constant] + type MaxWithdrawRequests: Get; - /// The pallet's account ID. - type PalletId: Get; + /// The maximum number of unstake requests. + #[pallet::constant] + type MaxUnstakeRequests: Get; - /// The origin with privileged access - type ForceOrigin: EnsureOrigin; + /// The maximum number of delegations. + #[pallet::constant] + type MaxDelegations: Get; - /// The address that receives slashed funds + /// The account that receives slashed amounts. + #[pallet::constant] type SlashedAmountRecipient: Get; - /// A type representing the weights required by the dispatchables of this pallet. - type WeightInfo: crate::weights::WeightInfo; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// The pallet struct. diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 397a8989..f5c83b48 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use crate as pallet_multi_asset_delegation; +use crate::types::Asset; use frame_support::{ derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU16, ConstU32, ConstU64}, @@ -29,7 +30,7 @@ use sp_runtime::{ type Block = frame_system::mocking::MockBlock; pub type Balance = u64; -pub type AssetId = u32; +pub type AssetId = Asset; pub const ALICE: u64 = 1; pub const BOB: u64 = 2; @@ -37,7 +38,7 @@ pub const CHARLIE: u64 = 3; pub const DAVE: u64 = 4; pub const EVE: u64 = 5; -pub const VDOT: AssetId = 1; +pub const VDOT: Asset = Asset::Vdot; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( @@ -93,46 +94,25 @@ impl pallet_balances::Config for Test { type MaxFreezes = (); } -pub struct MockServiceManager; - -impl tangle_primitives::ServiceManager for MockServiceManager { - fn get_active_blueprints_count(_account: &u64) -> usize { - // we dont care - Default::default() - } - - fn get_active_services_count(_account: &u64) -> usize { - // we dont care - Default::default() - } - - fn can_exit(_account: &u64) -> bool { - // Mock logic to determine if the given account can exit - true - } - - fn get_blueprints_by_operator(_account: &u64) -> Vec { - todo!(); // we dont care - } -} - -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaxLocks: u32 = 50; - pub const MinOperatorBondAmount: u64 = 10_000; - pub const BondDuration: u32 = 10; - pub PID: PalletId = PalletId(*b"PotStake"); - pub const SlashedAmountRecipient : u64 = 0; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxDelegatorBlueprints : u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxOperatorBlueprints : u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxWithdrawRequests: u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxUnstakeRequests: u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxDelegations: u32 = 50; +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = u64; + type AssetId = AssetId; + type AssetIdParameter = Asset; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; } impl pallet_multi_asset_delegation::Config for Test { @@ -160,25 +140,46 @@ impl pallet_multi_asset_delegation::Config for Test { type WeightInfo = (); } -impl pallet_assets::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Balance = u64; - type AssetId = AssetId; - type AssetIdParameter = u32; - type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = ConstU64<1>; - type AssetAccountDeposit = ConstU64<10>; - type MetadataDepositBase = ConstU64<1>; - type MetadataDepositPerByte = ConstU64<1>; - type ApprovalDeposit = ConstU64<1>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type WeightInfo = (); - type CallbackHandle = (); - type Extra = (); - type RemoveItemsLimit = ConstU32<5>; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaxLocks: u32 = 50; + pub const MinOperatorBondAmount: u64 = 10_000; + pub const BondDuration: u32 = 10; + pub PID: PalletId = PalletId(*b"PotStake"); + pub const SlashedAmountRecipient : u64 = 0; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxOperatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxWithdrawRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxUnstakeRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegations: u32 = 50; +} + +pub struct MockServiceManager; + +impl tangle_primitives::ServiceManager for MockServiceManager { + fn get_active_blueprints_count(_account: &u64) -> usize { + // we dont care + Default::default() + } + + fn get_active_services_count(_account: &u64) -> usize { + // we dont care + Default::default() + } + + fn can_exit(_account: &u64) -> bool { + // Mock logic to determine if the given account can exit + true + } + + fn get_blueprints_by_operator(_account: &u64) -> Vec { + todo!(); // we dont care + } } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index 8d6af158..15483e8a 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -25,10 +25,12 @@ use tangle_primitives::types::RoundIndex; pub mod delegator; pub mod operator; pub mod rewards; +pub mod asset; pub use delegator::*; pub use operator::*; pub use rewards::*; +pub use asset::*; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/pallets/multi-asset-delegation/src/types/asset.rs b/pallets/multi-asset-delegation/src/types/asset.rs new file mode 100644 index 00000000..ec993c72 --- /dev/null +++ b/pallets/multi-asset-delegation/src/types/asset.rs @@ -0,0 +1,66 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Webb Technologies Inc. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_core::H160; +use sp_runtime::RuntimeDebug; + +/// Represents an asset type that can be either a custom asset or an ERC20 token. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] +pub enum Asset { + /// Use the specified AssetId. + #[codec(index = 0)] + Custom(AssetId), + + /// Use an ERC20-like token with the specified contract address. + #[codec(index = 1)] + Erc20(H160), +} + +impl Default for Asset { + fn default() -> Self { + Asset::Custom(AssetId::default()) + } +} + +impl Asset { + /// Returns true if the asset is an ERC20 token. + pub fn is_erc20(&self) -> bool { + matches!(self, Asset::Erc20(_)) + } + + /// Returns true if the asset is a custom asset. + pub fn is_custom(&self) -> bool { + matches!(self, Asset::Custom(_)) + } + + /// Returns the ERC20 address if this is an ERC20 token. + pub fn erc20_address(&self) -> Option { + match self { + Asset::Erc20(address) => Some(*address), + _ => None, + } + } + + /// Returns the custom asset ID if this is a custom asset. + pub fn custom_id(&self) -> Option<&AssetId> { + match self { + Asset::Custom(id) => Some(id), + _ => None, + } + } +} diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 5c914ae1..0c1ade38 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use super::*; +use crate::types::Asset; use frame_support::{pallet_prelude::Get, BoundedVec}; use tangle_primitives::BlueprintId; @@ -46,9 +47,9 @@ pub enum DelegatorStatus { /// Represents a request to withdraw a specific amount of an asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct WithdrawRequest { - /// The ID of the asset to be withdrawd. - pub asset_id: AssetId, - /// The amount of the asset to be withdrawd. + /// The asset to be withdrawn. + pub asset: Asset, + /// The amount of the asset to be withdrawn. pub amount: Balance, /// The round in which the withdraw was requested. pub requested_round: RoundIndex, @@ -59,8 +60,8 @@ pub struct WithdrawRequest { pub struct BondLessRequest> { /// The account ID of the operator. pub operator: AccountId, - /// The ID of the asset to reduce the stake of. - pub asset_id: AssetId, + /// The asset to reduce the stake of. + pub asset: Asset, /// The amount by which to reduce the stake. pub amount: Balance, /// The round in which the stake reduction was requested. @@ -81,7 +82,7 @@ pub struct DelegatorMetadata< MaxBlueprints: Get, > { /// A map of deposited assets and their respective amounts. - pub deposits: BTreeMap, + pub deposits: BTreeMap, Balance>, /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. @@ -168,14 +169,14 @@ impl< } /// Calculates the total delegation amount for a specific asset. - pub fn calculate_delegation_by_asset(&self, asset_id: AssetId) -> Balance + pub fn calculate_delegation_by_asset(&self, asset: Asset) -> Balance where Balance: Default + core::ops::AddAssign + Clone, AssetId: Eq + PartialEq, { let mut total = Balance::default(); for stake in &self.delegations { - if stake.asset_id == asset_id { + if stake.asset == asset { total += stake.amount.clone(); } } @@ -199,8 +200,8 @@ impl< pub struct Deposit { /// The amount of the asset deposited. pub amount: Balance, - /// The ID of the deposited asset. - pub asset_id: AssetId, + /// The asset deposited. + pub asset: Asset, } /// Represents a stake between a delegator and an operator. @@ -210,8 +211,8 @@ pub struct BondInfoDelegator, /// The blueprint selection mode for this delegator. pub blueprint_selection: DelegatorBlueprintSelection, } @@ -284,12 +285,12 @@ mod tests { fn get_withdraw_requests_should_work() { let withdraw_requests = vec![ WithdrawRequest { - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), amount: MockBalance(50), requested_round: 1, }, WithdrawRequest { - asset_id: MockAssetId(2), + asset: Asset(MockAssetId(2)), amount: MockBalance(75), requested_round: 2, }, @@ -308,13 +309,13 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(75), - asset_id: MockAssetId(2), + asset: Asset(MockAssetId(2)), blueprint_selection: Default::default(), }, ]; @@ -331,14 +332,14 @@ mod tests { fn get_delegator_unstake_requests_should_work() { let unstake_requests = vec![ BondLessRequest { - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), amount: MockBalance(50), requested_round: 1, operator: MockAccountId(1), blueprint_selection: Default::default(), }, BondLessRequest { - asset_id: MockAssetId(2), + asset: Asset(MockAssetId(2)), amount: MockBalance(75), requested_round: 2, operator: MockAccountId(1), @@ -359,7 +360,7 @@ mod tests { delegations: BoundedVec::try_from(vec![BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }]) .unwrap(), @@ -378,19 +379,19 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(75), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(3), amount: MockBalance(25), - asset_id: MockAssetId(2), + asset: Asset(MockAssetId(2)), blueprint_selection: Default::default(), }, ]; @@ -399,9 +400,9 @@ mod tests { ..Default::default() }; - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(1)), MockBalance(125)); - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(2)), MockBalance(25)); - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(3)), MockBalance(0)); + assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(1))), MockBalance(125)); + assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(2))), MockBalance(25)); + assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(3))), MockBalance(0)); } #[test] @@ -410,19 +411,19 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(75), - asset_id: MockAssetId(2), + asset: Asset(MockAssetId(2)), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(25), - asset_id: MockAssetId(1), + asset: Asset(MockAssetId(1)), blueprint_selection: Default::default(), }, ]; diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 5798cb2d..9c81a0cd 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use super::*; +use crate::types::Asset; use frame_support::{pallet_prelude::*, BoundedVec}; /// A snapshot of the operator state at the start of the round. @@ -38,7 +39,7 @@ where pub fn get_stake_by_asset_id(&self, asset_id: AssetId) -> Balance { let mut total_stake = Balance::default(); for stake in &self.delegations { - if stake.asset_id == asset_id { + if stake.asset.id == asset_id { total_stake += stake.amount; } } @@ -50,7 +51,7 @@ where let mut stake_by_asset: BTreeMap = BTreeMap::new(); for stake in &self.delegations { - let entry = stake_by_asset.entry(stake.asset_id).or_default(); + let entry = stake_by_asset.entry(stake.asset.id).or_default(); *entry += stake.amount; } @@ -79,6 +80,17 @@ pub struct OperatorBondLessRequest { pub request_time: RoundIndex, } +/// Represents a delegation from a delegator to an operator. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct DelegatorBond { + /// The delegator's account ID. + pub delegator: AccountId, + /// The amount bonded. + pub amount: Balance, + /// The asset bonded. + pub asset: Asset, +} + /// Stores the metadata of an operator. #[derive(Encode, Decode, RuntimeDebug, TypeInfo, Clone, Eq, PartialEq)] pub struct OperatorMetadata< @@ -120,17 +132,6 @@ where } } -/// Represents a stake for an operator -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond { - /// The account ID of the delegator. - pub delegator: AccountId, - /// The amount bonded. - pub amount: Balance, - /// The ID of the bonded asset. - pub asset_id: AssetId, -} - // ------ Test for helper functions ------ // #[cfg(test)] @@ -190,17 +191,17 @@ mod tests { DelegatorBond { delegator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset { id: MockAssetId(1), ..Default::default() }, }, DelegatorBond { delegator: MockAccountId(2), amount: MockBalance(75), - asset_id: MockAssetId(1), + asset: Asset { id: MockAssetId(1), ..Default::default() }, }, DelegatorBond { delegator: MockAccountId(3), amount: MockBalance(25), - asset_id: MockAssetId(2), + asset: Asset { id: MockAssetId(2), ..Default::default() }, }, ]) .unwrap(), @@ -220,22 +221,22 @@ mod tests { DelegatorBond { delegator: MockAccountId(1), amount: MockBalance(50), - asset_id: MockAssetId(1), + asset: Asset { id: MockAssetId(1), ..Default::default() }, }, DelegatorBond { delegator: MockAccountId(2), amount: MockBalance(75), - asset_id: MockAssetId(1), + asset: Asset { id: MockAssetId(1), ..Default::default() }, }, DelegatorBond { delegator: MockAccountId(3), amount: MockBalance(25), - asset_id: MockAssetId(2), + asset: Asset { id: MockAssetId(2), ..Default::default() }, }, DelegatorBond { delegator: MockAccountId(4), amount: MockBalance(100), - asset_id: MockAssetId(2), + asset: Asset { id: MockAssetId(2), ..Default::default() }, }, ]) .unwrap(), From ce7effee24a70d5adb012e8bb48b67030585c1ef Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 12 Dec 2024 02:13:23 +0530 Subject: [PATCH 02/63] cleanup --- .../src/functions/delegate.rs | 3 +- pallets/multi-asset-delegation/src/lib.rs | 22 +++- pallets/multi-asset-delegation/src/types.rs | 4 +- .../multi-asset-delegation/src/types/asset.rs | 62 ++++----- precompiles/multi-asset-delegation/src/lib.rs | 123 ++++++++++++------ 5 files changed, 135 insertions(+), 79 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index dd9a704d..e2f750f5 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -50,7 +50,8 @@ impl Pallet { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; // Ensure enough deposited balance - let balance = metadata.deposits.get_mut(&asset).ok_or(Error::::InsufficientBalance)?; + let balance = + metadata.deposits.get_mut(&asset).ok_or(Error::::InsufficientBalance)?; ensure!(*balance >= amount, Error::::InsufficientBalance); // Reduce the balance in deposits diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index ab6d0ebd..3fc9aecb 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -100,7 +100,9 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// The currency type for native token operations. - type Currency: Currency + ReservableCurrency + LockableCurrency; + type Currency: Currency + + ReservableCurrency + + LockableCurrency; /// The minimum amount that an operator must bond. #[pallet::constant] @@ -134,13 +136,25 @@ pub mod pallet { type MinDelegateAmount: Get>; /// The fungibles instance for handling multi-asset operations. - type Fungibles: fungibles::Inspect + fungibles::Mutate + fungibles::Transfer; + type Fungibles: fungibles::Inspect + fungibles::Mutate; /// The base asset ID type. - type AssetId: Member + Parameter + Default + Copy + MaybeSerializeDeserialize + Debug + MaxEncodedLen; + type AssetId: Member + + Parameter + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen; /// The vault ID type. - type VaultId: Member + Parameter + Default + Copy + MaybeSerializeDeserialize + Debug + MaxEncodedLen; + type VaultId: Member + + Parameter + + Default + + Copy + + MaybeSerializeDeserialize + + Debug + + MaxEncodedLen; /// The origin that can force certain operations. type ForceOrigin: EnsureOrigin; diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index 15483e8a..e1ba3eb8 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -22,15 +22,15 @@ use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::RoundIndex; +pub mod asset; pub mod delegator; pub mod operator; pub mod rewards; -pub mod asset; +pub use asset::*; pub use delegator::*; pub use operator::*; pub use rewards::*; -pub use asset::*; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/pallets/multi-asset-delegation/src/types/asset.rs b/pallets/multi-asset-delegation/src/types/asset.rs index ec993c72..6c3afc91 100644 --- a/pallets/multi-asset-delegation/src/types/asset.rs +++ b/pallets/multi-asset-delegation/src/types/asset.rs @@ -22,45 +22,45 @@ use sp_runtime::RuntimeDebug; /// Represents an asset type that can be either a custom asset or an ERC20 token. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] pub enum Asset { - /// Use the specified AssetId. - #[codec(index = 0)] - Custom(AssetId), + /// Use the specified AssetId. + #[codec(index = 0)] + Custom(AssetId), - /// Use an ERC20-like token with the specified contract address. - #[codec(index = 1)] - Erc20(H160), + /// Use an ERC20-like token with the specified contract address. + #[codec(index = 1)] + Erc20(H160), } impl Default for Asset { - fn default() -> Self { - Asset::Custom(AssetId::default()) - } + fn default() -> Self { + Asset::Custom(AssetId::default()) + } } impl Asset { - /// Returns true if the asset is an ERC20 token. - pub fn is_erc20(&self) -> bool { - matches!(self, Asset::Erc20(_)) - } + /// Returns true if the asset is an ERC20 token. + pub fn is_erc20(&self) -> bool { + matches!(self, Asset::Erc20(_)) + } - /// Returns true if the asset is a custom asset. - pub fn is_custom(&self) -> bool { - matches!(self, Asset::Custom(_)) - } + /// Returns true if the asset is a custom asset. + pub fn is_custom(&self) -> bool { + matches!(self, Asset::Custom(_)) + } - /// Returns the ERC20 address if this is an ERC20 token. - pub fn erc20_address(&self) -> Option { - match self { - Asset::Erc20(address) => Some(*address), - _ => None, - } - } + /// Returns the ERC20 address if this is an ERC20 token. + pub fn erc20_address(&self) -> Option { + match self { + Asset::Erc20(address) => Some(*address), + _ => None, + } + } - /// Returns the custom asset ID if this is a custom asset. - pub fn custom_id(&self) -> Option<&AssetId> { - match self { - Asset::Custom(id) => Some(id), - _ => None, - } - } + /// Returns the custom asset ID if this is a custom asset. + pub fn custom_id(&self) -> Option<&AssetId> { + match self { + Asset::Custom(id) => Some(id), + _ => None, + } + } } diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 85eaf7f8..6fd4ebb3 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -47,7 +47,7 @@ use pallet_evm::AddressMapping; use pallet_multi_asset_delegation::types::DelegatorBlueprintSelection; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; -use sp_runtime::traits::Dispatchable; +use sp_runtime::traits::{Dispatchable, TryConvert}; use sp_std::{marker::PhantomData, vec::Vec}; use tangle_primitives::types::WrappedAccountId32; @@ -56,6 +56,8 @@ type BalanceOf = ::AccountId, >>::Balance; +type AssetIdOf = ::AssetId; + pub struct MultiAssetDelegationPrecompile(PhantomData); impl MultiAssetDelegationPrecompile @@ -65,6 +67,7 @@ where ::RuntimeOrigin: From>, Runtime::RuntimeCall: From>, BalanceOf: TryFrom + Into + solidity::Codec, + AssetIdOf: TryFrom + Into, Runtime::AccountId: From, { /// Helper method to parse SS58 address @@ -100,6 +103,10 @@ where Ok(payee) } + + fn u256_to_amount(amount: U256) -> EvmResult> { + amount.try_into().map_err(|_| revert("Invalid amount")) + } } #[precompile_utils::precompile] @@ -110,9 +117,8 @@ where ::RuntimeOrigin: From>, Runtime::RuntimeCall: From>, BalanceOf: TryFrom + Into + solidity::Codec, + AssetIdOf: TryFrom + Into, Runtime::AccountId: From, - ::AssetId: - TryFrom + Into + solidity::Codec, { #[precompile::public("joinOperators(uint256)")] fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { @@ -238,11 +244,16 @@ where #[precompile::public("deposit(uint256,uint256)")] fn deposit(handle: &mut impl PrecompileHandle, asset_id: U256, amount: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::deposit { asset_id, amount }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -250,17 +261,22 @@ where Ok(()) } - #[precompile::public("scheduleWithdraw(uint256,uint256)")] + #[precompile::public("schedule_withdraw(uint256,uint256)")] fn schedule_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, amount: U256, ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::schedule_withdraw { asset_id, amount }; @@ -280,17 +296,22 @@ where Ok(()) } - #[precompile::public("cancelWithdraw(uint256,uint256)")] + #[precompile::public("cancel_withdraw(uint256,uint256)")] fn cancel_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, amount: U256, ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::cancel_withdraw { asset_id, amount }; @@ -307,17 +328,23 @@ where amount: U256, blueprint_selection: Vec, ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Parse operator address let operator = Self::convert_to_account_id(operator)?; - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; - let blueprint_selection = DelegatorBlueprintSelection::Fixed( - blueprint_selection - .try_into() - .map_err(|_| revert("Invalid blueprint selection"))?, - ); + + // Parse blueprint selection + let blueprint_selection = DelegatorBlueprintSelection::try_from(blueprint_selection) + .map_err(|_| revert("error converting blueprint selection"))?; + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::delegate { operator, asset_id, @@ -330,19 +357,26 @@ where Ok(()) } - #[precompile::public("scheduleDelegatorUnstake(bytes32,uint256,uint256)")] + #[precompile::public("schedule_delegator_unstake(bytes32,uint256,uint256)")] fn schedule_delegator_unstake( handle: &mut impl PrecompileHandle, operator: H256, asset_id: U256, amount: U256, ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Parse operator address let operator = Self::convert_to_account_id(operator)?; - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { operator, asset_id, @@ -372,12 +406,19 @@ where asset_id: U256, amount: U256, ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let amount = Self::u256_to_amount(amount)?; + let asset_id = AssetIdOf::::try_from(asset_id) + .map_err(|_| revert("error converting to asset id"))?; + + // Get origin account. + let msg_sender = handle.context().caller; + let origin = Runtime::AddressMapping::into_account_id(msg_sender); + + // Parse operator address let operator = Self::convert_to_account_id(operator)?; - let asset_id: ::AssetId = - asset_id.try_into().map_err(|_| revert("Invalid asset id"))?; - let amount: BalanceOf = amount.try_into().map_err(|_| revert("Invalid amount"))?; + + // Build call with origin. + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { operator, asset_id, From cf47bece4d247acd8bc2b9bf04373e2be8f67bb1 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 12 Dec 2024 02:13:37 +0530 Subject: [PATCH 03/63] bump subxt --- .../evm-tracing/src/formatters/blockscout.rs | 14 ++-- .../evm-tracing/src/formatters/call_tracer.rs | 39 ++++----- client/evm-tracing/src/formatters/raw.rs | 3 +- .../src/formatters/trace_filter.rs | 28 +++---- client/evm-tracing/src/listeners/call_list.rs | 81 ++++++++----------- client/evm-tracing/src/listeners/raw.rs | 15 ++-- client/evm-tracing/src/types/serialization.rs | 4 +- client/rpc-core/txpool/src/types/content.rs | 15 ++-- client/rpc/debug/src/lib.rs | 80 ++++++++---------- client/rpc/trace/src/lib.rs | 57 ++++++------- client/rpc/txpool/src/lib.rs | 2 +- frost/frost-ristretto255/src/lib.rs | 5 +- frost/src/keys.rs | 2 +- frost/src/lib.rs | 10 +-- frost/src/round1.rs | 6 +- frost/src/scalar_mul.rs | 6 +- frost/src/signature.rs | 6 +- frost/src/signing_key.rs | 2 +- node/src/distributions/mainnet.rs | 42 +++++----- node/src/manual_seal.rs | 27 +++---- node/src/service.rs | 8 +- node/src/utils.rs | 2 +- pallets/claims/src/lib.rs | 15 ++-- pallets/claims/src/mock.rs | 3 +- pallets/claims/src/utils/mod.rs | 5 +- .../src/functions/delegate.rs | 17 ++-- .../src/functions/deposit.rs | 6 +- .../src/functions/operator.rs | 16 ++-- pallets/multi-asset-delegation/src/lib.rs | 12 +-- .../src/tests/operator.rs | 6 +- pallets/multi-asset-delegation/src/traits.rs | 6 +- pallets/services/rpc/src/lib.rs | 10 +-- pallets/services/src/functions.rs | 59 +++++++------- pallets/services/src/impls.rs | 3 +- pallets/services/src/lib.rs | 43 ++++++---- pallets/services/src/mock.rs | 12 ++- pallets/services/src/mock_evm.rs | 14 ++-- pallets/services/src/tests.rs | 11 +-- pallets/tangle-lst/benchmarking/src/inner.rs | 6 +- pallets/tangle-lst/benchmarking/src/mock.rs | 32 +++----- pallets/tangle-lst/src/lib.rs | 41 +++++----- pallets/tangle-lst/src/mock.rs | 9 +-- pallets/tangle-lst/src/tests.rs | 5 +- pallets/tangle-lst/src/tests/bonded_pool.rs | 3 +- pallets/tangle-lst/src/tests/create.rs | 4 +- pallets/tangle-lst/src/tests/update_roles.rs | 4 +- pallets/tangle-lst/src/types/bonded_pool.rs | 12 +-- pallets/tangle-lst/src/types/commission.rs | 8 +- precompiles/assets-erc20/src/lib.rs | 6 +- precompiles/assets-erc20/src/tests.rs | 4 +- precompiles/assets/src/lib.rs | 9 ++- precompiles/assets/src/mock.rs | 3 +- precompiles/balances-erc20/src/eip2612.rs | 3 +- precompiles/balances-erc20/src/lib.rs | 12 +-- precompiles/balances-erc20/src/mock.rs | 15 ++-- precompiles/balances-erc20/src/tests.rs | 4 +- precompiles/batch/src/lib.rs | 40 ++++----- precompiles/batch/src/mock.rs | 3 +- precompiles/call-permit/src/lib.rs | 7 +- precompiles/call-permit/src/mock.rs | 3 +- precompiles/multi-asset-delegation/src/lib.rs | 2 +- .../multi-asset-delegation/src/mock.rs | 3 +- .../multi-asset-delegation/src/tests.rs | 8 +- precompiles/pallet-democracy/src/lib.rs | 2 +- precompiles/pallet-democracy/src/mock.rs | 3 +- precompiles/pallet-democracy/src/tests.rs | 36 ++++----- precompiles/precompile-registry/src/lib.rs | 7 +- precompiles/precompile-registry/src/mock.rs | 3 +- precompiles/preimage/src/mock.rs | 3 +- precompiles/proxy/src/lib.rs | 25 +++--- precompiles/proxy/src/mock.rs | 5 +- precompiles/services/src/lib.rs | 19 +++-- precompiles/services/src/mock.rs | 17 ++-- precompiles/services/src/mock_evm.rs | 21 +++-- precompiles/services/src/tests.rs | 39 ++++----- precompiles/staking/src/lib.rs | 2 +- precompiles/staking/src/mock.rs | 3 +- precompiles/tangle-lst/src/lib.rs | 25 +++--- precompiles/tangle-lst/src/mock.rs | 23 +++--- .../verify-bls381-signature/src/lib.rs | 4 +- .../verify-bls381-signature/src/mock.rs | 3 +- .../src/lib.rs | 6 +- .../src/mock.rs | 3 +- .../src/lib.rs | 6 +- .../src/mock.rs | 3 +- .../verify-ecdsa-stark-signature/src/lib.rs | 8 +- .../verify-ecdsa-stark-signature/src/mock.rs | 3 +- .../verify-schnorr-signatures/src/lib.rs | 2 +- .../verify-schnorr-signatures/src/mock.rs | 3 +- precompiles/vesting/src/lib.rs | 4 +- primitives/rpc/evm-tracing-events/src/evm.rs | 20 ++--- .../rpc/evm-tracing-events/src/gasometer.rs | 20 ++--- .../rpc/evm-tracing-events/src/runtime.rs | 15 ++-- primitives/src/chain_identifier.rs | 16 ++-- primitives/src/services/field.rs | 20 +++-- primitives/src/services/mod.rs | 26 +++--- primitives/src/verifier/circom.rs | 10 +-- runtime/mainnet/src/filters.rs | 4 +- runtime/mainnet/src/frontier_evm.rs | 15 ++-- runtime/mainnet/src/lib.rs | 31 ++++--- runtime/testnet/src/filters.rs | 4 +- runtime/testnet/src/frontier_evm.rs | 6 +- runtime/testnet/src/lib.rs | 66 ++++++++------- 103 files changed, 673 insertions(+), 796 deletions(-) diff --git a/client/evm-tracing/src/formatters/blockscout.rs b/client/evm-tracing/src/formatters/blockscout.rs index fa8611bb..9efe1505 100644 --- a/client/evm-tracing/src/formatters/blockscout.rs +++ b/client/evm-tracing/src/formatters/blockscout.rs @@ -14,11 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -use crate::listeners::call_list::Listener; -use crate::types::serialization::*; -use crate::types::{ - single::{Call, TransactionTrace}, - CallResult, CallType, CreateResult, +use crate::{ + listeners::call_list::Listener, + types::{ + serialization::*, + single::{Call, TransactionTrace}, + CallResult, CallType, CreateResult, + }, }; use ethereum_types::{H160, U256}; use parity_scale_codec::{Decode, Encode}; @@ -34,7 +36,7 @@ impl super::ResponseFormatter for Formatter { if let Some(entry) = listener.entries.last() { return Some(TransactionTrace::CallList( entry.iter().map(|(_, value)| Call::Blockscout(value.clone())).collect(), - )); + )) } None } diff --git a/client/evm-tracing/src/formatters/call_tracer.rs b/client/evm-tracing/src/formatters/call_tracer.rs index b0451b0b..b72ea0c9 100644 --- a/client/evm-tracing/src/formatters/call_tracer.rs +++ b/client/evm-tracing/src/formatters/call_tracer.rs @@ -56,14 +56,13 @@ impl super::ResponseFormatter for Formatter { gas_used, trace_address: Some(trace_address.clone()), inner: match inner.clone() { - BlockscoutCallInner::Call { input, to, res, call_type } => { + BlockscoutCallInner::Call { input, to, res, call_type } => CallTracerInner::Call { call_type: match call_type { CallType::Call => "CALL".as_bytes().to_vec(), CallType::CallCode => "CALLCODE".as_bytes().to_vec(), - CallType::DelegateCall => { - "DELEGATECALL".as_bytes().to_vec() - }, + CallType::DelegateCall => + "DELEGATECALL".as_bytes().to_vec(), CallType::StaticCall => "STATICCALL".as_bytes().to_vec(), }, to, @@ -74,8 +73,7 @@ impl super::ResponseFormatter for Formatter { CallResult::Output { .. } => it.logs.clone(), CallResult::Error { .. } => Vec::new(), }, - } - }, + }, BlockscoutCallInner::Create { init, res } => CallTracerInner::Create { input: init, error: match res { @@ -89,21 +87,19 @@ impl super::ResponseFormatter for Formatter { CreateResult::Error { .. } => None, }, output: match res { - CreateResult::Success { created_contract_code, .. } => { - Some(created_contract_code) - }, + CreateResult::Success { created_contract_code, .. } => + Some(created_contract_code), CreateResult::Error { .. } => None, }, value, call_type: "CREATE".as_bytes().to_vec(), }, - BlockscoutCallInner::SelfDestruct { balance, to } => { + BlockscoutCallInner::SelfDestruct { balance, to } => CallTracerInner::SelfDestruct { value: balance, to, call_type: "SELFDESTRUCT".as_bytes().to_vec(), - } - }, + }, }, calls: Vec::new(), }) @@ -154,7 +150,7 @@ impl super::ResponseFormatter for Formatter { // // We consider an item to be `Ordering::Less` when: // - Is closer to the root or - // - Is greater than its sibling. + // - Is greater than its sibling. result.sort_by(|a, b| match (a, b) { ( Call::CallTracer(CallTracerCall { trace_address: Some(a), .. }), @@ -165,11 +161,11 @@ impl super::ResponseFormatter for Formatter { let sibling_greater_than = |a: &Vec, b: &Vec| -> bool { for (i, a_value) in a.iter().enumerate() { if a_value > &b[i] { - return true; + return true } else if a_value < &b[i] { - return false; + return false } else { - continue; + continue } } false @@ -193,11 +189,10 @@ impl super::ResponseFormatter for Formatter { ( Call::CallTracer(CallTracerCall { trace_address: Some(a), .. }), Call::CallTracer(CallTracerCall { trace_address: Some(b), .. }), - ) => { - &b[..] - == a.get(0..a.len() - 1) - .expect("non-root element while traversing trace result") - }, + ) => + &b[..] == + a.get(0..a.len() - 1) + .expect("non-root element while traversing trace result"), _ => unreachable!(), }) { // Remove `trace_address` from result. @@ -228,7 +223,7 @@ impl super::ResponseFormatter for Formatter { } } if traces.is_empty() { - return None; + return None } Some(traces) } diff --git a/client/evm-tracing/src/formatters/raw.rs b/client/evm-tracing/src/formatters/raw.rs index d3588e2f..30e35242 100644 --- a/client/evm-tracing/src/formatters/raw.rs +++ b/client/evm-tracing/src/formatters/raw.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -use crate::listeners::raw::Listener; -use crate::types::single::TransactionTrace; +use crate::{listeners::raw::Listener, types::single::TransactionTrace}; pub struct Formatter; diff --git a/client/evm-tracing/src/formatters/trace_filter.rs b/client/evm-tracing/src/formatters/trace_filter.rs index 12266cb7..f8844c8f 100644 --- a/client/evm-tracing/src/formatters/trace_filter.rs +++ b/client/evm-tracing/src/formatters/trace_filter.rs @@ -15,12 +15,15 @@ // along with Moonbeam. If not, see . use super::blockscout::BlockscoutCallInner as CallInner; -use crate::listeners::call_list::Listener; -use crate::types::{ - block::{ - TransactionTrace, TransactionTraceAction, TransactionTraceOutput, TransactionTraceResult, +use crate::{ + listeners::call_list::Listener, + types::{ + block::{ + TransactionTrace, TransactionTraceAction, TransactionTraceOutput, + TransactionTraceResult, + }, + CallResult, CreateResult, CreateType, }, - CallResult, CreateResult, CreateType, }; use ethereum_types::H256; @@ -53,12 +56,11 @@ impl super::ResponseFormatter for Formatter { // Can't be known here, must be inserted upstream. block_number: 0, output: match res { - CallResult::Output(output) => { + CallResult::Output(output) => TransactionTraceOutput::Result(TransactionTraceResult::Call { gas_used: trace.gas_used, output, - }) - }, + }), CallResult::Error(error) => TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, @@ -84,16 +86,14 @@ impl super::ResponseFormatter for Formatter { CreateResult::Success { created_contract_address_hash, created_contract_code, - } => { + } => TransactionTraceOutput::Result(TransactionTraceResult::Create { gas_used: trace.gas_used, code: created_contract_code, address: created_contract_address_hash, - }) - }, - CreateResult::Error { error } => { - TransactionTraceOutput::Error(error) - }, + }), + CreateResult::Error { error } => + TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, trace_address: trace.trace_address.clone(), diff --git a/client/evm-tracing/src/listeners/call_list.rs b/client/evm-tracing/src/listeners/call_list.rs index dac7c1fb..5ca1eb15 100644 --- a/client/evm-tracing/src/listeners/call_list.rs +++ b/client/evm-tracing/src/listeners/call_list.rs @@ -14,9 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -use crate::formatters::blockscout::BlockscoutCall as Call; -use crate::formatters::blockscout::BlockscoutCallInner as CallInner; -use crate::types::{single::Log, CallResult, CallType, ContextType, CreateResult}; +use crate::{ + formatters::blockscout::{BlockscoutCall as Call, BlockscoutCallInner as CallInner}, + types::{single::Log, CallResult, CallType, ContextType, CreateResult}, +}; use ethereum_types::{H160, U256}; use evm_tracing_events::{ runtime::{Capture, ExitError, ExitReason, ExitSucceed}, @@ -223,9 +224,9 @@ impl Listener { pub fn gasometer_event(&mut self, event: GasometerEvent) { match event { - GasometerEvent::RecordCost { snapshot, .. } - | GasometerEvent::RecordDynamicCost { snapshot, .. } - | GasometerEvent::RecordStipend { snapshot, .. } => { + GasometerEvent::RecordCost { snapshot, .. } | + GasometerEvent::RecordDynamicCost { snapshot, .. } | + GasometerEvent::RecordStipend { snapshot, .. } => { if let Some(context) = self.context_stack.last_mut() { if context.start_gas.is_none() { context.start_gas = Some(snapshot.gas()); @@ -496,13 +497,12 @@ impl Listener { // behavior (like batch precompile does) thus we simply consider this a call. self.call_type = Some(CallType::Call); }, - EvmEvent::Log { address, topics, data } => { + EvmEvent::Log { address, topics, data } => if self.with_log { if let Some(stack) = self.context_stack.last_mut() { stack.logs.push(Log { address, topics, data }); } - } - }, + }, // We ignore other kinds of message if any (new ones may be added in the future). #[allow(unreachable_patterns)] @@ -536,15 +536,13 @@ impl Listener { match context.context_type { ContextType::Call(call_type) => { let res = match &reason { - ExitReason::Succeed(ExitSucceed::Returned) => { - CallResult::Output(return_value.to_vec()) - }, + ExitReason::Succeed(ExitSucceed::Returned) => + CallResult::Output(return_value.to_vec()), ExitReason::Succeed(_) => CallResult::Output(vec![]), ExitReason::Error(error) => CallResult::Error(error_message(error)), - ExitReason::Revert(_) => { - CallResult::Error(b"execution reverted".to_vec()) - }, + ExitReason::Revert(_) => + CallResult::Error(b"execution reverted".to_vec()), ExitReason::Fatal(_) => CallResult::Error(vec![]), }; @@ -570,12 +568,10 @@ impl Listener { created_contract_address_hash: context.to, created_contract_code: return_value.to_vec(), }, - ExitReason::Error(error) => { - CreateResult::Error { error: error_message(error) } - }, - ExitReason::Revert(_) => { - CreateResult::Error { error: b"execution reverted".to_vec() } - }, + ExitReason::Error(error) => + CreateResult::Error { error: error_message(error) }, + ExitReason::Revert(_) => + CreateResult::Error { error: b"execution reverted".to_vec() }, ExitReason::Fatal(_) => CreateResult::Error { error: vec![] }, }; @@ -624,15 +620,14 @@ impl ListenerT for Listener { Event::Gasometer(gasometer_event) => self.gasometer_event(gasometer_event), Event::Runtime(runtime_event) => self.runtime_event(runtime_event), Event::Evm(evm_event) => self.evm_event(evm_event), - Event::CallListNew() => { + Event::CallListNew() => if !self.call_list_first_transaction { self.finish_transaction(); self.skip_next_context = false; self.entries.push(BTreeMap::new()); } else { self.call_list_first_transaction = false; - } - }, + }, }; } @@ -731,9 +726,8 @@ mod tests { target: H160::default(), balance: U256::zero(), }, - TestEvmEvent::Exit => { - EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() } - }, + TestEvmEvent::Exit => + EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() }, TestEvmEvent::TransactCall => EvmEvent::TransactCall { caller: H160::default(), address: H160::default(), @@ -756,9 +750,8 @@ mod tests { gas_limit: 0u64, address: H160::default(), }, - TestEvmEvent::Log => { - EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() } - }, + TestEvmEvent::Log => + EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() }, } } @@ -771,9 +764,8 @@ mod tests { stack: test_stack(), memory: test_memory(), }, - TestRuntimeEvent::StepResult => { - RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() } - }, + TestRuntimeEvent::StepResult => + RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() }, TestRuntimeEvent::SLoad => RuntimeEvent::SLoad { address: H160::default(), index: H256::default(), @@ -789,24 +781,20 @@ mod tests { fn test_emit_gasometer_event(event_type: TestGasometerEvent) -> GasometerEvent { match event_type { - TestGasometerEvent::RecordCost => { - GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() } - }, - TestGasometerEvent::RecordRefund => { - GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() } - }, - TestGasometerEvent::RecordStipend => { - GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() } - }, + TestGasometerEvent::RecordCost => + GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordRefund => + GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordStipend => + GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() }, TestGasometerEvent::RecordDynamicCost => GasometerEvent::RecordDynamicCost { gas_cost: 0u64, memory_gas: 0u64, gas_refund: 0i64, snapshot: test_snapshot(), }, - TestGasometerEvent::RecordTransaction => { - GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() } - }, + TestGasometerEvent::RecordTransaction => + GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() }, } } @@ -1094,7 +1082,8 @@ mod tests { listener.finish_transaction(); assert_eq!(listener.entries.len(), 1); // Each nested call contains 11 elements in the callstack (main + 10 subcalls). - // There are 5 main nested calls for a total of 56 elements in the callstack: 1 main + 55 nested. + // There are 5 main nested calls for a total of 56 elements in the callstack: 1 main + 55 + // nested. assert_eq!(listener.entries[0].len(), (depth * (subdepth + 1)) + 1); } diff --git a/client/evm-tracing/src/listeners/raw.rs b/client/evm-tracing/src/listeners/raw.rs index 180fd36e..2b39fe23 100644 --- a/client/evm-tracing/src/listeners/raw.rs +++ b/client/evm-tracing/src/listeners/raw.rs @@ -161,7 +161,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(memory.data.len())); if self.remaining_memory_usage.is_none() { - return; + return } Some(memory.data.clone()) @@ -176,7 +176,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(stack.data.len())); if self.remaining_memory_usage.is_none() { - return; + return } Some(stack.data.clone()) @@ -205,7 +205,7 @@ impl Listener { }); if self.remaining_memory_usage.is_none() { - return; + return } Some(context.storage_cache.clone()) @@ -243,7 +243,8 @@ impl Listener { .global_storage_changes .insert(context.address, context.storage_cache); - // Apply storage changes to parent, either updating its cache or map of changes. + // Apply storage changes to parent, either updating its cache or + // map of changes. for (address, mut storage) in context.global_storage_changes.into_iter() { @@ -276,8 +277,8 @@ impl Listener { _ => (), } }, - RuntimeEvent::SLoad { address: _, index, value } - | RuntimeEvent::SStore { address: _, index, value } => { + RuntimeEvent::SLoad { address: _, index, value } | + RuntimeEvent::SStore { address: _, index, value } => { if let Some(context) = self.context_stack.last_mut() { if !self.disable_storage { context.storage_cache.insert(index, value); @@ -294,7 +295,7 @@ impl Listener { impl ListenerT for Listener { fn event(&mut self, event: Event) { if self.remaining_memory_usage.is_none() { - return; + return } match event { diff --git a/client/evm-tracing/src/types/serialization.rs b/client/evm-tracing/src/types/serialization.rs index f786ffaf..9f31f709 100644 --- a/client/evm-tracing/src/types/serialization.rs +++ b/client/evm-tracing/src/types/serialization.rs @@ -54,7 +54,7 @@ where S: Serializer, { if let Some(bytes) = bytes.as_ref() { - return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))); + return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))) } Err(S::Error::custom("String serialize error.")) } @@ -87,7 +87,7 @@ where let d = std::str::from_utf8(&value[..]) .map_err(|_| S::Error::custom("String serialize error."))? .to_string(); - return serializer.serialize_str(&d); + return serializer.serialize_str(&d) } Err(S::Error::custom("String serialize error.")) } diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index ec98a00f..581be173 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -66,15 +66,12 @@ where impl GetT for Transaction { fn get(hash: H256, from_address: H160, txn: &EthereumTransaction) -> Self { let (nonce, action, value, gas_price, gas_limit, input) = match txn { - EthereumTransaction::Legacy(t) => { - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) - }, - EthereumTransaction::EIP2930(t) => { - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) - }, - EthereumTransaction::EIP1559(t) => { - (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()) - }, + EthereumTransaction::Legacy(t) => + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), + EthereumTransaction::EIP2930(t) => + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), + EthereumTransaction::EIP1559(t) => + (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()), }; Self { hash, diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index 09b2b932..c1878aca 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -353,15 +353,12 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => { - Ok(BlockId::Number(client.info().best_number)) - }, - RequestBlockId::Tag(RequestBlockTag::Earliest) => { - Ok(BlockId::Number(0u32.unique_saturated_into())) - }, - RequestBlockId::Tag(RequestBlockTag::Pending) => { - Err(internal_err("'pending' blocks are not supported")) - }, + RequestBlockId::Tag(RequestBlockTag::Latest) => + Ok(BlockId::Number(client.info().best_number)), + RequestBlockId::Tag(RequestBlockTag::Earliest) => + Ok(BlockId::Number(0u32.unique_saturated_into())), + RequestBlockId::Tag(RequestBlockTag::Pending) => + Err(internal_err("'pending' blocks are not supported")), RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -381,7 +378,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -398,7 +395,7 @@ where // If there are no ethereum transactions in the block return empty trace right away. if eth_tx_hashes.is_empty() { - return Ok(Response::Block(vec![])); + return Ok(Response::Block(vec![])) } // Get block extrinsics. @@ -413,7 +410,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; // Trace the block. @@ -428,7 +425,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (core)".to_string())); + return Err(internal_err("Runtime api version call failed (core)".to_string())) }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -473,11 +470,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::CallTracer => { + TracerInput::CallTracer => client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), _ => Err(internal_err("Bug: failed to resolve the tracer format.".to_string())), }?; @@ -537,7 +533,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(reference_hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(reference_hash) { Ok(Some(h)) => h, @@ -558,7 +554,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; let reference_block = overrides.current_block(reference_hash); @@ -580,7 +576,7 @@ where } else { return Err(internal_err( "Runtime api version call failed (core)".to_string(), - )); + )) }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -612,20 +608,17 @@ where // Pre-london update, legacy transactions. match transaction { ethereum::TransactionV2::Legacy(tx) => - { #[allow(deprecated)] api.trace_transaction_before_version_4( parent_block_hash, exts, tx, - ) - }, - _ => { + ), + _ => return Err(internal_err( "Bug: pre-london runtime expects legacy transactions" .to_string(), - )) - }, + )), } } }; @@ -666,11 +659,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => { + TracerInput::Blockscout => client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) @@ -688,7 +680,7 @@ where "Bug: `handle_transaction_request` does not support {:?}.", not_supported ))), - }; + } } } Err(internal_err("Runtime block call failed".to_string())) @@ -706,15 +698,12 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => { - Ok(BlockId::Number(client.info().best_number)) - }, - RequestBlockId::Tag(RequestBlockTag::Earliest) => { - Ok(BlockId::Number(0u32.unique_saturated_into())) - }, - RequestBlockId::Tag(RequestBlockTag::Pending) => { - Err(internal_err("'pending' blocks are not supported")) - }, + RequestBlockId::Tag(RequestBlockTag::Latest) => + Ok(BlockId::Number(client.info().best_number)), + RequestBlockId::Tag(RequestBlockTag::Earliest) => + Ok(BlockId::Number(0u32.unique_saturated_into())), + RequestBlockId::Tag(RequestBlockTag::Pending) => + Err(internal_err("'pending' blocks are not supported")), RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -732,7 +721,7 @@ where let api = client.runtime_api(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -747,13 +736,11 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; if trace_api_version <= 5 { - return Err(internal_err( - "debug_traceCall not supported with old runtimes".to_string(), - )); + return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())) } let TraceCallParams { @@ -808,7 +795,7 @@ where } else { return Err(internal_err( "block unavailable, cannot query gas limit".to_string(), - )); + )) } }, }; @@ -860,11 +847,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => { + TracerInput::Blockscout => client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index a62e1794..4514ce79 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -21,8 +21,8 @@ //! The implementation is composed of multiple tasks : //! - Many calls the RPC handler `Trace::filter`, communicating with the main task. //! - A main `CacheTask` managing the cache and the communication between tasks. -//! - For each traced block an async task responsible to wait for a permit, spawn a blocking -//! task and waiting for the result, then send it to the main `CacheTask`. +//! - For each traced block an async task responsible to wait for a permit, spawn a blocking task +//! and waiting for the result, then send it to the main `CacheTask`. use futures::{select, stream::FuturesUnordered, FutureExt, StreamExt}; use std::{collections::BTreeMap, future::Future, marker::PhantomData, sync::Arc, time::Duration}; @@ -100,9 +100,8 @@ where .try_into() .map_err(|_| "Block number overflow")?), Some(RequestBlockId::Tag(RequestBlockTag::Earliest)) => Ok(0), - Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => { - Err("'pending' is not supported") - }, + Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => + Err("'pending' is not supported"), Some(RequestBlockId::Hash(_)) => Err("Block hash not supported"), } } @@ -118,14 +117,14 @@ where return Err(format!( "count ({}) can't be greater than maximum ({})", count, self.max_count - )); + )) } // Build a list of all the Substrate block hashes that need to be traced. let mut block_hashes = vec![]; for block_height in block_heights { if block_height == 0 { - continue; // no traces for genesis block. + continue // no traces for genesis block. } let block_hash = self @@ -174,18 +173,15 @@ where let mut block_traces: Vec<_> = block_traces .iter() .filter(|trace| match trace.action { - block::TransactionTraceAction::Call { from, to, .. } => { - (from_address.is_empty() || from_address.contains(&from)) - && (to_address.is_empty() || to_address.contains(&to)) - }, - block::TransactionTraceAction::Create { from, .. } => { - (from_address.is_empty() || from_address.contains(&from)) - && to_address.is_empty() - }, - block::TransactionTraceAction::Suicide { address, .. } => { - (from_address.is_empty() || from_address.contains(&address)) - && to_address.is_empty() - }, + block::TransactionTraceAction::Call { from, to, .. } => + (from_address.is_empty() || from_address.contains(&from)) && + (to_address.is_empty() || to_address.contains(&to)), + block::TransactionTraceAction::Create { from, .. } => + (from_address.is_empty() || from_address.contains(&from)) && + to_address.is_empty(), + block::TransactionTraceAction::Suicide { address, .. } => + (from_address.is_empty() || from_address.contains(&address)) && + to_address.is_empty(), }) .cloned() .collect(); @@ -211,11 +207,11 @@ where "the amount of traces goes over the maximum ({}), please use 'after' \ and 'count' in your request", self.max_count - )); + )) } traces = traces.into_iter().take(count).collect(); - break; + break } } } @@ -595,9 +591,9 @@ where /// Handle a request to get the traces of the provided block. /// - If the result is stored in the cache, it sends it immediatly. - /// - If the block is currently being pooled, it is added in this block cache waiting list, - /// and all requests concerning this block will be satisfied when the tracing for this block - /// is finished. + /// - If the block is currently being pooled, it is added in this block cache waiting list, and + /// all requests concerning this block will be satisfied when the tracing for this block is + /// finished. /// - If this block is missing from the cache, it means no batch asked for it. All requested /// blocks should be contained in a batch beforehand, and thus an error is returned. #[instrument(skip(self))] @@ -652,8 +648,8 @@ where // We remove early the block cache if this batch is the last // pooling this block. if let Some(block_cache) = self.cached_blocks.get_mut(block) { - if block_cache.active_batch_count == 1 - && matches!( + if block_cache.active_batch_count == 1 && + matches!( block_cache.state, CacheBlockState::Pooled { started: false, .. } ) { @@ -760,12 +756,11 @@ where overrides.current_transaction_statuses(substrate_hash), ) { (Some(a), Some(b)) => (a, b), - _ => { + _ => return Err(format!( "Failed to get Ethereum block data for Substrate block {}", substrate_hash - )) - }, + )), }; let eth_block_hash = eth_block.header.hash(); @@ -786,7 +781,7 @@ where { api_version } else { - return Err("Runtime api version call failed (trace)".to_string()); + return Err("Runtime api version call failed (trace)".to_string()) }; // Trace the block. @@ -800,7 +795,7 @@ where { api_version } else { - return Err("Runtime api version call failed (core)".to_string()); + return Err("Runtime api version call failed (core)".to_string()) }; // Initialize block: calls the "on_initialize" hook on every pallet diff --git a/client/rpc/txpool/src/lib.rs b/client/rpc/txpool/src/lib.rs index 101050c5..c00ad935 100644 --- a/client/rpc/txpool/src/lib.rs +++ b/client/rpc/txpool/src/lib.rs @@ -74,7 +74,7 @@ where if let Ok(Some(api_version)) = api.api_version::>(best_block) { api_version } else { - return Err(internal_err("failed to retrieve Runtime Api version".to_string())); + return Err(internal_err("failed to retrieve Runtime Api version".to_string())) }; let ethereum_txns: TxPoolResponse = if api_version == 1 { #[allow(deprecated)] diff --git a/frost/frost-ristretto255/src/lib.rs b/frost/frost-ristretto255/src/lib.rs index a4d955fc..a3322ef4 100644 --- a/frost/frost-ristretto255/src/lib.rs +++ b/frost/frost-ristretto255/src/lib.rs @@ -102,13 +102,12 @@ impl Group for RistrettoGroup { .map_err(|_| GroupError::MalformedElement)? .decompress() { - Some(point) => { + Some(point) => if point == RistrettoPoint::identity() { Err(GroupError::InvalidIdentityElement) } else { Ok(WrappedRistrettoPoint(point)) - } - }, + }, None => Err(GroupError::MalformedElement), } } diff --git a/frost/src/keys.rs b/frost/src/keys.rs index 1c2656da..5069d93f 100644 --- a/frost/src/keys.rs +++ b/frost/src/keys.rs @@ -384,7 +384,7 @@ where let result = evaluate_vss(self.identifier, &self.commitment); if !(f_result == result) { - return Err(Error::InvalidSecretShare); + return Err(Error::InvalidSecretShare) } Ok((VerifyingShare(result), self.commitment.verifying_key()?)) diff --git a/frost/src/lib.rs b/frost/src/lib.rs index f2e10fcd..2e0d7d99 100644 --- a/frost/src/lib.rs +++ b/frost/src/lib.rs @@ -66,7 +66,7 @@ pub fn random_nonzero(rng: &mut R) -> Sc let scalar = <::Field>::random(rng); if scalar != <::Field>::zero() { - return scalar; + return scalar } } } @@ -203,7 +203,7 @@ fn compute_lagrange_coefficient( x_i: Identifier, ) -> Result, Error> { if x_set.is_empty() { - return Err(Error::IncorrectNumberOfIdentifiers); + return Err(Error::IncorrectNumberOfIdentifiers) } let mut num = <::Field>::one(); let mut den = <::Field>::one(); @@ -213,7 +213,7 @@ fn compute_lagrange_coefficient( for x_j in x_set.iter() { if x_i == *x_j { x_i_found = true; - continue; + continue } if let Some(x) = x { @@ -226,7 +226,7 @@ fn compute_lagrange_coefficient( } } if !x_i_found { - return Err(Error::UnknownIdentifier); + return Err(Error::UnknownIdentifier) } Ok(num * <::Field>::invert(&den).map_err(|_| Error::DuplicatedIdentifier)?) @@ -396,7 +396,7 @@ where // The following check prevents a party from accidentally revealing their share. // Note that the '&&' operator would be sufficient. if identity == commitment.binding.0 || identity == commitment.hiding.0 { - return Err(Error::IdentityCommitment); + return Err(Error::IdentityCommitment) } let binding_factor = diff --git a/frost/src/round1.rs b/frost/src/round1.rs index 54039c00..52f7d61a 100644 --- a/frost/src/round1.rs +++ b/frost/src/round1.rs @@ -106,9 +106,9 @@ where /// Checks if the commitments are valid. pub fn is_valid(&self) -> bool { - element_is_valid::(&self.hiding.0) - && element_is_valid::(&self.binding.0) - && self.hiding.0 != self.binding.0 + element_is_valid::(&self.hiding.0) && + element_is_valid::(&self.binding.0) && + self.hiding.0 != self.binding.0 } } diff --git a/frost/src/scalar_mul.rs b/frost/src/scalar_mul.rs index 8211ac83..a80b98b3 100644 --- a/frost/src/scalar_mul.rs +++ b/frost/src/scalar_mul.rs @@ -118,7 +118,7 @@ where // If carry == 1 and window & 1 == 0, then bit_buf & 1 == 1 so the next carry should // be 1 pos += 1; - continue; + continue } if window < width / 2 { @@ -197,14 +197,14 @@ where .collect::>>()?; if nafs.len() != lookup_tables.len() { - return None; + return None } let mut r = ::identity(); // All NAFs will have the same size, so get it from the first if nafs.is_empty() { - return Some(r); + return Some(r) } let naf_length = nafs[0].len(); diff --git a/frost/src/signature.rs b/frost/src/signature.rs index 5a1f89be..c7f059e5 100644 --- a/frost/src/signature.rs +++ b/frost/src/signature.rs @@ -210,10 +210,10 @@ where lambda_i: Scalar, challenge: &Challenge, ) -> Result<(), Error> { - if (::generator() * self.share) - != (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) + if (::generator() * self.share) != + (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) { - return Err(Error::InvalidSignatureShare); + return Err(Error::InvalidSignatureShare) } Ok(()) diff --git a/frost/src/signing_key.rs b/frost/src/signing_key.rs index 758600f5..9307d5ed 100644 --- a/frost/src/signing_key.rs +++ b/frost/src/signing_key.rs @@ -44,7 +44,7 @@ where <::Field as Field>::deserialize(&bytes).map_err(Error::from)?; if scalar == <::Field as Field>::zero() { - return Err(Error::MalformedSigningKey); + return Err(Error::MalformedSigningKey) } Ok(Self { scalar }) diff --git a/node/src/distributions/mainnet.rs b/node/src/distributions/mainnet.rs index b11cd735..d827fb98 100644 --- a/node/src/distributions/mainnet.rs +++ b/node/src/distributions/mainnet.rs @@ -44,7 +44,7 @@ fn read_contents_to_substrate_accounts(path_str: &str) -> BTreeMap BTreeMap BTreeMap Result<(), S // Ensure key is present if !ensure_keytype_exists_in_keystore(key_type, key_store.clone()) { println!("{key_type:?} key not found!"); - return Err("Key not found!".to_string()); + return Err("Key not found!".to_string()) } } diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 161de15d..40964208 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -94,16 +94,14 @@ impl StatementKind { /// Convert this to the (English) statement it represents. fn to_text(self) -> &'static [u8] { match self { - StatementKind::Regular => { + StatementKind::Regular => &b"I hereby agree to the terms of the statement whose sha2256sum is \ 5627de05cfe235cd4ffa0d6375c8a5278b89cc9b9e75622fa2039f4d1b43dadf. (This may be found at the URL: \ - https://statement.tangle.tools/airdrop-statement.html)"[..] - }, - StatementKind::Safe => { + https://statement.tangle.tools/airdrop-statement.html)"[..], + StatementKind::Safe => &b"I hereby agree to the terms of the statement whose sha2256sum is \ 7eae145b00c1912c8b01674df5df4ad9abcf6d18ea3f33d27eb6897a762f4273. (This may be found at the URL: \ - https://statement.tangle.tools/safe-claim-statement)"[..] - }, + https://statement.tangle.tools/safe-claim-statement)"[..], } } } @@ -641,10 +639,9 @@ impl Pallet { statement: Vec, ) -> Result> { let signer = match signature { - MultiAddressSignature::EVM(ethereum_signature) => { + MultiAddressSignature::EVM(ethereum_signature) => Self::eth_recover(ðereum_signature, &data, &statement[..]) - .ok_or(Error::::InvalidEthereumSignature)? - }, + .ok_or(Error::::InvalidEthereumSignature)?, MultiAddressSignature::Native(sr25519_signature) => { ensure!(!signer.is_none(), Error::::InvalidNativeAccount); Self::sr25519_recover(signer.unwrap(), &sr25519_signature, &data, &statement[..]) diff --git a/pallets/claims/src/mock.rs b/pallets/claims/src/mock.rs index 3949bf55..4cedf8ad 100644 --- a/pallets/claims/src/mock.rs +++ b/pallets/claims/src/mock.rs @@ -6,9 +6,8 @@ use sp_std::convert::TryFrom; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use crate::{pallet as pallet_airdrop_claims, sr25519_utils::sub, tests::get_bounded_vec}; -use frame_support::derive_impl; use frame_support::{ - ord_parameter_types, parameter_types, + derive_impl, ord_parameter_types, parameter_types, traits::{OnFinalize, OnInitialize, WithdrawReasons}, }; use pallet_balances; diff --git a/pallets/claims/src/utils/mod.rs b/pallets/claims/src/utils/mod.rs index a387457f..f2559685 100644 --- a/pallets/claims/src/utils/mod.rs +++ b/pallets/claims/src/utils/mod.rs @@ -45,9 +45,8 @@ impl Hash for MultiAddress { impl MultiAddress { pub fn to_account_id_32(&self) -> AccountId32 { match self { - MultiAddress::EVM(ethereum_address) => { - HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)) - }, + MultiAddress::EVM(ethereum_address) => + HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)), MultiAddress::Native(substrate_address) => substrate_address.clone(), } } diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index e2f750f5..c3c79ee1 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,12 +15,15 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::fungibles::Mutate; -use frame_support::traits::tokens::Preservation; -use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Get}; -use sp_runtime::traits::{CheckedSub, Zero}; -use sp_runtime::DispatchError; -use sp_runtime::Percent; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{fungibles::Mutate, tokens::Preservation, Get}, +}; +use sp_runtime::{ + traits::{CheckedSub, Zero}, + DispatchError, Percent, +}; use sp_std::vec::Vec; use tangle_primitives::BlueprintId; @@ -118,7 +121,7 @@ impl Pallet { // Update storage Operators::::insert(&operator, operator_metadata); } else { - return Err(Error::::NotAnOperator.into()); + return Err(Error::::NotAnOperator.into()) } Ok(()) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 86e40d92..0605ece7 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -15,11 +15,11 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::fungibles::Mutate; -use frame_support::{ensure, pallet_prelude::DispatchResult}; use frame_support::{ + ensure, + pallet_prelude::DispatchResult, sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, - traits::{tokens::Preservation, Get}, + traits::{fungibles::Mutate, tokens::Preservation, Get}, }; impl Pallet { diff --git a/pallets/multi-asset-delegation/src/functions/operator.rs b/pallets/multi-asset-delegation/src/functions/operator.rs index 1338b083..c193b4ee 100644 --- a/pallets/multi-asset-delegation/src/functions/operator.rs +++ b/pallets/multi-asset-delegation/src/functions/operator.rs @@ -17,19 +17,17 @@ /// Functions for the pallet. use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::Currency; -use frame_support::traits::ExistenceRequirement; -use frame_support::BoundedVec; use frame_support::{ ensure, pallet_prelude::DispatchResult, - traits::{Get, ReservableCurrency}, + traits::{Currency, ExistenceRequirement, Get, ReservableCurrency}, + BoundedVec, }; -use sp_runtime::traits::{CheckedAdd, CheckedSub}; -use sp_runtime::DispatchError; -use sp_runtime::Percent; -use tangle_primitives::BlueprintId; -use tangle_primitives::ServiceManager; +use sp_runtime::{ + traits::{CheckedAdd, CheckedSub}, + DispatchError, Percent, +}; +use tangle_primitives::{BlueprintId, ServiceManager}; impl Pallet { /// Handles the deposit of stake amount and creation of an operator. diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 3fc9aecb..de5b66c8 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -79,19 +79,19 @@ pub mod pallet { use crate::types::*; use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction}; - use frame_support::traits::fungibles::Inspect; use frame_support::{ pallet_prelude::*, - traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, + traits::{ + fungibles::Inspect, tokens::fungibles, Currency, Get, LockableCurrency, + ReservableCurrency, + }, PalletId, }; use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; - use sp_std::vec::Vec; - use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; - use tangle_primitives::BlueprintId; - use tangle_primitives::{traits::ServiceManager, RoundIndex}; + use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; + use tangle_primitives::{traits::ServiceManager, BlueprintId, RoundIndex}; /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 72c33e05..e4332d03 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -14,8 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::types::DelegatorBlueprintSelection::Fixed; -use crate::{types::OperatorStatus, CurrentRound, Error}; +use crate::{ + types::{DelegatorBlueprintSelection::Fixed, OperatorStatus}, + CurrentRound, Error, +}; use frame_support::{assert_noop, assert_ok}; use sp_runtime::Percent; diff --git a/pallets/multi-asset-delegation/src/traits.rs b/pallets/multi-asset-delegation/src/traits.rs index 2375ece5..973b3ec5 100644 --- a/pallets/multi-asset-delegation/src/traits.rs +++ b/pallets/multi-asset-delegation/src/traits.rs @@ -15,11 +15,9 @@ // along with Tangle. If not, see . use super::*; use crate::types::{BalanceOf, OperatorStatus}; -use sp_runtime::traits::Zero; -use sp_runtime::Percent; +use sp_runtime::{traits::Zero, Percent}; use sp_std::prelude::*; -use tangle_primitives::BlueprintId; -use tangle_primitives::{traits::MultiAssetDelegationInfo, RoundIndex}; +use tangle_primitives::{traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex}; impl MultiAssetDelegationInfo> for crate::Pallet { type AssetId = T::AssetId; diff --git a/pallets/services/rpc/src/lib.rs b/pallets/services/rpc/src/lib.rs index e505a3a1..5798ecae 100644 --- a/pallets/services/rpc/src/lib.rs +++ b/pallets/services/rpc/src/lib.rs @@ -113,12 +113,10 @@ impl From for i32 { fn custom_error_into_rpc_err(err: Error) -> ErrorObjectOwned { match err { - Error::RuntimeError(e) => { - ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))) - }, - Error::DecodeError => { - ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")) - }, + Error::RuntimeError(e) => + ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))), + Error::DecodeError => + ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")), Error::CustomDispatchError(msg) => ErrorObject::owned(3, "Dispatch error", Some(msg)), } } diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index 26d6944e..88a3af08 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -77,9 +77,8 @@ impl Pallet { pub fn mbsm_address_of(blueprint: &ServiceBlueprint) -> Result> { match blueprint.master_manager_revision { MasterBlueprintServiceManagerRevision::Specific(rev) => Self::mbsm_address(rev), - MasterBlueprintServiceManagerRevision::Latest => { - Self::mbsm_address(Self::mbsm_latest_revision()) - }, + MasterBlueprintServiceManagerRevision::Latest => + Self::mbsm_address(Self::mbsm_latest_revision()), other => unimplemented!("Got unexpected case for {:?}", other), } } @@ -95,8 +94,8 @@ impl Pallet { /// * `owner` - The owner of the blueprint. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating - /// whether the blueprint creation is allowed and the weight of the operation. + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating whether the blueprint creation is allowed and the weight of the operation. pub fn on_blueprint_created_hook( blueprint: &ServiceBlueprint, blueprint_id: u64, @@ -190,8 +189,8 @@ impl Pallet { /// * `value` - The value to be sent with the call. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating - /// whether the registration is allowed and the weight of the operation. + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating whether the registration is allowed and the weight of the operation. pub fn on_register_hook( blueprint: &ServiceBlueprint, blueprint_id: u64, @@ -241,7 +240,8 @@ impl Pallet { /// * `prefrences` - The operator preferences. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the unregistration is allowed and the weight of the operation. pub fn on_unregister_hook( blueprint: &ServiceBlueprint, @@ -281,7 +281,8 @@ impl Pallet { /// /// # Returns /// - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the price targets update is allowed and the weight of the operation. pub fn on_update_price_targets( blueprint: &ServiceBlueprint, @@ -323,7 +324,8 @@ impl Pallet { /// * `restaking_percent` - The restaking percent. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the approve is allowed and the weight of the operation. pub fn on_approve_hook( blueprint: &ServiceBlueprint, @@ -380,7 +382,8 @@ impl Pallet { /// * `request_id` - The request id. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the reject is allowed and the weight of the operation. pub fn on_reject_hook( blueprint: &ServiceBlueprint, @@ -437,8 +440,8 @@ impl Pallet { /// * `value` - The value to be sent with the call. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating - /// whether the request is allowed and the weight of the operation. + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating whether the request is allowed and the weight of the operation. pub fn on_request_hook( blueprint: &ServiceBlueprint, blueprint_id: u64, @@ -519,8 +522,8 @@ impl Pallet { ) } - /// Hook to be called when a service is initialized. This function will call the `onServiceInitialized` - /// function of the service blueprint manager contract. + /// Hook to be called when a service is initialized. This function will call the + /// `onServiceInitialized` function of the service blueprint manager contract. /// /// # Arguments /// * `blueprint` - The service blueprint. @@ -533,7 +536,8 @@ impl Pallet { /// * `ttl` - The time to live. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the request is allowed and the weight of the operation. pub fn on_service_init_hook( blueprint: &ServiceBlueprint, @@ -611,8 +615,8 @@ impl Pallet { ) } - /// Hook to be called when a service is terminated. This function will call the `onServiceTermination` - /// function of the service blueprint manager contract. + /// Hook to be called when a service is terminated. This function will call the + /// `onServiceTermination` function of the service blueprint manager contract. /// /// # Arguments /// * `blueprint` - The service blueprint. @@ -621,7 +625,8 @@ impl Pallet { /// * `owner` - The owner of the service. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating /// whether the request is allowed and the weight of the operation. pub fn on_service_termination_hook( blueprint: &ServiceBlueprint, @@ -678,8 +683,8 @@ impl Pallet { /// * `inputs` - The input fields. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating - /// whether the job call is allowed and the weight of the operation. + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating whether the job call is allowed and the weight of the operation. pub fn on_job_call_hook( blueprint: &ServiceBlueprint, blueprint_id: u64, @@ -751,8 +756,8 @@ impl Pallet { /// * `outputs` - The output fields. /// /// # Returns - /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean indicating - /// whether the job result is allowed and the weight of the operation. + /// * `Result<(bool, Weight), DispatchErrorWithPostInfo>` - A tuple containing a boolean + /// indicating whether the job result is allowed and the weight of the operation. pub fn on_job_result_hook( blueprint: &ServiceBlueprint, blueprint_id: u64, @@ -827,8 +832,8 @@ impl Pallet { /// * `service` - The service. /// /// # Returns - /// * `Result<(Option, Weight), DispatchErrorWithPostInfo>` - A tuple containing the - /// slashing origin account id (if any) and the weight of the operation. + /// * `Result<(Option, Weight), DispatchErrorWithPostInfo>` - A tuple containing + /// the slashing origin account id (if any) and the weight of the operation. pub fn query_slashing_origin( service: &Service, T::AssetId>, ) -> Result<(Option, Weight), DispatchErrorWithPostInfo> { @@ -893,8 +898,8 @@ impl Pallet { /// * `service` - The service. /// /// # Returns - /// * `Result<(Option, Weight), DispatchErrorWithPostInfo>` - A tuple containing the - /// dispute origin account id (if any) and the weight of the operation. + /// * `Result<(Option, Weight), DispatchErrorWithPostInfo>` - A tuple containing + /// the dispute origin account id (if any) and the weight of the operation. pub fn query_dispute_origin( service: &Service, T::AssetId>, ) -> Result<(Option, Weight), DispatchErrorWithPostInfo> { diff --git a/pallets/services/src/impls.rs b/pallets/services/src/impls.rs index 4423b785..69297d07 100644 --- a/pallets/services/src/impls.rs +++ b/pallets/services/src/impls.rs @@ -5,8 +5,7 @@ use alloc::vec::Vec; use sp_std::vec; #[cfg(feature = "std")] use std::vec::Vec; -use tangle_primitives::BlueprintId; -use tangle_primitives::{services::Constraints, traits::ServiceManager}; +use tangle_primitives::{services::Constraints, traits::ServiceManager, BlueprintId}; impl traits::EvmRunner for () { type Error = crate::Error; diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index e6fe8cf4..362f5202 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -58,15 +58,23 @@ pub use impls::BenchmarkingOperatorDelegationManager; #[frame_support::pallet(dev_mode)] pub mod module { use super::*; - use frame_support::dispatch::PostDispatchInfo; - use frame_support::traits::fungibles::{Inspect, Mutate}; - use frame_support::traits::tokens::Preservation; + use frame_support::{ + dispatch::PostDispatchInfo, + traits::{ + fungibles::{Inspect, Mutate}, + tokens::Preservation, + }, + }; use sp_core::H160; - use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero}; - use sp_runtime::Percent; + use sp_runtime::{ + traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero}, + Percent, + }; use sp_std::vec::Vec; - use tangle_primitives::services::MasterBlueprintServiceManagerRevision; - use tangle_primitives::{services::*, MultiAssetDelegationInfo}; + use tangle_primitives::{ + services::{MasterBlueprintServiceManagerRevision, *}, + MultiAssetDelegationInfo, + }; use types::*; #[pallet::config] @@ -201,7 +209,8 @@ pub mod module { impl Hooks> for Pallet { fn integrity_test() { // Ensure that the pallet's configuration is valid. - // 1. Make sure that pallet's associated AccountId value maps correctly to the EVM address. + // 1. Make sure that pallet's associated AccountId value maps correctly to the EVM + // address. let account_id = T::EvmAddressMapping::into_account_id(Self::address()); assert_eq!(account_id, Self::account_id(), "Services: AccountId mapping is incorrect."); } @@ -1031,10 +1040,10 @@ pub mod module { .operators_with_approval_state .into_iter() .filter_map(|(v, state)| match state { - ApprovalState::Approved { restaking_percent } => { - Some((v, restaking_percent)) - }, - // N.B: this should not happen, as all operators are approved and checked above. + ApprovalState::Approved { restaking_percent } => + Some((v, restaking_percent)), + // N.B: this should not happen, as all operators are approved and checked + // above. _ => None, }) .collect::>(); @@ -1275,11 +1284,12 @@ pub mod module { Ok(PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }) } - /// Slash an operator (offender) for a service id with a given percent of their exposed stake for that service. + /// Slash an operator (offender) for a service id with a given percent of their exposed + /// stake for that service. /// /// The caller needs to be an authorized Slash Origin for this service. - /// Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash - /// by another entity. + /// Note that this does not apply the slash directly, but instead schedules a deferred call + /// to apply the slash by another entity. pub fn slash( origin: OriginFor, offender: T::AccountId, @@ -1341,7 +1351,8 @@ pub mod module { /// Dispute an [UnappliedSlash] for a given era and index. /// - /// The caller needs to be an authorized Dispute Origin for the service in the [UnappliedSlash]. + /// The caller needs to be an authorized Dispute Origin for the service in the + /// [UnappliedSlash]. pub fn dispute( origin: OriginFor, #[pallet::compact] era: u32, diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 44d97c26..8dff9aa1 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -22,10 +22,9 @@ use frame_election_provider_support::{ onchain, SequentialPhragmen, }; use frame_support::{ - construct_runtime, parameter_types, - traits::{ConstU128, ConstU32, OneSessionHandler}, + construct_runtime, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, }; -use frame_support::{derive_impl, traits::AsEnsureOriginWithArg}; use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; @@ -280,7 +279,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false; + return false } true } @@ -759,11 +758,10 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => { + (left_val, right_val) => if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - } - }, + }, }; } } diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index 8fcccabd..a8c57b0c 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -163,7 +163,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation as OnChargeEVMTransaction< @@ -180,7 +180,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation as OnChargeEVMTransaction< @@ -266,9 +266,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -278,9 +277,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), _ => None, } } diff --git a/pallets/services/src/tests.rs b/pallets/services/src/tests.rs index d46ad41f..3a40240c 100644 --- a/pallets/services/src/tests.rs +++ b/pallets/services/src/tests.rs @@ -18,11 +18,9 @@ use crate::types::ConstraintsOf; use super::*; use frame_support::{assert_err, assert_ok}; use mock::*; -use sp_core::U256; -use sp_core::{bounded_vec, ecdsa, ByteArray}; +use sp_core::{bounded_vec, ecdsa, ByteArray, U256}; use sp_runtime::{KeyTypeId, Percent}; -use tangle_primitives::services::*; -use tangle_primitives::MultiAssetDelegationInfo; +use tangle_primitives::{services::*, MultiAssetDelegationInfo}; const ALICE: u8 = 1; const BOB: u8 = 2; @@ -61,9 +59,8 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => { - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } - }, + MachineKind::Small => + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, } } diff --git a/pallets/tangle-lst/benchmarking/src/inner.rs b/pallets/tangle-lst/benchmarking/src/inner.rs index 88d70bac..2487891f 100644 --- a/pallets/tangle-lst/benchmarking/src/inner.rs +++ b/pallets/tangle-lst/benchmarking/src/inner.rs @@ -3,13 +3,12 @@ use alloc::{vec, vec::Vec}; use frame_benchmarking::v1::{account, whitelist_account}; use frame_election_provider_support::SortedListProvider; -use frame_support::traits::Currency; use frame_support::{ assert_ok, ensure, traits::{ fungible::{Inspect, Mutate, Unbalanced}, tokens::Preservation, - Get, Imbalance, + Currency, Get, Imbalance, }, }; use frame_system::RawOrigin as RuntimeOrigin; @@ -24,8 +23,7 @@ use sp_runtime::{ traits::{Bounded, StaticLookup, Zero}, Perbill, }; -use sp_staking::EraIndex; -use sp_staking::StakingInterface; +use sp_staking::{EraIndex, StakingInterface}; // `frame_benchmarking::benchmarks!` macro needs this use pallet_tangle_lst::Call; diff --git a/pallets/tangle-lst/benchmarking/src/mock.rs b/pallets/tangle-lst/benchmarking/src/mock.rs index f7116ecb..375a7269 100644 --- a/pallets/tangle-lst/benchmarking/src/mock.rs +++ b/pallets/tangle-lst/benchmarking/src/mock.rs @@ -2,30 +2,20 @@ use super::*; use frame_election_provider_support::VoteWeight; -use frame_support::traits::AsEnsureOriginWithArg; -use frame_support::traits::Hooks; -use frame_support::traits::OnFinalize; -use frame_support::{assert_ok, derive_impl, parameter_types, PalletId}; +use frame_support::{ + assert_ok, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, Hooks, OnFinalize}, + PalletId, +}; use frame_system::RawOrigin; -use pallet_tangle_lst::BondedPools; -use pallet_tangle_lst::Config; -use pallet_tangle_lst::Event; -use pallet_tangle_lst::LastPoolId; -use pallet_tangle_lst::PoolId; -use pallet_tangle_lst::PoolState; +use pallet_tangle_lst::{BondedPools, Config, Event, LastPoolId, PoolId, PoolState}; use sp_core::U256; -use sp_runtime::traits::ConstU128; -use sp_runtime::traits::ConstU32; -use sp_runtime::traits::ConstU64; -use sp_runtime::traits::Convert; -use sp_runtime::traits::Zero; -use sp_runtime::DispatchError; -use sp_runtime::DispatchResult; -use sp_runtime::Perbill; -use sp_runtime::{BuildStorage, FixedU128}; +use sp_runtime::{ + traits::{ConstU128, ConstU32, ConstU64, Convert, Zero}, + BuildStorage, DispatchError, DispatchResult, FixedU128, Perbill, +}; use sp_runtime_interface::sp_tracing; -use sp_staking::EraIndex; -use sp_staking::{OnStakingUpdate, Stake}; +use sp_staking::{EraIndex, OnStakingUpdate, Stake}; use sp_std::collections::btree_map::BTreeMap; pub type BlockNumber = u64; diff --git a/pallets/tangle-lst/src/lib.rs b/pallets/tangle-lst/src/lib.rs index 317d5ffc..028e5c54 100644 --- a/pallets/tangle-lst/src/lib.rs +++ b/pallets/tangle-lst/src/lib.rs @@ -107,34 +107,29 @@ #![cfg_attr(not(feature = "std"), no_std)] use codec::Codec; -use frame_support::traits::fungibles; -use frame_support::traits::fungibles::Create; -use frame_support::traits::fungibles::Inspect as FungiblesInspect; -use frame_support::traits::fungibles::Mutate as FungiblesMutate; -use frame_support::traits::tokens::Precision; -use frame_support::traits::tokens::Preservation; -use frame_support::traits::Currency; -use frame_support::traits::ExistenceRequirement; -use frame_support::traits::LockableCurrency; -use frame_support::traits::ReservableCurrency; use frame_support::{ defensive, defensive_assert, ensure, pallet_prelude::{MaxEncodedLen, *}, storage::bounded_btree_map::BoundedBTreeMap, traits::{ - tokens::Fortitude, Defensive, DefensiveOption, DefensiveResult, DefensiveSaturating, Get, + fungibles, + fungibles::{Create, Inspect as FungiblesInspect, Mutate as FungiblesMutate}, + tokens::{Fortitude, Precision, Preservation}, + Currency, Defensive, DefensiveOption, DefensiveResult, DefensiveSaturating, + ExistenceRequirement, Get, LockableCurrency, ReservableCurrency, }, DefaultNoBound, PalletError, }; use frame_system::pallet_prelude::BlockNumberFor; use scale_info::TypeInfo; use sp_core::U256; -use sp_runtime::traits::AccountIdConversion; -use sp_runtime::traits::{ - AtLeast32BitUnsigned, Bounded, CheckedAdd, Convert, Saturating, StaticLookup, Zero, +use sp_runtime::{ + traits::{ + AccountIdConversion, AtLeast32BitUnsigned, Bounded, CheckedAdd, Convert, Saturating, + StaticLookup, Zero, + }, + FixedPointNumber, Perbill, }; -use sp_runtime::FixedPointNumber; -use sp_runtime::Perbill; use sp_staking::{EraIndex, StakingInterface}; use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, ops::Div, vec::Vec}; @@ -849,7 +844,7 @@ pub mod pallet { let pool_id = member.get_by_pool_id(current_era, pool_id); if pool_id.is_none() { - return Err(Error::::PoolNotFound.into()); + return Err(Error::::PoolNotFound.into()) } // checked above @@ -1511,7 +1506,7 @@ impl Pallet { let balance = T::U256ToBalance::convert; if current_balance.is_zero() || current_points.is_zero() || points.is_zero() { // There is nothing to unbond - return Zero::zero(); + return Zero::zero() } // Equivalent of (current_balance / current_points) * points @@ -1539,7 +1534,8 @@ impl Pallet { let bouncer = T::Lookup::lookup(bouncer)?; // ensure that pool token can be created - // if this fails, it means that the pool token already exists or the token counter needs to be incremented correctly + // if this fails, it means that the pool token already exists or the token counter needs to + // be incremented correctly ensure!( T::Fungibles::total_issuance(pool_id.into()) == 0_u32.into(), Error::::PoolTokenCreationFailed @@ -1618,9 +1614,8 @@ impl Pallet { bonded_pool.ok_to_join()?; let (_points_issued, bonded) = match extra { - BondExtra::FreeBalance(amount) => { - (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount) - }, + BondExtra::FreeBalance(amount) => + (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount), }; bonded_pool.ok_to_be_open()?; @@ -1686,7 +1681,7 @@ impl Pallet { let min_balance = T::Currency::minimum_balance(); if pre_frozen_balance == min_balance { - return Err(Error::::NothingToAdjust.into()); + return Err(Error::::NothingToAdjust.into()) } // Update frozen amount with current ED. diff --git a/pallets/tangle-lst/src/mock.rs b/pallets/tangle-lst/src/mock.rs index 95e6f629..eba18dd4 100644 --- a/pallets/tangle-lst/src/mock.rs +++ b/pallets/tangle-lst/src/mock.rs @@ -2,12 +2,11 @@ use super::*; use crate::{self as pallet_lst}; -use frame_support::traits::AsEnsureOriginWithArg; -use frame_support::{assert_ok, derive_impl, parameter_types, PalletId}; +use frame_support::{ + assert_ok, derive_impl, parameter_types, traits::AsEnsureOriginWithArg, PalletId, +}; use frame_system::RawOrigin; -use sp_runtime::traits::ConstU128; -use sp_runtime::Perbill; -use sp_runtime::{BuildStorage, FixedU128}; +use sp_runtime::{traits::ConstU128, BuildStorage, FixedU128, Perbill}; use sp_staking::{OnStakingUpdate, Stake}; pub type BlockNumber = u64; diff --git a/pallets/tangle-lst/src/tests.rs b/pallets/tangle-lst/src/tests.rs index d567b1f8..5309c2d9 100644 --- a/pallets/tangle-lst/src/tests.rs +++ b/pallets/tangle-lst/src/tests.rs @@ -16,7 +16,10 @@ // the License. use super::*; -use crate::{mock::Currency, mock::*, Event}; +use crate::{ + mock::{Currency, *}, + Event, +}; use frame_support::traits::Currency as CurrencyT; mod bond_extra; diff --git a/pallets/tangle-lst/src/tests/bonded_pool.rs b/pallets/tangle-lst/src/tests/bonded_pool.rs index 4edb9585..13325ca9 100644 --- a/pallets/tangle-lst/src/tests/bonded_pool.rs +++ b/pallets/tangle-lst/src/tests/bonded_pool.rs @@ -1,7 +1,6 @@ use super::*; use crate::mock::Currency; -use frame_support::traits::Currency as CurrencyT; -use frame_support::{assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok, traits::Currency as CurrencyT}; #[test] fn test_setup_works() { diff --git a/pallets/tangle-lst/src/tests/create.rs b/pallets/tangle-lst/src/tests/create.rs index 7779dffc..99ee9d94 100644 --- a/pallets/tangle-lst/src/tests/create.rs +++ b/pallets/tangle-lst/src/tests/create.rs @@ -1,7 +1,5 @@ use super::*; -use frame_support::assert_err; -use frame_support::assert_noop; -use frame_support::assert_ok; +use frame_support::{assert_err, assert_noop, assert_ok}; #[test] fn create_works() { diff --git a/pallets/tangle-lst/src/tests/update_roles.rs b/pallets/tangle-lst/src/tests/update_roles.rs index c3287f9e..346d418a 100644 --- a/pallets/tangle-lst/src/tests/update_roles.rs +++ b/pallets/tangle-lst/src/tests/update_roles.rs @@ -1,7 +1,5 @@ use super::*; -use frame_support::assert_err; -use frame_support::assert_noop; -use frame_support::assert_ok; +use frame_support::{assert_err, assert_noop, assert_ok}; #[test] fn update_roles_works() { diff --git a/pallets/tangle-lst/src/types/bonded_pool.rs b/pallets/tangle-lst/src/types/bonded_pool.rs index bca83493..bcddfb94 100644 --- a/pallets/tangle-lst/src/types/bonded_pool.rs +++ b/pallets/tangle-lst/src/types/bonded_pool.rs @@ -160,8 +160,8 @@ impl BondedPool { } pub fn can_nominate(&self, who: &T::AccountId) -> bool { - self.is_root(who) - || self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) + self.is_root(who) || + self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) } pub fn can_kick(&self, who: &T::AccountId) -> bool { @@ -262,9 +262,9 @@ impl BondedPool { // any unbond must comply with the balance condition: ensure!( - is_full_unbond - || balance_after_unbond - >= if is_depositor { + is_full_unbond || + balance_after_unbond >= + if is_depositor { Pallet::::depositor_min_bond() } else { MinJoinBond::::get() @@ -296,7 +296,7 @@ impl BondedPool { }, (false, true) => { // the depositor can simply not be unbonded permissionlessly, period. - return Err(Error::::DoesNotHavePermission.into()); + return Err(Error::::DoesNotHavePermission.into()) }, }; diff --git a/pallets/tangle-lst/src/types/commission.rs b/pallets/tangle-lst/src/types/commission.rs index 9fbee755..01ecdd0e 100644 --- a/pallets/tangle-lst/src/types/commission.rs +++ b/pallets/tangle-lst/src/types/commission.rs @@ -55,13 +55,13 @@ impl Commission { // do not throttle if `to` is the same or a decrease in commission. if *to <= commission_as_percent { - return false; + return false } // Test for `max_increase` throttling. // // Throttled if the attempted increase in commission is greater than `max_increase`. if (*to).saturating_sub(commission_as_percent) > t.max_increase { - return true; + return true } // Test for `min_delay` throttling. @@ -84,7 +84,7 @@ impl Commission { blocks_surpassed < t.min_delay } }, - ); + ) } false } @@ -145,7 +145,7 @@ impl Commission { ); if let Some(old) = self.max.as_mut() { if new_max > *old { - return Err(Error::::MaxCommissionRestricted.into()); + return Err(Error::::MaxCommissionRestricted.into()) } *old = new_max; } else { diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index d985500d..9ea3b1c7 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -127,7 +127,7 @@ where fn discriminant(address: H160, gas: u64) -> DiscriminantResult> { let extra_cost = RuntimeHelper::::db_read_gas_cost(); if gas < extra_cost { - return DiscriminantResult::OutOfGas; + return DiscriminantResult::OutOfGas } let asset_id = match Runtime::address_to_asset_id(address) { @@ -254,8 +254,8 @@ where handle.record_db_read::(136)?; // If previous approval exists, we need to clean it - if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) - != 0u32.into() + if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) != + 0u32.into() { RuntimeHelper::::try_dispatch( handle, diff --git a/precompiles/assets-erc20/src/tests.rs b/precompiles/assets-erc20/src/tests.rs index 72e02996..a89db545 100644 --- a/precompiles/assets-erc20/src/tests.rs +++ b/precompiles/assets-erc20/src/tests.rs @@ -441,8 +441,8 @@ fn transfer_not_enough_founds() { ForeignPCall::transfer { to: Address(Charlie.into()), value: 50.into() }, ) .execute_reverts(|output| { - from_utf8(output).unwrap().contains("Dispatched call failed with error: ") - && from_utf8(output).unwrap().contains("BalanceLow") + from_utf8(output).unwrap().contains("Dispatched call failed with error: ") && + from_utf8(output).unwrap().contains("BalanceLow") }); }); } diff --git a/precompiles/assets/src/lib.rs b/precompiles/assets/src/lib.rs index 9ad9b1c6..176d49ca 100644 --- a/precompiles/assets/src/lib.rs +++ b/precompiles/assets/src/lib.rs @@ -1,14 +1,15 @@ #![cfg_attr(not(feature = "std"), no_std)] use fp_evm::PrecompileHandle; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; -use frame_support::traits::fungibles::Inspect; +use frame_support::{ + dispatch::{GetDispatchInfo, PostDispatchInfo}, + traits::fungibles::Inspect, +}; use pallet_evm::AddressMapping; use parity_scale_codec::MaxEncodedLen; use precompile_utils::{prelude::*, solidity}; use sp_core::U256; -use sp_runtime::traits::Dispatchable; -use sp_runtime::traits::StaticLookup; +use sp_runtime::traits::{Dispatchable, StaticLookup}; use sp_std::marker::PhantomData; type BalanceOf = ::Balance; diff --git a/precompiles/assets/src/mock.rs b/precompiles/assets/src/mock.rs index 40ac73fc..906396e7 100644 --- a/precompiles/assets/src/mock.rs +++ b/precompiles/assets/src/mock.rs @@ -17,9 +17,8 @@ //! Test utilities use super::*; use crate::{AssetsPrecompile, AssetsPrecompileCall}; -use frame_support::derive_impl; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU64}, weights::Weight, }; diff --git a/precompiles/balances-erc20/src/eip2612.rs b/precompiles/balances-erc20/src/eip2612.rs index cbd2cec3..beb46e75 100644 --- a/precompiles/balances-erc20/src/eip2612.rs +++ b/precompiles/balances-erc20/src/eip2612.rs @@ -21,8 +21,7 @@ use frame_support::{ }; use sp_core::H256; use sp_io::hashing::keccak_256; -use sp_runtime::traits::UniqueSaturatedInto; -use sp_runtime::AccountId32; +use sp_runtime::{traits::UniqueSaturatedInto, AccountId32}; use sp_std::vec::Vec; /// EIP2612 permit typehash. diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index 5024ccdd..8c05ca46 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -34,10 +34,10 @@ use pallet_evm::AddressMapping; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; use sp_runtime::AccountId32; -use sp_std::vec::Vec; use sp_std::{ convert::{TryFrom, TryInto}, marker::PhantomData, + vec::Vec, }; mod eip2612; @@ -437,7 +437,7 @@ where fn deposit(handle: &mut impl PrecompileHandle) -> EvmResult { // Deposit only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()); + return Err(RevertReason::UnknownSelector.into()) } let caller: Runtime::AccountId = @@ -446,7 +446,7 @@ where let amount = Self::u256_to_amount(handle.context().apparent_value)?; if amount.into() == U256::from(0u32) { - return Err(revert("deposited amount must be non-zero")); + return Err(revert("deposited amount must be non-zero")) } handle.record_log_costs_manual(2, 32)?; @@ -476,7 +476,7 @@ where fn withdraw(handle: &mut impl PrecompileHandle, value: U256) -> EvmResult { // Withdraw only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()); + return Err(RevertReason::UnknownSelector.into()) } handle.record_log_costs_manual(2, 32)?; @@ -488,7 +488,7 @@ where }; if value > account_amount { - return Err(revert("Trying to withdraw more than owned")); + return Err(revert("Trying to withdraw more than owned")) } log2( @@ -548,7 +548,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/balances-erc20/src/mock.rs b/precompiles/balances-erc20/src/mock.rs index 1cddc955..fa5d1e4b 100644 --- a/precompiles/balances-erc20/src/mock.rs +++ b/precompiles/balances-erc20/src/mock.rs @@ -17,16 +17,15 @@ //! Testing utilities. use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; -use pallet_evm::AddressMapping; -use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; -use precompile_utils::testing::{Bob, CryptoAlith, CryptoBaltathar, Precompile1}; -use precompile_utils::{precompile_set::*, testing::MockAccount}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; +use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; +use precompile_utils::{ + precompile_set::*, + testing::{Bob, CryptoAlith, CryptoBaltathar, MockAccount, Precompile1}, +}; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; -use sp_core::{ConstU32, U256}; -use sp_core::{Decode, Encode, MaxEncodedLen, H160}; +use sp_core::{ConstU32, Decode, Encode, MaxEncodedLen, H160, U256}; use sp_runtime::BuildStorage; use sp_std::ops::Deref; diff --git a/precompiles/balances-erc20/src/tests.rs b/precompiles/balances-erc20/src/tests.rs index 6e176e80..f62c1a4d 100644 --- a/precompiles/balances-erc20/src/tests.rs +++ b/precompiles/balances-erc20/src/tests.rs @@ -306,8 +306,8 @@ fn transfer_not_enough_funds() { PCall::transfer { to: Address(Bob.into()), value: 1400.into() }, ) .execute_reverts(|output| { - from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") - && from_utf8(&output).unwrap().contains("FundsUnavailable") + from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") && + from_utf8(&output).unwrap().contains("FundsUnavailable") }); }); } diff --git a/precompiles/batch/src/lib.rs b/precompiles/batch/src/lib.rs index 640b1b79..0c71539a 100644 --- a/precompiles/batch/src/lib.rs +++ b/precompiles/batch/src/lib.rs @@ -146,9 +146,8 @@ where let forwarded_gas = match (remaining_gas.checked_sub(log_cost), mode) { (Some(remaining), _) => remaining, - (None, Mode::BatchAll) => { - return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) - }, + (None, Mode::BatchAll) => + return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), (None, _) => return Ok(()), }; @@ -163,11 +162,10 @@ where log.record(handle)?; match mode { - Mode::BatchAll => { + Mode::BatchAll => return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }) - }, + }), Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -184,11 +182,10 @@ where log.record(handle)?; match mode { - Mode::BatchAll => { + Mode::BatchAll => return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }) - }, + }), Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -219,23 +216,19 @@ where // How to proceed match (mode, reason) { // _: Fatal is always fatal - (_, ExitReason::Fatal(exit_status)) => { - return Err(PrecompileFailure::Fatal { exit_status }) - }, + (_, ExitReason::Fatal(exit_status)) => + return Err(PrecompileFailure::Fatal { exit_status }), // BatchAll : Reverts and errors are immediatly forwarded. - (Mode::BatchAll, ExitReason::Revert(exit_status)) => { - return Err(PrecompileFailure::Revert { exit_status, output }) - }, - (Mode::BatchAll, ExitReason::Error(exit_status)) => { - return Err(PrecompileFailure::Error { exit_status }) - }, + (Mode::BatchAll, ExitReason::Revert(exit_status)) => + return Err(PrecompileFailure::Revert { exit_status, output }), + (Mode::BatchAll, ExitReason::Error(exit_status)) => + return Err(PrecompileFailure::Error { exit_status }), // BatchSomeUntilFailure : Reverts and errors prevent subsequent subcalls to // be executed but the precompile still succeed. - (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => { - return Ok(()) - }, + (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => + return Ok(()), // Success or ignored revert/error. (_, _) => (), @@ -270,9 +263,8 @@ where match mode { Mode::BatchSome => Self::batch_some { to, value, call_data, gas_limit }, - Mode::BatchSomeUntilFailure => { - Self::batch_some_until_failure { to, value, call_data, gas_limit } - }, + Mode::BatchSomeUntilFailure => + Self::batch_some_until_failure { to, value, call_data, gas_limit }, Mode::BatchAll => Self::batch_all { to, value, call_data, gas_limit }, } } diff --git a/precompiles/batch/src/mock.rs b/precompiles/batch/src/mock.rs index e9c7ec91..a2d22415 100644 --- a/precompiles/batch/src/mock.rs +++ b/precompiles/batch/src/mock.rs @@ -18,8 +18,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; use precompile_utils::{mock_account, precompile_set::*, testing::MockAccount}; use sp_runtime::{BuildStorage, Perbill}; diff --git a/precompiles/call-permit/src/lib.rs b/precompiles/call-permit/src/lib.rs index ee64f0b8..4a0ae951 100644 --- a/precompiles/call-permit/src/lib.rs +++ b/precompiles/call-permit/src/lib.rs @@ -170,7 +170,7 @@ where .ok_or_else(|| revert("Call require too much gas (uint64 overflow)"))?; if total_cost > handle.remaining_gas() { - return Err(revert("Gaslimit is too low to dispatch provided call")); + return Err(revert("Gaslimit is too low to dispatch provided call")) } // VERIFY PERMIT @@ -216,9 +216,8 @@ where match reason { ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(_) => { - Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }) - }, + ExitReason::Revert(_) => + Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }), ExitReason::Succeed(_) => Ok(output.into()), } } diff --git a/precompiles/call-permit/src/mock.rs b/precompiles/call-permit/src/mock.rs index f9858e7c..0e45d42d 100644 --- a/precompiles/call-permit/src/mock.rs +++ b/precompiles/call-permit/src/mock.rs @@ -19,8 +19,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, pallet_prelude::*, parameter_types}; +use frame_support::{construct_runtime, derive_impl, pallet_prelude::*, parameter_types}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; use precompile_utils::{mock_account, precompile_set::*, testing::MockAccount}; use sp_runtime::{BuildStorage, Perbill}; diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 6fd4ebb3..d8ed82e5 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -82,7 +82,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/multi-asset-delegation/src/mock.rs b/precompiles/multi-asset-delegation/src/mock.rs index a999578d..35d911ff 100644 --- a/precompiles/multi-asset-delegation/src/mock.rs +++ b/precompiles/multi-asset-delegation/src/mock.rs @@ -17,9 +17,8 @@ //! Test utilities use super::*; use crate::{MultiAssetDelegationPrecompile, MultiAssetDelegationPrecompileCall}; -use frame_support::derive_impl; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU64}, weights::Weight, PalletId, diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index c6ed8d64..2c7d6533 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -432,8 +432,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Inactive + MultiAssetDelegation::operator_info(operator_account).unwrap().status == + OperatorStatus::Inactive ); PrecompilesValue::get() @@ -441,8 +441,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Active + MultiAssetDelegation::operator_info(operator_account).unwrap().status == + OperatorStatus::Active ); assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); diff --git a/precompiles/pallet-democracy/src/lib.rs b/precompiles/pallet-democracy/src/lib.rs index 89091f0c..e456a0b4 100644 --- a/precompiles/pallet-democracy/src/lib.rs +++ b/precompiles/pallet-democracy/src/lib.rs @@ -467,7 +467,7 @@ where if !<::Preimages as QueryPreimage>::is_requested( &proposal_hash, ) { - return Err(revert("not imminent preimage (preimage not requested)")); + return Err(revert("not imminent preimage (preimage not requested)")) }; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); diff --git a/precompiles/pallet-democracy/src/mock.rs b/precompiles/pallet-democracy/src/mock.rs index 91443766..09f7e3ab 100644 --- a/precompiles/pallet-democracy/src/mock.rs +++ b/precompiles/pallet-democracy/src/mock.rs @@ -18,9 +18,8 @@ //! Test utilities use super::*; -use frame_support::derive_impl; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{EqualPrivilegeOnly, OnFinalize, OnInitialize, StorePreimage}, weights::Weight, }; diff --git a/precompiles/pallet-democracy/src/tests.rs b/precompiles/pallet-democracy/src/tests.rs index bdf4baf3..e8f280d0 100644 --- a/precompiles/pallet-democracy/src/tests.rs +++ b/precompiles/pallet-democracy/src/tests.rs @@ -220,9 +220,8 @@ fn lowest_unbaked_non_zero() { .dispatch(RuntimeOrigin::signed(Alice.into()))); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -244,9 +243,9 @@ fn lowest_unbaked_non_zero() { // Run it through until it is baked roll_to( - ::VotingPeriod::get() - + ::LaunchPeriod::get() - + 1000, + ::VotingPeriod::get() + + ::LaunchPeriod::get() + + 1000, ); precompiles() @@ -559,9 +558,8 @@ fn standard_vote_aye_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -644,9 +642,8 @@ fn standard_vote_nay_conviction_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -724,9 +721,8 @@ fn remove_vote_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -797,9 +793,8 @@ fn delegate_works() { ); let alice_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Delegating { balance, target, conviction, delegations, prior } => { - (balance, target, conviction, delegations, prior) - }, + Voting::Delegating { balance, target, conviction, delegations, prior } => + (balance, target, conviction, delegations, prior), _ => panic!("Votes are not delegating"), }; @@ -812,9 +807,8 @@ fn delegate_works() { let bob_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Bob)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; diff --git a/precompiles/precompile-registry/src/lib.rs b/precompiles/precompile-registry/src/lib.rs index 5a1e864a..0910bd1f 100644 --- a/precompiles/precompile-registry/src/lib.rs +++ b/precompiles/precompile-registry/src/lib.rs @@ -69,9 +69,8 @@ where .is_active_precompile(address.0, handle.remaining_gas()) { IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile), - IsPrecompileResult::OutOfGas => { - Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) - }, + IsPrecompileResult::OutOfGas => + Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), } } @@ -86,7 +85,7 @@ where // Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15) handle.record_db_read::(175)?; if !is_precompile_or_fail::(address.0, handle.remaining_gas())? { - return Err(revert("provided address is not a precompile")); + return Err(revert("provided address is not a precompile")) } // pallet_evm::create_account read storage item pallet_evm::AccountCodes diff --git a/precompiles/precompile-registry/src/mock.rs b/precompiles/precompile-registry/src/mock.rs index 45bcc845..079d3e65 100644 --- a/precompiles/precompile-registry/src/mock.rs +++ b/precompiles/precompile-registry/src/mock.rs @@ -19,8 +19,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, pallet_prelude::*, parameter_types}; +use frame_support::{construct_runtime, derive_impl, pallet_prelude::*, parameter_types}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; use precompile_utils::{mock_account, precompile_set::*, testing::MockAccount}; use sp_runtime::{BuildStorage, Perbill}; diff --git a/precompiles/preimage/src/mock.rs b/precompiles/preimage/src/mock.rs index 9840a569..09e1459d 100644 --- a/precompiles/preimage/src/mock.rs +++ b/precompiles/preimage/src/mock.rs @@ -18,8 +18,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use frame_system::EnsureRoot; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/proxy/src/lib.rs b/precompiles/proxy/src/lib.rs index 45073243..c63daf96 100644 --- a/precompiles/proxy/src/lib.rs +++ b/precompiles/proxy/src/lib.rs @@ -60,9 +60,8 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => { - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) - }, + Some(selector) => + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector), } } @@ -92,12 +91,11 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => { - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) - || ProxyPrecompileCall::::proxy_selectors().contains(&selector) - || ProxyPrecompileCall::::proxy_force_type_selectors() - .contains(&selector) - }, + Some(selector) => + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) || + ProxyPrecompileCall::::proxy_selectors().contains(&selector) || + ProxyPrecompileCall::::proxy_force_type_selectors() + .contains(&selector), } } @@ -187,7 +185,7 @@ where .iter() .any(|pd| pd.delegate == delegate) { - return Err(revert("Cannot add more than one proxy")); + return Err(revert("Cannot add more than one proxy")) } let delegate: ::Source = @@ -343,7 +341,7 @@ where // Check that we only perform proxy calls on behalf of externally owned accounts let AddressType::EOA = precompile_set::get_address_type::(handle, real.into())? else { - return Err(revert("real address must be EOA")); + return Err(revert("real address must be EOA")) }; // Read proxy @@ -419,9 +417,8 @@ where // Return subcall result match reason { ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(exit_status) => { - Err(PrecompileFailure::Revert { exit_status, output }) - }, + ExitReason::Revert(exit_status) => + Err(PrecompileFailure::Revert { exit_status, output }), ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Succeed(_) => Ok(()), } diff --git a/precompiles/proxy/src/mock.rs b/precompiles/proxy/src/mock.rs index e9584c44..b1e097fb 100644 --- a/precompiles/proxy/src/mock.rs +++ b/precompiles/proxy/src/mock.rs @@ -18,8 +18,9 @@ //! Test utilities use crate::{ProxyPrecompile, ProxyPrecompileCall}; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, traits::InstanceFilter, weights::Weight}; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, traits::InstanceFilter, weights::Weight, +}; use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, SubstrateBlockHashMapping}; use precompile_utils::{ precompile_set::{ diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 50946f49..402679e8 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -9,8 +9,7 @@ use pallet_services::types::BalanceOf; use parity_scale_codec::Decode; use precompile_utils::prelude::*; use sp_core::U256; -use sp_runtime::traits::Dispatchable; -use sp_runtime::Percent; +use sp_runtime::{traits::Dispatchable, Percent}; use sp_std::{marker::PhantomData, vec::Vec}; use tangle_primitives::services::{Asset, Field, OperatorPreferences, ServiceBlueprint}; @@ -206,19 +205,18 @@ where (0, ZERO_ADDRESS) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)) } (Asset::Erc20(erc20_token.into()), amount) }, (other_asset_id, ZERO_ADDRESS) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)) } (Asset::Custom(other_asset_id.into()), amount) }, - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; let call = pallet_services::Call::::request { @@ -351,11 +349,12 @@ where Ok(()) } - /// Slash an operator (offender) for a service id with a given percent of their exposed stake for that service. + /// Slash an operator (offender) for a service id with a given percent of their exposed stake + /// for that service. /// /// The caller needs to be an authorized Slash Origin for this service. - /// Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash - /// by another entity. + /// Note that this does not apply the slash directly, but instead schedules a deferred call to + /// apply the slash by another entity. #[precompile::public("slash(bytes,uint256,uint8)")] fn slash( handle: &mut impl PrecompileHandle, diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 4a0bf273..511cc42a 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -21,23 +21,20 @@ use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, SequentialPhragmen, }; -use frame_support::pallet_prelude::Hooks; -use frame_support::pallet_prelude::Weight; use frame_support::{ - construct_runtime, parameter_types, - traits::{ConstU128, OneSessionHandler}, + construct_runtime, derive_impl, + pallet_prelude::{Hooks, Weight}, + parameter_types, + traits::{AsEnsureOriginWithArg, ConstU128, OneSessionHandler}, }; -use frame_support::{derive_impl, traits::AsEnsureOriginWithArg}; use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; -use pallet_services::traits::EvmRunner; -use pallet_services::{EvmAddressMapping, EvmGasWeightMapping}; +use pallet_services::{traits::EvmRunner, EvmAddressMapping, EvmGasWeightMapping}; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -use serde::Deserialize; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::json; use sp_core::{self, sr25519, sr25519::Public as sr25519Public, ConstU32, RuntimeDebug, H160}; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; @@ -410,7 +407,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false; + return false } true } diff --git a/precompiles/services/src/mock_evm.rs b/precompiles/services/src/mock_evm.rs index 901b9a0e..14fdf666 100644 --- a/precompiles/services/src/mock_evm.rs +++ b/precompiles/services/src/mock_evm.rs @@ -14,11 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] -use crate::mock::{ - AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, +use crate::{ + mock::{AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp}, + ServicesPrecompile, ServicesPrecompileCall, }; -use crate::ServicesPrecompile; -use crate::ServicesPrecompileCall; use fp_evm::FeeCalculator; use frame_support::{ parameter_types, @@ -152,7 +151,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation as OnChargeEVMTransaction< @@ -169,7 +168,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation as OnChargeEVMTransaction< @@ -255,9 +254,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -267,9 +265,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), _ => None, } } diff --git a/precompiles/services/src/tests.rs b/precompiles/services/src/tests.rs index 447eae2f..0cde095d 100644 --- a/precompiles/services/src/tests.rs +++ b/precompiles/services/src/tests.rs @@ -1,28 +1,20 @@ use core::ops::Mul; -use crate::mock::*; -use crate::mock_evm::PCall; -use crate::mock_evm::PrecompilesValue; +use crate::{ + mock::*, + mock_evm::{PCall, PrecompilesValue}, +}; use frame_support::assert_ok; -use pallet_services::types::ConstraintsOf; -use pallet_services::Instances; -use pallet_services::Operators; -use pallet_services::OperatorsProfile; +use pallet_services::{types::ConstraintsOf, Instances, Operators, OperatorsProfile}; use parity_scale_codec::Encode; -use precompile_utils::prelude::UnboundedBytes; -use precompile_utils::testing::*; -use sp_core::ecdsa; -use sp_core::{H160, U256}; -use sp_runtime::bounded_vec; -use sp_runtime::AccountId32; -use tangle_primitives::services::BlueprintServiceManager; -use tangle_primitives::services::FieldType; -use tangle_primitives::services::JobDefinition; -use tangle_primitives::services::JobMetadata; -use tangle_primitives::services::MasterBlueprintServiceManagerRevision; -use tangle_primitives::services::PriceTargets; -use tangle_primitives::services::ServiceMetadata; -use tangle_primitives::services::{OperatorPreferences, ServiceBlueprint}; +use precompile_utils::{prelude::UnboundedBytes, testing::*}; +use sp_core::{ecdsa, H160, U256}; +use sp_runtime::{bounded_vec, AccountId32}; +use tangle_primitives::services::{ + BlueprintServiceManager, FieldType, JobDefinition, JobMetadata, + MasterBlueprintServiceManagerRevision, OperatorPreferences, PriceTargets, ServiceBlueprint, + ServiceMetadata, +}; fn zero_key() -> ecdsa::Public { ecdsa::Public::from([0; 33]) @@ -53,9 +45,8 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => { - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } - }, + MachineKind::Small => + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, } } diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 313a7da9..76235bd4 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -78,7 +78,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/staking/src/mock.rs b/precompiles/staking/src/mock.rs index b64e4ec8..a6dbf075 100644 --- a/precompiles/staking/src/mock.rs +++ b/precompiles/staking/src/mock.rs @@ -21,9 +21,8 @@ #![allow(clippy::all)] use super::*; use frame_election_provider_support::bounds::{ElectionBounds, ElectionBoundsBuilder}; -use frame_support::derive_impl; use frame_support::{ - assert_ok, construct_runtime, + assert_ok, construct_runtime, derive_impl, pallet_prelude::Hooks, parameter_types, traits::{ConstU64, OnFinalize, OnInitialize, OneSessionHandler}, diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index de005e09..243a7935 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -14,20 +14,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! This file contains the implementation of the MultiAssetDelegationPrecompile struct which provides an -//! interface between the EVM and the native MultiAssetDelegation pallet of the runtime. It allows EVM contracts -//! to call functions of the MultiAssetDelegation pallet, in order to enable EVM accounts to interact with the delegation system. +//! This file contains the implementation of the MultiAssetDelegationPrecompile struct which +//! provides an interface between the EVM and the native MultiAssetDelegation pallet of the runtime. +//! It allows EVM contracts to call functions of the MultiAssetDelegation pallet, in order to enable +//! EVM accounts to interact with the delegation system. //! -//! The MultiAssetDelegationPrecompile struct implements core methods that correspond to the functions of the -//! MultiAssetDelegation pallet. These methods can be called from EVM contracts. They include functions to join as an operator, -//! delegate assets, withdraw assets, etc. +//! The MultiAssetDelegationPrecompile struct implements core methods that correspond to the +//! functions of the MultiAssetDelegation pallet. These methods can be called from EVM contracts. +//! They include functions to join as an operator, delegate assets, withdraw assets, etc. //! //! Each method records the gas cost for the operation, performs the requested operation, and //! returns the result in a format that can be used by the EVM. //! -//! The MultiAssetDelegationPrecompile struct is generic over the Runtime type, which is the type of the runtime -//! that includes the MultiAssetDelegation pallet. This allows the precompile to work with any runtime that -//! includes the MultiAssetDelegation pallet and meets the other trait bounds required by the precompile. +//! The MultiAssetDelegationPrecompile struct is generic over the Runtime type, which is the type of +//! the runtime that includes the MultiAssetDelegation pallet. This allows the precompile to work +//! with any runtime that includes the MultiAssetDelegation pallet and meets the other trait bounds +//! required by the precompile. #![cfg_attr(not(feature = "std"), no_std)] @@ -44,8 +46,7 @@ use pallet_evm::AddressMapping; use pallet_tangle_lst::{BondExtra, ConfigOp, PoolId, PoolState}; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; -use sp_runtime::traits::Dispatchable; -use sp_runtime::traits::StaticLookup; +use sp_runtime::traits::{Dispatchable, StaticLookup}; use sp_std::{marker::PhantomData, vec::Vec}; use tangle_primitives::types::WrappedAccountId32; @@ -343,7 +344,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/tangle-lst/src/mock.rs b/precompiles/tangle-lst/src/mock.rs index 39c20ed0..dd8edf87 100644 --- a/precompiles/tangle-lst/src/mock.rs +++ b/precompiles/tangle-lst/src/mock.rs @@ -17,10 +17,12 @@ //! Test utilities use super::*; use crate::{TangleLstPrecompile, TangleLstPrecompileCall}; -use frame_support::derive_impl; -use frame_support::traits::AsEnsureOriginWithArg; -use frame_support::PalletId; -use frame_support::{construct_runtime, parameter_types, traits::ConstU64, weights::Weight}; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU64}, + weights::Weight, + PalletId, +}; use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, SubstrateBlockHashMapping}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; @@ -30,18 +32,11 @@ use sp_core::{ sr25519::{Public as sr25519Public, Signature}, ConstU32, H160, U256, }; -use sp_runtime::traits::Convert; -use sp_runtime::DispatchError; -use sp_runtime::DispatchResult; -use sp_runtime::FixedU128; -use sp_runtime::Perbill; use sp_runtime::{ - traits::{IdentifyAccount, Verify}, - AccountId32, BuildStorage, + traits::{Convert, IdentifyAccount, Verify}, + AccountId32, BuildStorage, DispatchError, DispatchResult, FixedU128, Perbill, }; -use sp_staking::EraIndex; -use sp_staking::OnStakingUpdate; -use sp_staking::Stake; +use sp_staking::{EraIndex, OnStakingUpdate, Stake}; use sp_std::collections::btree_map::BTreeMap; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; diff --git a/precompiles/verify-bls381-signature/src/lib.rs b/precompiles/verify-bls381-signature/src/lib.rs index decc2b3e..578a7721 100644 --- a/precompiles/verify-bls381-signature/src/lib.rs +++ b/precompiles/verify-bls381-signature/src/lib.rs @@ -55,14 +55,14 @@ impl Bls381Precompile { { p_key } else { - return Ok(false); + return Ok(false) }; let signature = if let Ok(sig) = snowbridge_milagro_bls::Signature::from_bytes(&signature_bytes) { sig } else { - return Ok(false); + return Ok(false) }; let is_confirmed = signature.verify(&message, &public_key); diff --git a/precompiles/verify-bls381-signature/src/mock.rs b/precompiles/verify-bls381-signature/src/mock.rs index 3474c6fd..4e98b901 100644 --- a/precompiles/verify-bls381-signature/src/mock.rs +++ b/precompiles/verify-bls381-signature/src/mock.rs @@ -16,8 +16,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs b/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs index d3405a36..fa47d71e 100644 --- a/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs @@ -61,21 +61,21 @@ impl EcdsaSecp256k1Precompile { let pub_key_point = if let Some(x) = maybe_pub_key_point.into() { x } else { - return Ok(false); + return Ok(false) }; let maybe_verifying_key = k256::ecdsa::VerifyingKey::from_affine(pub_key_point); let verifying_key = if let Ok(x) = maybe_verifying_key { x } else { - return Ok(false); + return Ok(false) }; let maybe_signature = k256::ecdsa::Signature::from_slice(signature_bytes.as_slice()); let signature = if let Ok(x) = maybe_signature { x } else { - return Ok(false); + return Ok(false) }; let is_confirmed = diff --git a/precompiles/verify-ecdsa-secp256k1-signature/src/mock.rs b/precompiles/verify-ecdsa-secp256k1-signature/src/mock.rs index 8d223e1a..1e63814d 100644 --- a/precompiles/verify-ecdsa-secp256k1-signature/src/mock.rs +++ b/precompiles/verify-ecdsa-secp256k1-signature/src/mock.rs @@ -16,8 +16,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs b/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs index 4c5b6b5b..b0e2a128 100644 --- a/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs @@ -61,21 +61,21 @@ impl EcdsaSecp256r1Precompile { let pub_key_point = if let Some(x) = maybe_pub_key_point.into() { x } else { - return Ok(false); + return Ok(false) }; let maybe_verifying_key = p256::ecdsa::VerifyingKey::from_affine(pub_key_point); let verifying_key = if let Ok(x) = maybe_verifying_key { x } else { - return Ok(false); + return Ok(false) }; let maybe_signature = p256::ecdsa::Signature::from_slice(signature_bytes.as_slice()); let signature = if let Ok(x) = maybe_signature { x } else { - return Ok(false); + return Ok(false) }; let is_confirmed = diff --git a/precompiles/verify-ecdsa-secp256r1-signature/src/mock.rs b/precompiles/verify-ecdsa-secp256r1-signature/src/mock.rs index c17ec8bd..17c714e4 100644 --- a/precompiles/verify-ecdsa-secp256r1-signature/src/mock.rs +++ b/precompiles/verify-ecdsa-secp256r1-signature/src/mock.rs @@ -16,8 +16,7 @@ #![allow(clippy::all)] //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/verify-ecdsa-stark-signature/src/lib.rs b/precompiles/verify-ecdsa-stark-signature/src/lib.rs index c6a1287b..0dc5e1ec 100644 --- a/precompiles/verify-ecdsa-stark-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-stark-signature/src/lib.rs @@ -62,25 +62,25 @@ impl EcdsaStarkPrecompile { let r = if let Ok(x) = Scalar::from_be_bytes(r_bytes) { x } else { - return Ok(false); + return Ok(false) }; let s = if let Ok(x) = Scalar::from_be_bytes(s_bytes) { x } else { - return Ok(false); + return Ok(false) }; let public_key_point = if let Ok(x) = Point::from_bytes(public_bytes) { x } else { - return Ok(false); + return Ok(false) }; let public_key_x: Scalar = if let Some(x) = public_key_point.x() { x.to_scalar() } else { - return Ok(false); + return Ok(false) }; let public_key = convert_stark_scalar(&public_key_x); diff --git a/precompiles/verify-ecdsa-stark-signature/src/mock.rs b/precompiles/verify-ecdsa-stark-signature/src/mock.rs index 615cd260..7b684ac7 100644 --- a/precompiles/verify-ecdsa-stark-signature/src/mock.rs +++ b/precompiles/verify-ecdsa-stark-signature/src/mock.rs @@ -16,8 +16,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/verify-schnorr-signatures/src/lib.rs b/precompiles/verify-schnorr-signatures/src/lib.rs index c4d6ef6c..79f00023 100644 --- a/precompiles/verify-schnorr-signatures/src/lib.rs +++ b/precompiles/verify-schnorr-signatures/src/lib.rs @@ -55,7 +55,7 @@ pub fn to_slice_32(val: &[u8]) -> Option<[u8; 32]> { let mut key = [0u8; 32]; key[..32].copy_from_slice(val); - return Some(key); + return Some(key) } None } diff --git a/precompiles/verify-schnorr-signatures/src/mock.rs b/precompiles/verify-schnorr-signatures/src/mock.rs index b5a3849d..6e01097e 100644 --- a/precompiles/verify-schnorr-signatures/src/mock.rs +++ b/precompiles/verify-schnorr-signatures/src/mock.rs @@ -16,8 +16,7 @@ //! Test utilities use super::*; -use frame_support::derive_impl; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, derive_impl, parameter_types, weights::Weight}; use pallet_evm::{AddressMapping, EnsureAddressNever, EnsureAddressRoot}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use precompile_utils::{precompile_set::*, testing::MockAccount}; diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index b73d49df..05f748f9 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -79,7 +79,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; @@ -153,7 +153,7 @@ where match pallet_vesting::Vesting::::get(origin.clone()) { Some(schedules) => { if index >= schedules.len() as u8 { - return Err(revert("Invalid vesting schedule index")); + return Err(revert("Invalid vesting schedule index")) } // Make the call to transfer the vested funds to the `target` account. let target = Self::convert_to_account_id(target)?; diff --git a/primitives/rpc/evm-tracing-events/src/evm.rs b/primitives/rpc/evm-tracing-events/src/evm.rs index 2b997eae..688861fd 100644 --- a/primitives/rpc/evm-tracing-events/src/evm.rs +++ b/primitives/rpc/evm-tracing-events/src/evm.rs @@ -61,9 +61,8 @@ impl From for CreateScheme { fn from(i: evm_runtime::CreateScheme) -> Self { match i { evm_runtime::CreateScheme::Legacy { caller } => Self::Legacy { caller }, - evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => { - Self::Create2 { caller, code_hash, salt } - }, + evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => + Self::Create2 { caller, code_hash, salt }, evm_runtime::CreateScheme::Fixed(address) => Self::Fixed(address), } } @@ -167,15 +166,12 @@ impl<'a> From> for EvmEvent { init_code: init_code.to_vec(), target_gas, }, - evm::tracing::Event::Suicide { address, target, balance } => { - Self::Suicide { address, target, balance } - }, - evm::tracing::Event::Exit { reason, return_value } => { - Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() } - }, - evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => { - Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit } - }, + evm::tracing::Event::Suicide { address, target, balance } => + Self::Suicide { address, target, balance }, + evm::tracing::Event::Exit { reason, return_value } => + Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() }, + evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => + Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit }, evm::tracing::Event::TransactCreate { caller, value, diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index 85d8352b..d1fbb453 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -59,15 +59,12 @@ pub enum GasometerEvent { impl From for GasometerEvent { fn from(i: evm_gasometer::tracing::Event) -> Self { match i { - evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => { - Self::RecordCost { cost, snapshot: snapshot.into() } - }, - evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => { - Self::RecordRefund { refund, snapshot: snapshot.into() } - }, - evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => { - Self::RecordStipend { stipend, snapshot: snapshot.into() } - }, + evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => + Self::RecordCost { cost, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => + Self::RecordRefund { refund, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => + Self::RecordStipend { stipend, snapshot: snapshot.into() }, evm_gasometer::tracing::Event::RecordDynamicCost { gas_cost, memory_gas, @@ -79,9 +76,8 @@ impl From for GasometerEvent { gas_refund, snapshot: snapshot.into(), }, - evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => { - Self::RecordTransaction { cost, snapshot: snapshot.into() } - }, + evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => + Self::RecordTransaction { cost, snapshot: snapshot.into() }, } } } diff --git a/primitives/rpc/evm-tracing-events/src/runtime.rs b/primitives/rpc/evm-tracing-events/src/runtime.rs index 089932d5..ad738f73 100644 --- a/primitives/rpc/evm-tracing-events/src/runtime.rs +++ b/primitives/rpc/evm-tracing-events/src/runtime.rs @@ -92,7 +92,7 @@ impl RuntimeEvent { filter: crate::StepEventFilter, ) -> Self { match i { - evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => { + evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => Self::Step { context: context.clone().into(), opcode: opcodes_string(opcode), @@ -102,8 +102,7 @@ impl RuntimeEvent { }, stack: if filter.enable_stack { Some(stack.into()) } else { None }, memory: if filter.enable_memory { Some(memory.into()) } else { None }, - } - }, + }, evm_runtime::tracing::Event::StepResult { result, return_value } => Self::StepResult { result: match result { Ok(_) => Ok(()), @@ -114,12 +113,10 @@ impl RuntimeEvent { }, return_value: return_value.to_vec(), }, - evm_runtime::tracing::Event::SLoad { address, index, value } => { - Self::SLoad { address, index, value } - }, - evm_runtime::tracing::Event::SStore { address, index, value } => { - Self::SStore { address, index, value } - }, + evm_runtime::tracing::Event::SLoad { address, index, value } => + Self::SLoad { address, index, value }, + evm_runtime::tracing::Event::SStore { address, index, value } => + Self::SStore { address, index, value }, } } } diff --git a/primitives/src/chain_identifier.rs b/primitives/src/chain_identifier.rs index 72155a8a..d916c2a2 100644 --- a/primitives/src/chain_identifier.rs +++ b/primitives/src/chain_identifier.rs @@ -65,14 +65,14 @@ impl TypedChainId { #[must_use] pub const fn underlying_chain_id(&self) -> u32 { match self { - TypedChainId::Evm(id) - | TypedChainId::Substrate(id) - | TypedChainId::PolkadotParachain(id) - | TypedChainId::KusamaParachain(id) - | TypedChainId::RococoParachain(id) - | TypedChainId::Cosmos(id) - | TypedChainId::Solana(id) - | TypedChainId::Ink(id) => *id, + TypedChainId::Evm(id) | + TypedChainId::Substrate(id) | + TypedChainId::PolkadotParachain(id) | + TypedChainId::KusamaParachain(id) | + TypedChainId::RococoParachain(id) | + TypedChainId::Cosmos(id) | + TypedChainId::Solana(id) | + TypedChainId::Ink(id) => *id, Self::None => 0, } } diff --git a/primitives/src/services/field.rs b/primitives/src/services/field.rs index 55f09cf4..ef54621f 100644 --- a/primitives/src/services/field.rs +++ b/primitives/src/services/field.rs @@ -172,13 +172,13 @@ impl PartialEq for Field { (Self::AccountId(l0), Self::AccountId(r0)) => l0 == r0, (Self::Struct(l_name, l_fields), Self::Struct(r_name, r_fields)) => { if l_name != r_name || l_fields.len() != r_fields.len() { - return false; + return false } for ((l_field_name, l_field_value), (r_field_name, r_field_value)) in l_fields.iter().zip(r_fields.iter()) { if l_field_name != r_field_name || l_field_value != r_field_value { - return false; + return false } } true @@ -307,18 +307,16 @@ impl PartialEq for Field { (Self::Int64(_), FieldType::Int64) => true, (Self::String(_), FieldType::String) => true, (Self::Bytes(_), FieldType::Bytes) => true, - (Self::Array(a), FieldType::Array(len, b)) => { - a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())) - }, + (Self::Array(a), FieldType::Array(len, b)) => + a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())), (Self::List(a), FieldType::List(b)) => a.iter().all(|f| f.eq(b.as_ref())), (Self::AccountId(_), FieldType::AccountId) => true, - (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => { - fields_a.into_iter().len() == fields_b.into_iter().len() - && fields_a + (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => + fields_a.into_iter().len() == fields_b.into_iter().len() && + fields_a .into_iter() .zip(fields_b) - .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)) - }, + .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)), _ => false, } } @@ -422,7 +420,7 @@ impl Field { /// Encode the fields to ethabi bytes. pub fn encode_to_ethabi(fields: &[Self]) -> ethabi::Bytes { if fields.is_empty() { - return Default::default(); + return Default::default() } let tokens: Vec = fields.iter().map(Self::to_ethabi_token).collect(); ethabi::encode(&tokens) diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index d572a46a..4163487b 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -161,7 +161,7 @@ pub fn type_checker( return Err(TypeCheckError::NotEnoughArguments { expected: params.len() as u8, actual: args.len() as u8, - }); + }) } for i in 0..args.len() { let arg = &args[i]; @@ -171,7 +171,7 @@ pub fn type_checker( index: i as u8, expected: expected.clone(), actual: arg.clone().into(), - }); + }) } } Ok(()) @@ -361,12 +361,13 @@ pub struct ServiceBlueprint { /// The request hook that will be called before creating a service from the service blueprint. /// The parameters that are required for the service request. pub request_params: BoundedVec, - /// A Blueprint Manager is a smart contract that implements the `IBlueprintServiceManager` interface. + /// A Blueprint Manager is a smart contract that implements the `IBlueprintServiceManager` + /// interface. pub manager: BlueprintServiceManager, /// The Revision number of the Master Blueprint Service Manager. /// - /// If not sure what to use, use `MasterBlueprintServiceManagerRevision::default()` which will use - /// the latest revision available. + /// If not sure what to use, use `MasterBlueprintServiceManagerRevision::default()` which will + /// use the latest revision available. pub master_manager_revision: MasterBlueprintServiceManagerRevision, /// The gadget that will be executed for the service. pub gadget: Gadget, @@ -484,12 +485,10 @@ impl ServiceBlueprint { }, // Master Manager Revision match self.master_manager_revision { - MasterBlueprintServiceManagerRevision::Latest => { - ethabi::Token::Uint(ethabi::Uint::MAX) - }, - MasterBlueprintServiceManagerRevision::Specific(rev) => { - ethabi::Token::Uint(rev.into()) - }, + MasterBlueprintServiceManagerRevision::Latest => + ethabi::Token::Uint(ethabi::Uint::MAX), + MasterBlueprintServiceManagerRevision::Specific(rev) => + ethabi::Token::Uint(rev.into()), }, // Gadget ? ]) @@ -593,8 +592,9 @@ pub struct Service { /// The Permitted caller(s) of the service. pub permitted_callers: BoundedVec, /// The Selected operators(s) for this service with their restaking Percentage. - // This a Vec instead of a BTreeMap because the number of operators is expected to be small (smaller than 512) - // and the overhead of a BTreeMap is not worth it, plus BoundedBTreeMap is not serde compatible. + // This a Vec instead of a BTreeMap because the number of operators is expected to be small + // (smaller than 512) and the overhead of a BTreeMap is not worth it, plus BoundedBTreeMap is + // not serde compatible. pub operators: BoundedVec<(AccountId, Percent), C::MaxOperatorsPerService>, /// Asset(s) used to secure the service instance. pub assets: BoundedVec, diff --git a/primitives/src/verifier/circom.rs b/primitives/src/verifier/circom.rs index 4dbf7303..34251912 100644 --- a/primitives/src/verifier/circom.rs +++ b/primitives/src/verifier/circom.rs @@ -51,28 +51,28 @@ impl super::InstanceVerifier for CircomVerifierGroth16Bn254 { Ok(v) => v, Err(e) => { log::error!("Failed to convert public input bytes to field elements: {e:?}",); - return Err(e); + return Err(e) }, }; let vk = match ArkVerifyingKey::deserialize_compressed(vk_bytes) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize verifying key: {e:?}"); - return Err(e.into()); + return Err(e.into()) }, }; let proof = match Proof::decode(proof_bytes).and_then(|v| v.try_into()) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize proof: {e:?}"); - return Err(e); + return Err(e) }, }; let res = match verify_groth16(&vk, &public_input_field_elts, &proof) { Ok(v) => v, Err(e) => { log::error!("Failed to verify proof: {e:?}"); - return Err(e); + return Err(e) }, }; @@ -246,7 +246,7 @@ fn point_to_u256(point: F) -> Result { let point = point.into_bigint(); let point_bytes = point.to_bytes_be(); if point_bytes.len() != 32 { - return Err(CircomError::InvalidProofBytes.into()); + return Err(CircomError::InvalidProofBytes.into()) } Ok(U256::from(&point_bytes[..])) } diff --git a/runtime/mainnet/src/filters.rs b/runtime/mainnet/src/filters.rs index bb010546..28a8545c 100644 --- a/runtime/mainnet/src/filters.rs +++ b/runtime/mainnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for MainnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true; + return true } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false; + return false } true diff --git a/runtime/mainnet/src/frontier_evm.rs b/runtime/mainnet/src/frontier_evm.rs index 38d046f1..cede2d73 100644 --- a/runtime/mainnet/src/frontier_evm.rs +++ b/runtime/mainnet/src/frontier_evm.rs @@ -61,7 +61,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) } None } @@ -119,21 +119,20 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { ) -> precompile_utils::EvmResult { Ok(match self { ProxyType::Any => true, - ProxyType::Governance => { - call.value == U256::zero() - && matches!( + ProxyType::Governance => + call.value == U256::zero() && + matches!( PrecompileName::from_address(call.to.0), Some(ref precompile) if is_governance_precompile(precompile) - ) - }, + ), // The proxy precompile does not contain method cancel_proxy ProxyType::CancelProxy => false, ProxyType::Balances => { // Allow only "simple" accounts as recipient (no code nor precompile). // Note: Checking the presence of the code is not enough because some precompiles // have no code. - !recipient_has_code - && !precompile_utils::precompile_set::is_precompile_or_fail::( + !recipient_has_code && + !precompile_utils::precompile_set::is_precompile_or_fail::( call.to.0, gas, )? }, diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index 59b5818e..df56bbff 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -32,10 +32,9 @@ use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight, }; -use frame_support::derive_impl; -use frame_support::genesis_builder_helper::build_state; -use frame_support::genesis_builder_helper::get_preset; use frame_support::{ + derive_impl, + genesis_builder_helper::{build_state, get_preset}, traits::{ tokens::{PayFromAccount, UnityAssetBalanceConversion}, AsEnsureOriginWithArg, Contains, OnFinalize, WithdrawReasons, @@ -657,8 +656,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") - % max.saturating_add(1); + .expect("input is padded with zeroes; qed") % + max.saturating_add(1); random as usize }, }; @@ -1149,15 +1148,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) - | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) | + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) - | RuntimeCall::Council(..) - | RuntimeCall::Elections(..) - | RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | + RuntimeCall::Elections(..) | + RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1466,9 +1465,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -1478,11 +1476,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - }, + ))), _ => None, } } diff --git a/runtime/testnet/src/filters.rs b/runtime/testnet/src/filters.rs index 028238d3..1f7d32f3 100644 --- a/runtime/testnet/src/filters.rs +++ b/runtime/testnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for TestnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true; + return true } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false; + return false } true diff --git a/runtime/testnet/src/frontier_evm.rs b/runtime/testnet/src/frontier_evm.rs index 3fb74973..5b62c57b 100644 --- a/runtime/testnet/src/frontier_evm.rs +++ b/runtime/testnet/src/frontier_evm.rs @@ -64,7 +64,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) } None } @@ -99,7 +99,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation > as OnChargeEVMTransaction< @@ -116,7 +116,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation > as OnChargeEVMTransaction< diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index da36b14c..be3080a3 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -33,10 +33,9 @@ use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight, }; -use frame_support::derive_impl; -use frame_support::genesis_builder_helper::build_state; -use frame_support::genesis_builder_helper::get_preset; use frame_support::{ + derive_impl, + genesis_builder_helper::{build_state, get_preset}, traits::{ tokens::{PayFromAccount, UnityAssetBalanceConversion}, AsEnsureOriginWithArg, Contains, OnFinalize, WithdrawReasons, @@ -664,8 +663,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") - % max.saturating_add(1); + .expect("input is padded with zeroes; qed") % + max.saturating_add(1); random as usize }, }; @@ -1147,15 +1146,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) - | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) | + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) - | RuntimeCall::Council(..) - | RuntimeCall::Elections(..) - | RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | + RuntimeCall::Elections(..) | + RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1388,9 +1387,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -1400,11 +1398,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - }, + ))), _ => None, } } @@ -1618,7 +1615,8 @@ impl pallet_multi_asset_delegation::Config for Runtime { // parameter_types! { // // tTNT: native asset is always a reserved asset // pub NativeLocation: Location = Location::here(); -// pub NativeSygmaResourceId: [u8; 32] = hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000002000"); +// pub NativeSygmaResourceId: [u8; 32] = +// hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000002000"); // // SygUSD: a non-reserved asset // pub SygUSDLocation: Location = Location::new( @@ -1632,7 +1630,8 @@ impl pallet_multi_asset_delegation::Config for Runtime { // // SygUSDAssetId is the substrate assetID of SygUSD // pub SygUSDAssetId: AssetId = 2000; // // SygUSDResourceId is the resourceID that mapping with the foreign asset SygUSD -// pub SygUSDResourceId: ResourceId = hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000001100"); +// pub SygUSDResourceId: ResourceId = +// hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000001100"); // // PHA: a reserved asset // pub PHALocation: Location = Location::new( @@ -1646,8 +1645,8 @@ impl pallet_multi_asset_delegation::Config for Runtime { // // PHAAssetId is the substrate assetID of PHA // pub PHAAssetId: AssetId = 2001; // // PHAResourceId is the resourceID that mapping with the foreign asset PHA -// pub PHAResourceId: ResourceId = hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000001000"); -// } +// pub PHAResourceId: ResourceId = +// hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000001000"); } // fn bridge_accounts_generator() -> BTreeMap { // let mut account_map: BTreeMap = BTreeMap::new(); @@ -1677,7 +1676,8 @@ impl pallet_multi_asset_delegation::Config for Runtime { // pub const SygmaBridgePalletId: PalletId = PalletId(*b"sygma/01"); // // Tangle testnet super admin: 5D2hZnw8Z7kg5LpQiEBb6HPG4V51wYXuKhE7sVhXiUPWj8D1 -// pub SygmaBridgeAdminAccountKey: [u8; 32] = hex_literal::hex!("2ab4c35efb6ab82377c2325467103cf46742d288ae1f8917f1d5960f4a1e9065"); +// pub SygmaBridgeAdminAccountKey: [u8; 32] = +// hex_literal::hex!("2ab4c35efb6ab82377c2325467103cf46742d288ae1f8917f1d5960f4a1e9065"); // pub SygmaBridgeAdminAccount: AccountId = SygmaBridgeAdminAccountKey::get().into(); // // SygmaBridgeFeeAccount is a substrate account and used for bridging fee collection @@ -1687,18 +1687,22 @@ impl pallet_multi_asset_delegation::Config for Runtime { // // BridgeAccountNative: 5EYCAe5jLbHcAAMKvLFSXgCTbPrLgBJusvPwfKcaKzuf5X5e // pub BridgeAccountNative: AccountId32 = SygmaBridgePalletId::get().into_account_truncating(); // // BridgeAccountOtherToken 5EYCAe5jLbHcAAMKvLFiGhk3htXY8jQncbLTDGJQnpnPMAVp -// pub BridgeAccountOtherToken: AccountId32 = SygmaBridgePalletId::get().into_sub_account_truncating(1u32); -// // BridgeAccounts is a list of accounts for holding transferred asset collection -// pub BridgeAccounts: BTreeMap = bridge_accounts_generator(); +// pub BridgeAccountOtherToken: AccountId32 = +// SygmaBridgePalletId::get().into_sub_account_truncating(1u32); // BridgeAccounts is a list of +// accounts for holding transferred asset collection pub BridgeAccounts: BTreeMap = bridge_accounts_generator(); // // EIP712ChainID is the chainID that pallet is assigned with, used in EIP712 typed data domain // // For local testing with ./scripts/sygma-setup/execute_proposal_test.js, please change it to 5 // pub EIP712ChainID: ChainID = U256::from(3799); -// // DestVerifyingContractAddress is a H160 address that is used in proposal signature verification, specifically EIP712 typed data -// // When relayers signing, this address will be included in the EIP712Domain -// // As long as the relayer and pallet configured with the same address, EIP712Domain should be recognized properly. -// pub DestVerifyingContractAddress: VerifyingContractAddress = primitive_types::H160::from_slice(hex::decode(DEST_VERIFYING_CONTRACT_ADDRESS).ok().unwrap().as_slice()); +// // DestVerifyingContractAddress is a H160 address that is used in proposal signature +// verification, specifically EIP712 typed data // When relayers signing, this address will be +// included in the EIP712Domain // As long as the relayer and pallet configured with the same +// address, EIP712Domain should be recognized properly. pub DestVerifyingContractAddress: +// VerifyingContractAddress = +// primitive_types::H160::from_slice(hex::decode(DEST_VERIFYING_CONTRACT_ADDRESS).ok().unwrap(). +// as_slice()); // pub CheckingAccount: AccountId32 = AccountId32::new([102u8; 32]); @@ -1710,8 +1714,8 @@ impl pallet_multi_asset_delegation::Config for Runtime { // (PHALocation::get().into(), PHAResourceId::get()), // ]; -// pub AssetDecimalPairs: Vec<(XcmAssetId, u8)> = vec![(NativeLocation::get().into(), 18u8), (SygUSDLocation::get().into(), 6u8), (PHALocation::get().into(), 12u8)]; -// } +// pub AssetDecimalPairs: Vec<(XcmAssetId, u8)> = vec![(NativeLocation::get().into(), 18u8), +// (SygUSDLocation::get().into(), 6u8), (PHALocation::get().into(), 12u8)]; } // pub struct ReserveChecker; // impl ContainsPair for ReserveChecker { From 663f3749bfbb40ba7c147d2bac7f91d5a6095c04 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:35:38 +0530 Subject: [PATCH 04/63] clean slate --- .../src/benchmarking.rs | 2 +- .../multi-asset-delegation/src/functions.rs | 2 +- .../src/functions/delegate.rs | 95 ++++++------- .../src/functions/deposit.rs | 8 +- .../src/functions/operator.rs | 18 +-- .../src/functions/rewards.rs | 2 +- .../src/functions/session_manager.rs | 2 +- pallets/multi-asset-delegation/src/lib.rs | 129 +++++++++--------- pallets/multi-asset-delegation/src/mock.rs | 125 +++++++++-------- pallets/multi-asset-delegation/src/tests.rs | 2 +- .../src/tests/delegate.rs | 2 +- .../src/tests/deposit.rs | 2 +- .../src/tests/operator.rs | 8 +- .../src/tests/session_manager.rs | 2 +- pallets/multi-asset-delegation/src/traits.rs | 8 +- pallets/multi-asset-delegation/src/types.rs | 4 +- .../src/types/delegator.rs | 59 ++++---- .../src/types/operator.rs | 43 +++--- .../src/types/rewards.rs | 2 +- pallets/multi-asset-delegation/src/weights.rs | 2 +- 20 files changed, 249 insertions(+), 268 deletions(-) diff --git a/pallets/multi-asset-delegation/src/benchmarking.rs b/pallets/multi-asset-delegation/src/benchmarking.rs index 775214ec..b231ce4e 100644 --- a/pallets/multi-asset-delegation/src/benchmarking.rs +++ b/pallets/multi-asset-delegation/src/benchmarking.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/functions.rs b/pallets/multi-asset-delegation/src/functions.rs index 9425aa1a..e0a36c9a 100644 --- a/pallets/multi-asset-delegation/src/functions.rs +++ b/pallets/multi-asset-delegation/src/functions.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index c3c79ee1..beb35f31 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,15 +15,12 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{fungibles::Mutate, tokens::Preservation, Get}, -}; -use sp_runtime::{ - traits::{CheckedSub, Zero}, - DispatchError, Percent, -}; +use frame_support::traits::fungibles::Mutate; +use frame_support::traits::tokens::Preservation; +use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Get}; +use sp_runtime::traits::{CheckedSub, Zero}; +use sp_runtime::DispatchError; +use sp_runtime::Percent; use sp_std::vec::Vec; use tangle_primitives::BlueprintId; @@ -35,7 +32,7 @@ impl Pallet { /// /// * `who` - The account ID of the delegator. /// * `operator` - The account ID of the operator. - /// * `asset` - The asset to be delegated. + /// * `asset_id` - The ID of the asset to be delegated. /// * `amount` - The amount to be delegated. /// /// # Errors @@ -45,7 +42,7 @@ impl Pallet { pub fn process_delegate( who: T::AccountId, operator: T::AccountId, - asset: Asset, + asset_id: T::AssetId, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, ) -> DispatchResult { @@ -54,20 +51,20 @@ impl Pallet { // Ensure enough deposited balance let balance = - metadata.deposits.get_mut(&asset).ok_or(Error::::InsufficientBalance)?; + metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; ensure!(*balance >= amount, Error::::InsufficientBalance); // Reduce the balance in deposits *balance = balance.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; if *balance == Zero::zero() { - metadata.deposits.remove(&asset); + metadata.deposits.remove(&asset_id); } // Check if the delegation exists and update it, otherwise create a new delegation if let Some(delegation) = metadata .delegations .iter_mut() - .find(|d| d.operator == operator && d.asset == asset) + .find(|d| d.operator == operator && d.asset_id == asset_id) { delegation.amount += amount; } else { @@ -75,7 +72,7 @@ impl Pallet { let new_delegation = BondInfoDelegator { operator: operator.clone(), amount, - asset, + asset_id, blueprint_selection, }; @@ -99,13 +96,13 @@ impl Pallet { ); // Create and push the new delegation bond - let delegation = DelegatorBond { delegator: who.clone(), amount, asset }; + let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; let mut delegations = operator_metadata.delegations.clone(); // Check if delegation already exists if let Some(existing_delegation) = - delegations.iter_mut().find(|d| d.delegator == who && d.asset == asset) + delegations.iter_mut().find(|d| d.delegator == who && d.asset_id == asset_id) { existing_delegation.amount += amount; } else { @@ -121,7 +118,7 @@ impl Pallet { // Update storage Operators::::insert(&operator, operator_metadata); } else { - return Err(Error::::NotAnOperator.into()) + return Err(Error::::NotAnOperator.into()); } Ok(()) @@ -134,7 +131,7 @@ impl Pallet { /// /// * `who` - The account ID of the delegator. /// * `operator` - The account ID of the operator. - /// * `asset` - The asset to be reduced. + /// * `asset_id` - The ID of the asset to be reduced. /// * `amount` - The amount to be reduced. /// /// # Errors @@ -144,7 +141,7 @@ impl Pallet { pub fn process_schedule_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset: Asset, + asset_id: T::AssetId, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -154,7 +151,7 @@ impl Pallet { let delegation_index = metadata .delegations .iter() - .position(|d| d.operator == operator && d.asset == asset) + .position(|d| d.operator == operator && d.asset_id == asset_id) .ok_or(Error::::NoActiveDelegation)?; // Get the delegation and clone necessary data @@ -171,7 +168,7 @@ impl Pallet { unstake_requests .try_push(BondLessRequest { operator: operator.clone(), - asset, + asset_id, amount, requested_round: current_round, blueprint_selection, @@ -193,7 +190,7 @@ impl Pallet { let operator_delegation_index = operator_metadata .delegations .iter() - .position(|d| d.delegator == who && d.asset == asset) + .position(|d| d.delegator == who && d.asset_id == asset_id) .ok_or(Error::::NoActiveDelegation)?; let operator_delegation = @@ -243,7 +240,7 @@ impl Pallet { // Add the amount back to the delegator's deposits metadata .deposits - .entry(request.asset) + .entry(request.asset_id) .and_modify(|e| *e += request.amount) .or_insert(request.amount); executed_requests.push(request.clone()); @@ -265,8 +262,7 @@ impl Pallet { /// # Arguments /// /// * `who` - The account ID of the delegator. - /// * `operator` - The account ID of the operator. - /// * `asset` - The asset for which to cancel the unstake request. + /// * `asset_id` - The ID of the asset for which to cancel the unstake request. /// * `amount` - The amount of the unstake request to cancel. /// /// # Errors @@ -276,7 +272,7 @@ impl Pallet { pub fn process_cancel_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset: Asset, + asset_id: T::AssetId, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -286,7 +282,9 @@ impl Pallet { let request_index = metadata .delegator_unstake_requests .iter() - .position(|r| r.asset == asset && r.amount == amount && r.operator == operator) + .position(|r| { + r.asset_id == asset_id && r.amount == amount && r.operator == operator + }) .ok_or(Error::::NoBondLessRequest)?; let unstake_request = metadata.delegator_unstake_requests.remove(request_index); @@ -303,12 +301,12 @@ impl Pallet { let mut delegations = operator_metadata.delegations.clone(); if let Some(delegation) = delegations .iter_mut() - .find(|d| d.asset == asset && d.delegator == who.clone()) + .find(|d| d.asset_id == asset_id && d.delegator == who.clone()) { delegation.amount += amount; } else { delegations - .try_push(DelegatorBond { delegator: who.clone(), amount, asset }) + .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) .map_err(|_| Error::::MaxDelegationsExceeded)?; // Increase the delegation count only when a new delegation is added @@ -325,7 +323,7 @@ impl Pallet { // If a similar delegation exists, increase the amount if let Some(delegation) = delegations.iter_mut().find(|d| { - d.operator == unstake_request.operator && d.asset == unstake_request.asset + d.operator == unstake_request.operator && d.asset_id == unstake_request.asset_id }) { delegation.amount += unstake_request.amount; } else { @@ -334,7 +332,7 @@ impl Pallet { .try_push(BondInfoDelegator { operator: unstake_request.operator.clone(), amount: unstake_request.amount, - asset: unstake_request.asset, + asset_id: unstake_request.asset_id, blueprint_selection: unstake_request.blueprint_selection, }) .map_err(|_| Error::::MaxDelegationsExceeded)?; @@ -390,29 +388,14 @@ impl Pallet { .checked_sub(&slash_amount) .ok_or(Error::::InsufficientStakeRemaining)?; - // Handle the slashed amount based on asset type - match delegation.asset { - Asset::Custom(asset_id) => { - // For custom assets, transfer to the treasury - let _ = T::Fungibles::transfer( - asset_id, - &Self::pallet_account(), - &T::SlashedAmountRecipient::get(), - slash_amount, - Preservation::Expendable, - ); - }, - Asset::Erc20(contract_address) => { - // For ERC20 tokens, we need to handle differently - // This would typically involve interacting with the EVM to transfer tokens - // For now, we'll just emit an event - Self::deposit_event(Event::Erc20Slashed { - who: delegator.clone(), - contract_address, - amount: slash_amount, - }); - }, - } + // Transfer slashed amount to the treasury + let _ = T::Fungibles::transfer( + delegation.asset_id, + &Self::pallet_account(), + &T::SlashedAmountRecipient::get(), + slash_amount, + Preservation::Expendable, + ); // emit event Self::deposit_event(Event::DelegatorSlashed { diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 0605ece7..1e5cd4ed 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,11 +15,11 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; +use frame_support::traits::fungibles::Mutate; +use frame_support::{ensure, pallet_prelude::DispatchResult}; use frame_support::{ - ensure, - pallet_prelude::DispatchResult, sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, - traits::{fungibles::Mutate, tokens::Preservation, Get}, + traits::{tokens::Preservation, Get}, }; impl Pallet { diff --git a/pallets/multi-asset-delegation/src/functions/operator.rs b/pallets/multi-asset-delegation/src/functions/operator.rs index c193b4ee..e35a5fa2 100644 --- a/pallets/multi-asset-delegation/src/functions/operator.rs +++ b/pallets/multi-asset-delegation/src/functions/operator.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,17 +17,19 @@ /// Functions for the pallet. use super::*; use crate::{types::*, Pallet}; +use frame_support::traits::Currency; +use frame_support::traits::ExistenceRequirement; +use frame_support::BoundedVec; use frame_support::{ ensure, pallet_prelude::DispatchResult, - traits::{Currency, ExistenceRequirement, Get, ReservableCurrency}, - BoundedVec, + traits::{Get, ReservableCurrency}, }; -use sp_runtime::{ - traits::{CheckedAdd, CheckedSub}, - DispatchError, Percent, -}; -use tangle_primitives::{BlueprintId, ServiceManager}; +use sp_runtime::traits::{CheckedAdd, CheckedSub}; +use sp_runtime::DispatchError; +use sp_runtime::Percent; +use tangle_primitives::BlueprintId; +use tangle_primitives::ServiceManager; impl Pallet { /// Handles the deposit of stake amount and creation of an operator. diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs index bd79fd21..860e971e 100644 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ b/pallets/multi-asset-delegation/src/functions/rewards.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/functions/session_manager.rs b/pallets/multi-asset-delegation/src/functions/session_manager.rs index 20eb6c44..050f3b70 100644 --- a/pallets/multi-asset-delegation/src/functions/session_manager.rs +++ b/pallets/multi-asset-delegation/src/functions/session_manager.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index de5b66c8..a6f2f0db 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -79,19 +79,19 @@ pub mod pallet { use crate::types::*; use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction}; + use frame_support::traits::fungibles::Inspect; use frame_support::{ pallet_prelude::*, - traits::{ - fungibles::Inspect, tokens::fungibles, Currency, Get, LockableCurrency, - ReservableCurrency, - }, + traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, PalletId, }; use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; - use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; - use tangle_primitives::{traits::ServiceManager, BlueprintId, RoundIndex}; + use sp_std::vec::Vec; + use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; + use tangle_primitives::BlueprintId; + use tangle_primitives::{traits::ServiceManager, RoundIndex}; /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] @@ -99,96 +99,97 @@ pub mod pallet { /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; - /// The currency type for native token operations. + /// The currency type used for managing balances. type Currency: Currency + ReservableCurrency + LockableCurrency; - /// The minimum amount that an operator must bond. - #[pallet::constant] - type MinOperatorBondAmount: Get>; + /// Type representing the unique ID of an asset. + type AssetId: Parameter + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + Default + + MaxEncodedLen + + TypeInfo; + + /// Type representing the unique ID of a vault. + type VaultId: Parameter + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + Default + + MaxEncodedLen + + TypeInfo; - /// The duration of the bond. + /// The maximum number of blueprints a delegator can have in Fixed mode. #[pallet::constant] - type BondDuration: Get; + type MaxDelegatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - /// The service manager type. - type ServiceManager: ServiceManager>; + /// The maximum number of blueprints an operator can support. + #[pallet::constant] + type MaxOperatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - /// The number of rounds that must pass before an operator can leave. + /// The maximum number of withdraw requests a delegator can have. #[pallet::constant] - type LeaveOperatorsDelay: Get; + type MaxWithdrawRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - /// The number of rounds that must pass before an operator can reduce their bond. + /// The maximum number of delegations a delegator can have. #[pallet::constant] - type OperatorBondLessDelay: Get; + type MaxDelegations: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - /// The number of rounds that must pass before a delegator can leave. + /// The maximum number of unstake requests a delegator can have. #[pallet::constant] - type LeaveDelegatorsDelay: Get; + type MaxUnstakeRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - /// The number of rounds that must pass before a delegator can reduce their bond. + /// The minimum amount of stake required for an operator. #[pallet::constant] - type DelegationBondLessDelay: Get; + type MinOperatorBondAmount: Get>; - /// The minimum amount that can be delegated. + /// The minimum amount of stake required for a delegate. #[pallet::constant] type MinDelegateAmount: Get>; - /// The fungibles instance for handling multi-asset operations. - type Fungibles: fungibles::Inspect + fungibles::Mutate; - - /// The base asset ID type. - type AssetId: Member - + Parameter - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen; - - /// The vault ID type. - type VaultId: Member - + Parameter - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen; + /// The duration for which the stake is locked. + #[pallet::constant] + type BondDuration: Get; - /// The origin that can force certain operations. - type ForceOrigin: EnsureOrigin; + /// The service manager that manages active services. + type ServiceManager: ServiceManager>; - /// The pallet ID. + /// Number of rounds that operators remain bonded before the exit request is executable. #[pallet::constant] - type PalletId: Get; + type LeaveOperatorsDelay: Get; - /// The maximum number of blueprints a delegator can select. + /// Number of rounds operator requests to decrease self-stake must wait to be executable. #[pallet::constant] - type MaxDelegatorBlueprints: Get; + type OperatorBondLessDelay: Get; - /// The maximum number of blueprints an operator can select. + /// Number of rounds that delegators remain bonded before the exit request is executable. #[pallet::constant] - type MaxOperatorBlueprints: Get; + type LeaveDelegatorsDelay: Get; - /// The maximum number of withdraw requests. + /// Number of rounds that delegation unstake requests must wait before being executable. #[pallet::constant] - type MaxWithdrawRequests: Get; + type DelegationBondLessDelay: Get; - /// The maximum number of unstake requests. - #[pallet::constant] - type MaxUnstakeRequests: Get; + /// The fungibles trait used for managing fungible assets. + type Fungibles: fungibles::Inspect> + + fungibles::Mutate; - /// The maximum number of delegations. - #[pallet::constant] - type MaxDelegations: Get; + /// The pallet's account ID. + type PalletId: Get; - /// The account that receives slashed amounts. - #[pallet::constant] + /// The origin with privileged access + type ForceOrigin: EnsureOrigin; + + /// The address that receives slashed funds type SlashedAmountRecipient: Get; - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; + /// A type representing the weights required by the dispatchables of this pallet. + type WeightInfo: crate::weights::WeightInfo; } /// The pallet struct. diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index f5c83b48..3efa2be6 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use crate as pallet_multi_asset_delegation; -use crate::types::Asset; use frame_support::{ derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU16, ConstU32, ConstU64}, @@ -30,7 +29,7 @@ use sp_runtime::{ type Block = frame_system::mocking::MockBlock; pub type Balance = u64; -pub type AssetId = Asset; +pub type AssetId = u32; pub const ALICE: u64 = 1; pub const BOB: u64 = 2; @@ -38,7 +37,7 @@ pub const CHARLIE: u64 = 3; pub const DAVE: u64 = 4; pub const EVE: u64 = 5; -pub const VDOT: Asset = Asset::Vdot; +pub const VDOT: AssetId = 1; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( @@ -94,25 +93,46 @@ impl pallet_balances::Config for Test { type MaxFreezes = (); } -impl pallet_assets::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Balance = u64; - type AssetId = AssetId; - type AssetIdParameter = Asset; - type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = ConstU64<1>; - type AssetAccountDeposit = ConstU64<10>; - type MetadataDepositBase = ConstU64<1>; - type MetadataDepositPerByte = ConstU64<1>; - type ApprovalDeposit = ConstU64<1>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type WeightInfo = (); - type CallbackHandle = (); - type Extra = (); - type RemoveItemsLimit = ConstU32<5>; +pub struct MockServiceManager; + +impl tangle_primitives::ServiceManager for MockServiceManager { + fn get_active_blueprints_count(_account: &u64) -> usize { + // we dont care + Default::default() + } + + fn get_active_services_count(_account: &u64) -> usize { + // we dont care + Default::default() + } + + fn can_exit(_account: &u64) -> bool { + // Mock logic to determine if the given account can exit + true + } + + fn get_blueprints_by_operator(_account: &u64) -> Vec { + todo!(); // we dont care + } +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaxLocks: u32 = 50; + pub const MinOperatorBondAmount: u64 = 10_000; + pub const BondDuration: u32 = 10; + pub PID: PalletId = PalletId(*b"PotStake"); + pub const SlashedAmountRecipient : u64 = 0; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxOperatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxWithdrawRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxUnstakeRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegations: u32 = 50; } impl pallet_multi_asset_delegation::Config for Test { @@ -140,46 +160,25 @@ impl pallet_multi_asset_delegation::Config for Test { type WeightInfo = (); } -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaxLocks: u32 = 50; - pub const MinOperatorBondAmount: u64 = 10_000; - pub const BondDuration: u32 = 10; - pub PID: PalletId = PalletId(*b"PotStake"); - pub const SlashedAmountRecipient : u64 = 0; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxDelegatorBlueprints : u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxOperatorBlueprints : u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxWithdrawRequests: u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxUnstakeRequests: u32 = 50; - #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] - pub const MaxDelegations: u32 = 50; -} - -pub struct MockServiceManager; - -impl tangle_primitives::ServiceManager for MockServiceManager { - fn get_active_blueprints_count(_account: &u64) -> usize { - // we dont care - Default::default() - } - - fn get_active_services_count(_account: &u64) -> usize { - // we dont care - Default::default() - } - - fn can_exit(_account: &u64) -> bool { - // Mock logic to determine if the given account can exit - true - } - - fn get_blueprints_by_operator(_account: &u64) -> Vec { - todo!(); // we dont care - } +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = u64; + type AssetId = AssetId; + type AssetIdParameter = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/pallets/multi-asset-delegation/src/tests.rs b/pallets/multi-asset-delegation/src/tests.rs index 98ada29e..376a1b43 100644 --- a/pallets/multi-asset-delegation/src/tests.rs +++ b/pallets/multi-asset-delegation/src/tests.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 71e96e08..4bde5eb3 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index da0b5f28..7f5aa809 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index e4332d03..27a855d3 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::{ - types::{DelegatorBlueprintSelection::Fixed, OperatorStatus}, - CurrentRound, Error, -}; +use crate::types::DelegatorBlueprintSelection::Fixed; +use crate::{types::OperatorStatus, CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; use sp_runtime::Percent; diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index ab0058c3..19224df2 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/traits.rs b/pallets/multi-asset-delegation/src/traits.rs index 973b3ec5..d7877ba6 100644 --- a/pallets/multi-asset-delegation/src/traits.rs +++ b/pallets/multi-asset-delegation/src/traits.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,9 +15,11 @@ // along with Tangle. If not, see . use super::*; use crate::types::{BalanceOf, OperatorStatus}; -use sp_runtime::{traits::Zero, Percent}; +use sp_runtime::traits::Zero; +use sp_runtime::Percent; use sp_std::prelude::*; -use tangle_primitives::{traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex}; +use tangle_primitives::BlueprintId; +use tangle_primitives::{traits::MultiAssetDelegationInfo, RoundIndex}; impl MultiAssetDelegationInfo> for crate::Pallet { type AssetId = T::AssetId; diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index e1ba3eb8..a1b0cb4d 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,12 +22,10 @@ use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::RoundIndex; -pub mod asset; pub mod delegator; pub mod operator; pub mod rewards; -pub use asset::*; pub use delegator::*; pub use operator::*; pub use rewards::*; diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 0c1ade38..50a31511 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,7 +15,6 @@ // along with Tangle. If not, see . use super::*; -use crate::types::Asset; use frame_support::{pallet_prelude::Get, BoundedVec}; use tangle_primitives::BlueprintId; @@ -47,9 +46,9 @@ pub enum DelegatorStatus { /// Represents a request to withdraw a specific amount of an asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct WithdrawRequest { - /// The asset to be withdrawn. - pub asset: Asset, - /// The amount of the asset to be withdrawn. + /// The ID of the asset to be withdrawd. + pub asset_id: AssetId, + /// The amount of the asset to be withdrawd. pub amount: Balance, /// The round in which the withdraw was requested. pub requested_round: RoundIndex, @@ -60,8 +59,8 @@ pub struct WithdrawRequest { pub struct BondLessRequest> { /// The account ID of the operator. pub operator: AccountId, - /// The asset to reduce the stake of. - pub asset: Asset, + /// The ID of the asset to reduce the stake of. + pub asset_id: AssetId, /// The amount by which to reduce the stake. pub amount: Balance, /// The round in which the stake reduction was requested. @@ -82,7 +81,7 @@ pub struct DelegatorMetadata< MaxBlueprints: Get, > { /// A map of deposited assets and their respective amounts. - pub deposits: BTreeMap, Balance>, + pub deposits: BTreeMap, /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. @@ -169,14 +168,14 @@ impl< } /// Calculates the total delegation amount for a specific asset. - pub fn calculate_delegation_by_asset(&self, asset: Asset) -> Balance + pub fn calculate_delegation_by_asset(&self, asset_id: AssetId) -> Balance where Balance: Default + core::ops::AddAssign + Clone, AssetId: Eq + PartialEq, { let mut total = Balance::default(); for stake in &self.delegations { - if stake.asset == asset { + if stake.asset_id == asset_id { total += stake.amount.clone(); } } @@ -200,8 +199,8 @@ impl< pub struct Deposit { /// The amount of the asset deposited. pub amount: Balance, - /// The asset deposited. - pub asset: Asset, + /// The ID of the deposited asset. + pub asset_id: AssetId, } /// Represents a stake between a delegator and an operator. @@ -211,8 +210,8 @@ pub struct BondInfoDelegator, + /// The ID of the bonded asset. + pub asset_id: AssetId, /// The blueprint selection mode for this delegator. pub blueprint_selection: DelegatorBlueprintSelection, } @@ -285,12 +284,12 @@ mod tests { fn get_withdraw_requests_should_work() { let withdraw_requests = vec![ WithdrawRequest { - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), amount: MockBalance(50), requested_round: 1, }, WithdrawRequest { - asset: Asset(MockAssetId(2)), + asset_id: MockAssetId(2), amount: MockBalance(75), requested_round: 2, }, @@ -309,13 +308,13 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(75), - asset: Asset(MockAssetId(2)), + asset_id: MockAssetId(2), blueprint_selection: Default::default(), }, ]; @@ -332,14 +331,14 @@ mod tests { fn get_delegator_unstake_requests_should_work() { let unstake_requests = vec![ BondLessRequest { - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), amount: MockBalance(50), requested_round: 1, operator: MockAccountId(1), blueprint_selection: Default::default(), }, BondLessRequest { - asset: Asset(MockAssetId(2)), + asset_id: MockAssetId(2), amount: MockBalance(75), requested_round: 2, operator: MockAccountId(1), @@ -360,7 +359,7 @@ mod tests { delegations: BoundedVec::try_from(vec![BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }]) .unwrap(), @@ -379,19 +378,19 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(75), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(3), amount: MockBalance(25), - asset: Asset(MockAssetId(2)), + asset_id: MockAssetId(2), blueprint_selection: Default::default(), }, ]; @@ -400,9 +399,9 @@ mod tests { ..Default::default() }; - assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(1))), MockBalance(125)); - assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(2))), MockBalance(25)); - assert_eq!(metadata.calculate_delegation_by_asset(Asset(MockAssetId(3))), MockBalance(0)); + assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(1)), MockBalance(125)); + assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(2)), MockBalance(25)); + assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(3)), MockBalance(0)); } #[test] @@ -411,19 +410,19 @@ mod tests { BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(50), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(1), amount: MockBalance(75), - asset: Asset(MockAssetId(2)), + asset_id: MockAssetId(2), blueprint_selection: Default::default(), }, BondInfoDelegator { operator: MockAccountId(2), amount: MockBalance(25), - asset: Asset(MockAssetId(1)), + asset_id: MockAssetId(1), blueprint_selection: Default::default(), }, ]; diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 9c81a0cd..c34fe001 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,7 +15,6 @@ // along with Tangle. If not, see . use super::*; -use crate::types::Asset; use frame_support::{pallet_prelude::*, BoundedVec}; /// A snapshot of the operator state at the start of the round. @@ -39,7 +38,7 @@ where pub fn get_stake_by_asset_id(&self, asset_id: AssetId) -> Balance { let mut total_stake = Balance::default(); for stake in &self.delegations { - if stake.asset.id == asset_id { + if stake.asset_id == asset_id { total_stake += stake.amount; } } @@ -51,7 +50,7 @@ where let mut stake_by_asset: BTreeMap = BTreeMap::new(); for stake in &self.delegations { - let entry = stake_by_asset.entry(stake.asset.id).or_default(); + let entry = stake_by_asset.entry(stake.asset_id).or_default(); *entry += stake.amount; } @@ -80,17 +79,6 @@ pub struct OperatorBondLessRequest { pub request_time: RoundIndex, } -/// Represents a delegation from a delegator to an operator. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct DelegatorBond { - /// The delegator's account ID. - pub delegator: AccountId, - /// The amount bonded. - pub amount: Balance, - /// The asset bonded. - pub asset: Asset, -} - /// Stores the metadata of an operator. #[derive(Encode, Decode, RuntimeDebug, TypeInfo, Clone, Eq, PartialEq)] pub struct OperatorMetadata< @@ -132,6 +120,17 @@ where } } +/// Represents a stake for an operator +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] +pub struct DelegatorBond { + /// The account ID of the delegator. + pub delegator: AccountId, + /// The amount bonded. + pub amount: Balance, + /// The ID of the bonded asset. + pub asset_id: AssetId, +} + // ------ Test for helper functions ------ // #[cfg(test)] @@ -191,17 +190,17 @@ mod tests { DelegatorBond { delegator: MockAccountId(1), amount: MockBalance(50), - asset: Asset { id: MockAssetId(1), ..Default::default() }, + asset_id: MockAssetId(1), }, DelegatorBond { delegator: MockAccountId(2), amount: MockBalance(75), - asset: Asset { id: MockAssetId(1), ..Default::default() }, + asset_id: MockAssetId(1), }, DelegatorBond { delegator: MockAccountId(3), amount: MockBalance(25), - asset: Asset { id: MockAssetId(2), ..Default::default() }, + asset_id: MockAssetId(2), }, ]) .unwrap(), @@ -221,22 +220,22 @@ mod tests { DelegatorBond { delegator: MockAccountId(1), amount: MockBalance(50), - asset: Asset { id: MockAssetId(1), ..Default::default() }, + asset_id: MockAssetId(1), }, DelegatorBond { delegator: MockAccountId(2), amount: MockBalance(75), - asset: Asset { id: MockAssetId(1), ..Default::default() }, + asset_id: MockAssetId(1), }, DelegatorBond { delegator: MockAccountId(3), amount: MockBalance(25), - asset: Asset { id: MockAssetId(2), ..Default::default() }, + asset_id: MockAssetId(2), }, DelegatorBond { delegator: MockAccountId(4), amount: MockBalance(100), - asset: Asset { id: MockAssetId(2), ..Default::default() }, + asset_id: MockAssetId(2), }, ]) .unwrap(), diff --git a/pallets/multi-asset-delegation/src/types/rewards.rs b/pallets/multi-asset-delegation/src/types/rewards.rs index f345c45a..6a1daad7 100644 --- a/pallets/multi-asset-delegation/src/types/rewards.rs +++ b/pallets/multi-asset-delegation/src/types/rewards.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pallets/multi-asset-delegation/src/weights.rs b/pallets/multi-asset-delegation/src/weights.rs index 37c381ce..665c6195 100644 --- a/pallets/multi-asset-delegation/src/weights.rs +++ b/pallets/multi-asset-delegation/src/weights.rs @@ -1,5 +1,5 @@ // This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. +// Copyright (C) 2022-2024 Tangle Foundation. // // Tangle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by From 5a677c8c250c9463bf8a04c9e7d263aa47d8b1ea Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:52:58 +0530 Subject: [PATCH 05/63] use common exports --- .../src/functions/delegate.rs | 7 +- .../src/functions/deposit.rs | 7 +- pallets/multi-asset-delegation/src/lib.rs | 24 +++---- .../multi-asset-delegation/src/types/asset.rs | 66 ------------------- .../src/types/delegator.rs | 21 +++--- .../src/types/operator.rs | 13 ++-- .../src/types/rewards.rs | 1 + primitives/src/services/mod.rs | 6 +- 8 files changed, 43 insertions(+), 102 deletions(-) delete mode 100644 pallets/multi-asset-delegation/src/types/asset.rs diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index beb35f31..85cc6588 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; +use tangle_primitives::services::Asset; use frame_support::traits::fungibles::Mutate; use frame_support::traits::tokens::Preservation; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Get}; @@ -42,7 +43,7 @@ impl Pallet { pub fn process_delegate( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, ) -> DispatchResult { @@ -141,7 +142,7 @@ impl Pallet { pub fn process_schedule_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -272,7 +273,7 @@ impl Pallet { pub fn process_cancel_delegator_unstake( who: T::AccountId, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 1e5cd4ed..6bf289fe 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; +use tangle_primitives::services::Asset; use frame_support::traits::fungibles::Mutate; use frame_support::{ensure, pallet_prelude::DispatchResult}; use frame_support::{ @@ -42,7 +43,7 @@ impl Pallet { /// the transfer fails. pub fn process_deposit( who: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); @@ -87,7 +88,7 @@ impl Pallet { /// asset is not supported. pub fn process_schedule_withdraw( who: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { @@ -172,7 +173,7 @@ impl Pallet { /// Returns an error if the user is not a delegator or if there is no matching withdraw request. pub fn process_cancel_withdraw( who: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index a6f2f0db..6b1abdd8 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -77,7 +77,7 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { use crate::types::*; - + use tangle_primitives::services::Asset; use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction}; use frame_support::traits::fungibles::Inspect; use frame_support::{ @@ -112,6 +112,8 @@ pub mod pallet { + Ord + Default + MaxEncodedLen + + Encode + + Decode + TypeInfo; /// Type representing the unique ID of a vault. @@ -283,14 +285,14 @@ pub mod pallet { who: T::AccountId, operator: T::AccountId, amount: BalanceOf, - asset_id: T::AssetId, + asset_id: Asset, }, /// A delegator unstake request has been scheduled. ScheduledDelegatorBondLess { who: T::AccountId, operator: T::AccountId, amount: BalanceOf, - asset_id: T::AssetId, + asset_id: Asset, }, /// A delegator unstake request has been executed. ExecutedDelegatorBondLess { who: T::AccountId }, @@ -304,7 +306,7 @@ pub mod pallet { AssetUpdatedInVault { who: T::AccountId, vault_id: T::VaultId, - asset_id: T::AssetId, + asset_id: Asset, action: AssetAction, }, /// Operator has been slashed @@ -530,7 +532,7 @@ pub mod pallet { #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn deposit( origin: OriginFor, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -544,7 +546,7 @@ pub mod pallet { #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn schedule_withdraw( origin: OriginFor, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -568,7 +570,7 @@ pub mod pallet { #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn cancel_withdraw( origin: OriginFor, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -583,7 +585,7 @@ pub mod pallet { pub fn delegate( origin: OriginFor, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, ) -> DispatchResult { @@ -605,7 +607,7 @@ pub mod pallet { pub fn schedule_delegator_unstake( origin: OriginFor, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -640,7 +642,7 @@ pub mod pallet { pub fn cancel_delegator_unstake( origin: OriginFor, operator: T::AccountId, - asset_id: T::AssetId, + asset_id: Asset, amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -735,7 +737,7 @@ pub mod pallet { pub fn manage_asset_in_vault( origin: OriginFor, vault_id: T::VaultId, - asset_id: T::AssetId, + asset_id: Asset, action: AssetAction, ) -> DispatchResult { let who = ensure_signed(origin)?; diff --git a/pallets/multi-asset-delegation/src/types/asset.rs b/pallets/multi-asset-delegation/src/types/asset.rs deleted file mode 100644 index 6c3afc91..00000000 --- a/pallets/multi-asset-delegation/src/types/asset.rs +++ /dev/null @@ -1,66 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Webb Technologies Inc. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -use parity_scale_codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_core::H160; -use sp_runtime::RuntimeDebug; - -/// Represents an asset type that can be either a custom asset or an ERC20 token. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] -pub enum Asset { - /// Use the specified AssetId. - #[codec(index = 0)] - Custom(AssetId), - - /// Use an ERC20-like token with the specified contract address. - #[codec(index = 1)] - Erc20(H160), -} - -impl Default for Asset { - fn default() -> Self { - Asset::Custom(AssetId::default()) - } -} - -impl Asset { - /// Returns true if the asset is an ERC20 token. - pub fn is_erc20(&self) -> bool { - matches!(self, Asset::Erc20(_)) - } - - /// Returns true if the asset is a custom asset. - pub fn is_custom(&self) -> bool { - matches!(self, Asset::Custom(_)) - } - - /// Returns the ERC20 address if this is an ERC20 token. - pub fn erc20_address(&self) -> Option { - match self { - Asset::Erc20(address) => Some(*address), - _ => None, - } - } - - /// Returns the custom asset ID if this is a custom asset. - pub fn custom_id(&self) -> Option<&AssetId> { - match self { - Asset::Custom(id) => Some(id), - _ => None, - } - } -} diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 50a31511..6fb7b371 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -17,6 +17,7 @@ use super::*; use frame_support::{pallet_prelude::Get, BoundedVec}; use tangle_primitives::BlueprintId; +use tangle_primitives::services::Asset; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -45,9 +46,9 @@ pub enum DelegatorStatus { /// Represents a request to withdraw a specific amount of an asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct WithdrawRequest { +pub struct WithdrawRequest { /// The ID of the asset to be withdrawd. - pub asset_id: AssetId, + pub asset_id: Asset, /// The amount of the asset to be withdrawd. pub amount: Balance, /// The round in which the withdraw was requested. @@ -56,11 +57,11 @@ pub struct WithdrawRequest { /// Represents a request to reduce the bonded amount of a specific asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct BondLessRequest> { +pub struct BondLessRequest> { /// The account ID of the operator. pub operator: AccountId, /// The ID of the asset to reduce the stake of. - pub asset_id: AssetId, + pub asset_id: Asset, /// The amount by which to reduce the stake. pub amount: Balance, /// The round in which the stake reduction was requested. @@ -81,7 +82,7 @@ pub struct DelegatorMetadata< MaxBlueprints: Get, > { /// A map of deposited assets and their respective amounts. - pub deposits: BTreeMap, + pub deposits: BTreeMap, Balance>, /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. @@ -168,7 +169,7 @@ impl< } /// Calculates the total delegation amount for a specific asset. - pub fn calculate_delegation_by_asset(&self, asset_id: AssetId) -> Balance + pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance // Asset) -> Balance where Balance: Default + core::ops::AddAssign + Clone, AssetId: Eq + PartialEq, @@ -196,22 +197,22 @@ impl< /// Represents a deposit of a specific asset. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct Deposit { +pub struct Deposit { /// The amount of the asset deposited. pub amount: Balance, /// The ID of the deposited asset. - pub asset_id: AssetId, + pub asset_id: Asset, } /// Represents a stake between a delegator and an operator. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct BondInfoDelegator> { +pub struct BondInfoDelegator> { /// The account ID of the operator. pub operator: AccountId, /// The amount bonded. pub amount: Balance, /// The ID of the bonded asset. - pub asset_id: AssetId, + pub asset_id: Asset, /// The blueprint selection mode for this delegator. pub blueprint_selection: DelegatorBlueprintSelection, } diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index c34fe001..5c3ad29c 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -16,10 +16,11 @@ use super::*; use frame_support::{pallet_prelude::*, BoundedVec}; +use tangle_primitives::services::Asset; /// A snapshot of the operator state at the start of the round. #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct OperatorSnapshot> { +pub struct OperatorSnapshot> { /// The total value locked by the operator. pub stake: Balance, @@ -28,7 +29,7 @@ pub struct OperatorSnapshot, MaxDelegations>, } -impl> +impl> OperatorSnapshot where AssetId: PartialEq + Ord + Copy, @@ -84,7 +85,7 @@ pub struct OperatorBondLessRequest { pub struct OperatorMetadata< AccountId, Balance, - AssetId, + AssetId : Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, > { @@ -103,7 +104,7 @@ pub struct OperatorMetadata< pub blueprint_ids: BoundedVec, } -impl, MaxBlueprints: Get> Default +impl, MaxBlueprints: Get> Default for OperatorMetadata where Balance: Default, @@ -122,13 +123,13 @@ where /// Represents a stake for an operator #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond { +pub struct DelegatorBond { /// The account ID of the delegator. pub delegator: AccountId, /// The amount bonded. pub amount: Balance, /// The ID of the bonded asset. - pub asset_id: AssetId, + pub asset_id: Asset, } // ------ Test for helper functions ------ // diff --git a/pallets/multi-asset-delegation/src/types/rewards.rs b/pallets/multi-asset-delegation/src/types/rewards.rs index 6a1daad7..488694c3 100644 --- a/pallets/multi-asset-delegation/src/types/rewards.rs +++ b/pallets/multi-asset-delegation/src/types/rewards.rs @@ -16,6 +16,7 @@ use super::*; use sp_runtime::Percent; +use tangle_primitives::services::Asset; /// Configuration for rewards associated with a specific asset. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index a27a26c9..621f0107 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -626,7 +626,7 @@ pub enum ApprovalState { /// Different types of assets that can be used. #[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Copy, Clone, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Asset { +pub enum Asset { /// Use the specified AssetId. #[codec(index = 0)] Custom(AssetId), @@ -636,13 +636,13 @@ pub enum Asset { Erc20(sp_core::H160), } -impl Default for Asset { +impl Default for Asset { fn default() -> Self { Asset::Custom(sp_runtime::traits::Zero::zero()) } } -impl Asset { +impl Asset { pub fn to_ethabi_param_type() -> ethabi::ParamType { ethabi::ParamType::Tuple(vec![ // Kind of the Asset From 5e53247110a37bba815a031bba3538f2325c55ee Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:53:58 +0530 Subject: [PATCH 06/63] use common exports --- pallets/multi-asset-delegation/src/types/delegator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 6fb7b371..59dbfa88 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -71,7 +71,7 @@ pub struct BondLessRequest Date: Thu, 12 Dec 2024 18:51:55 +0530 Subject: [PATCH 07/63] wip --- pallets/multi-asset-delegation/src/types/delegator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 59dbfa88..6fb7b371 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -71,7 +71,7 @@ pub struct BondLessRequest Date: Fri, 13 Dec 2024 13:38:30 +0530 Subject: [PATCH 08/63] wip --- Cargo.lock | 2 + pallets/multi-asset-delegation/Cargo.toml | 6 +- .../multi-asset-delegation/src/functions.rs | 1 + .../src/functions/delegate.rs | 28 ++++--- .../src/functions/deposit.rs | 47 ++++++++++-- .../src/functions/evm.rs | 74 +++++++++++++++++++ pallets/multi-asset-delegation/src/lib.rs | 14 +++- .../src/types/delegator.rs | 14 ++-- .../src/types/operator.rs | 18 +++-- primitives/src/services/mod.rs | 2 +- primitives/src/traits/services.rs | 11 +++ 11 files changed, 182 insertions(+), 35 deletions(-) create mode 100644 pallets/multi-asset-delegation/src/functions/evm.rs diff --git a/Cargo.lock b/Cargo.lock index 7822e3d5..fd8bfcbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8282,9 +8282,11 @@ dependencies = [ name = "pallet-multi-asset-delegation" version = "1.2.3" dependencies = [ + "ethabi", "frame-benchmarking", "frame-support", "frame-system", + "log", "pallet-assets", "pallet-balances", "parity-scale-codec", diff --git a/pallets/multi-asset-delegation/Cargo.toml b/pallets/multi-asset-delegation/Cargo.toml index 45be4fb2..379b972a 100644 --- a/pallets/multi-asset-delegation/Cargo.toml +++ b/pallets/multi-asset-delegation/Cargo.toml @@ -13,10 +13,12 @@ frame-support = { workspace = true } frame-system = { workspace = true } parity-scale-codec = { workspace = true } scale-info = { workspace = true } +log = { workspace = true } sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } +ethabi = { workspace = true } pallet-balances = { workspace = true } tangle-primitives = { workspace = true } pallet-assets = { workspace = true, default-features = false } @@ -33,7 +35,9 @@ std = [ "sp-std/std", "pallet-balances/std", "pallet-assets/std", - "tangle-primitives/std" + "tangle-primitives/std", + "ethabi/std", + "log/std" ] try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ diff --git a/pallets/multi-asset-delegation/src/functions.rs b/pallets/multi-asset-delegation/src/functions.rs index e0a36c9a..bcf33acf 100644 --- a/pallets/multi-asset-delegation/src/functions.rs +++ b/pallets/multi-asset-delegation/src/functions.rs @@ -20,3 +20,4 @@ pub mod deposit; pub mod operator; pub mod rewards; pub mod session_manager; +pub mod evm; diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 85cc6588..39322fc0 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,7 +15,6 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use tangle_primitives::services::Asset; use frame_support::traits::fungibles::Mutate; use frame_support::traits::tokens::Preservation; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Get}; @@ -23,6 +22,7 @@ use sp_runtime::traits::{CheckedSub, Zero}; use sp_runtime::DispatchError; use sp_runtime::Percent; use sp_std::vec::Vec; +use tangle_primitives::services::Asset; use tangle_primitives::BlueprintId; impl Pallet { @@ -389,14 +389,24 @@ impl Pallet { .checked_sub(&slash_amount) .ok_or(Error::::InsufficientStakeRemaining)?; - // Transfer slashed amount to the treasury - let _ = T::Fungibles::transfer( - delegation.asset_id, - &Self::pallet_account(), - &T::SlashedAmountRecipient::get(), - slash_amount, - Preservation::Expendable, - ); + match delegation.asset_id { + Asset::Custom(asset_id) => { + // Transfer slashed amount to the treasury + let _ = T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &T::SlashedAmountRecipient::get(), + slash_amount, + Preservation::Expendable, + ); + }, + Asset::Erc20(address) => { + // TODO : Handle it + // let (success, _weight) = + // Self::erc20_transfer(address, &caller, Self::address(), value)?; + // ensure!(success, Error::::ERC20TransferFailed); + }, + } // emit event Self::deposit_event(Event::DelegatorSlashed { diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 6bf289fe..500861e6 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -15,13 +15,15 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use tangle_primitives::services::Asset; use frame_support::traits::fungibles::Mutate; use frame_support::{ensure, pallet_prelude::DispatchResult}; use frame_support::{ sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, traits::{tokens::Preservation, Get}, }; +use sp_core::H160; +use tangle_primitives::EvmAddressMapping; +use tangle_primitives::services::Asset; impl Pallet { /// Returns the account ID of the pallet. @@ -29,6 +31,41 @@ impl Pallet { T::PalletId::get().into_account_truncating() } + /// Returns the EVM account id of the pallet. + /// + /// This function retrieves the account id associated with the pallet by converting + /// the pallet evm address to an account id. + /// + /// # Returns + /// * `T::AccountId` - The account id of the pallet. + pub fn pallet_evm_account() -> H160 { + T::EvmAddressMapping::into_address(Self::pallet_account()) + } + + pub fn handle_transfer_to_pallet( + sender: &T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + match asset_id { + Asset::Custom(asset_id) => { + T::Fungibles::transfer( + asset_id, + &sender, + &Self::pallet_account(), + amount, + Preservation::Expendable, + ); + }, + Asset::Erc20(asset_address) => { + let (success, _weight) = + Self::erc20_transfer(asset_address, &sender, Self::pallet_evm_account(), amount).map_err(|_| Error::::ERC20TransferFailed)?; + ensure!(success, Error::::ERC20TransferFailed); + } + } + Ok(()) + } + /// Processes the deposit of assets into the pallet. /// /// # Arguments @@ -49,13 +86,7 @@ impl Pallet { ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); // Transfer the amount to the pallet account - T::Fungibles::transfer( - asset_id, - &who, - &Self::pallet_account(), - amount, - Preservation::Expendable, - )?; + Self::handle_transfer_to_pallet(&who, asset_id, amount)?; // Update storage Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs new file mode 100644 index 00000000..bccc44b0 --- /dev/null +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -0,0 +1,74 @@ +use super::*; +use ethabi::{Function, StateMutability, Token}; +use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; +use sp_core::{H160, U256}; +use crate::types::BalanceOf; +use frame_support::pallet_prelude::Weight; +use tangle_primitives::EvmAddressMapping; + +impl Pallet { + + /// Moves a `value` amount of tokens from the caller's account to `to`. + pub fn erc20_transfer( + erc20: H160, + caller: &T::AccountId, + to: H160, + value: BalanceOf, + ) -> Result<(bool, Weight), DispatchErrorWithPostInfo> { + let from = T::EvmAddressMapping::into_address(caller.clone()); + #[allow(deprecated)] + let transfer_fn = Function { + name: String::from("transfer"), + inputs: vec![ + ethabi::Param { + name: String::from("to"), + kind: ethabi::ParamType::Address, + internal_type: None, + }, + ethabi::Param { + name: String::from("value"), + kind: ethabi::ParamType::Uint(256), + internal_type: None, + }, + ], + outputs: vec![ethabi::Param { + name: String::from("success"), + kind: ethabi::ParamType::Bool, + internal_type: None, + }], + constant: None, + state_mutability: StateMutability::NonPayable, + }; + + let args = [ + Token::Address(to), + Token::Uint(ethabi::Uint::from(value.using_encoded(U256::from_little_endian))), + ]; + + log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(transfer_fn.short_signature()), transfer_fn.signature()); + let data = transfer_fn.encode_input(&args).map_err(|_| Error::::EVMAbiEncode)?; + let gas_limit = 300_000; + let info = Self::evm_call(from, erc20, U256::zero(), data, gas_limit)?; + let weight = Self::weight_from_call_info(&info); + + // decode the result and return it + let maybe_value = info.exit_reason.is_succeed().then_some(&info.value); + let success = if let Some(data) = maybe_value { + let result = transfer_fn.decode_output(data).map_err(|_| Error::::EVMAbiDecode)?; + let success = result.first().ok_or_else(|| Error::::EVMAbiDecode)?; + if let ethabi::Token::Bool(val) = success { + *val + } else { + false + } + } else { + false + }; + + Ok((success, weight)) + } + + + + +} \ No newline at end of file diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 6b1abdd8..81ca7c3d 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -77,7 +77,6 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { use crate::types::*; - use tangle_primitives::services::Asset; use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction}; use frame_support::traits::fungibles::Inspect; use frame_support::{ @@ -90,6 +89,7 @@ pub mod pallet { use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; use sp_std::vec::Vec; use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; + use tangle_primitives::services::Asset; use tangle_primitives::BlueprintId; use tangle_primitives::{traits::ServiceManager, RoundIndex}; @@ -190,6 +190,9 @@ pub mod pallet { /// The address that receives slashed funds type SlashedAmountRecipient: Get; + /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address + type EvmAddressMapping: tangle_primitives::traits::EvmAddressMapping; + /// A type representing the weights required by the dispatchables of this pallet. type WeightInfo: crate::weights::WeightInfo; } @@ -412,6 +415,8 @@ pub mod pallet { PendingUnstakeRequestExists, /// The blueprint is not selected BlueprintNotSelected, + /// Erc20 transfer failed + ERC20TransferFailed } /// Hooks for the pallet. @@ -583,11 +588,12 @@ pub mod pallet { #[pallet::call_index(14)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn delegate( - origin: OriginFor, - operator: T::AccountId, - asset_id: Asset, + origin: OriginFor, // 5cxssdfsd + operator: T::AccountId, // xcxcv + asset_id: Asset, // evm(usdt) amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, + //evm_address : Option, // Some(shady_evm_address) ) -> DispatchResult { let who = ensure_signed(origin)?; Self::process_delegate( diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 6fb7b371..0dbfc1b0 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -16,8 +16,8 @@ use super::*; use frame_support::{pallet_prelude::Get, BoundedVec}; -use tangle_primitives::BlueprintId; use tangle_primitives::services::Asset; +use tangle_primitives::BlueprintId; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -46,7 +46,7 @@ pub enum DelegatorStatus { /// Represents a request to withdraw a specific amount of an asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct WithdrawRequest { +pub struct WithdrawRequest { /// The ID of the asset to be withdrawd. pub asset_id: Asset, /// The amount of the asset to be withdrawd. @@ -57,7 +57,7 @@ pub struct WithdrawRequest { /// Represents a request to reduce the bonded amount of a specific asset. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct BondLessRequest> { +pub struct BondLessRequest> { /// The account ID of the operator. pub operator: AccountId, /// The ID of the asset to reduce the stake of. @@ -169,7 +169,8 @@ impl< } /// Calculates the total delegation amount for a specific asset. - pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance // Asset) -> Balance + pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance + // Asset) -> Balance where Balance: Default + core::ops::AddAssign + Clone, AssetId: Eq + PartialEq, @@ -197,7 +198,7 @@ impl< /// Represents a deposit of a specific asset. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct Deposit { +pub struct Deposit { /// The amount of the asset deposited. pub amount: Balance, /// The ID of the deposited asset. @@ -206,7 +207,8 @@ pub struct Deposit { /// Represents a stake between a delegator and an operator. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct BondInfoDelegator> { +pub struct BondInfoDelegator> +{ /// The account ID of the operator. pub operator: AccountId, /// The amount bonded. diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 5c3ad29c..47ab4a06 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -20,7 +20,8 @@ use tangle_primitives::services::Asset; /// A snapshot of the operator state at the start of the round. #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct OperatorSnapshot> { +pub struct OperatorSnapshot> +{ /// The total value locked by the operator. pub stake: Balance, @@ -29,7 +30,7 @@ pub struct OperatorSnapshot, MaxDelegations>, } -impl> +impl> OperatorSnapshot where AssetId: PartialEq + Ord + Copy, @@ -85,7 +86,7 @@ pub struct OperatorBondLessRequest { pub struct OperatorMetadata< AccountId, Balance, - AssetId : Encode + Decode, + AssetId: Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, > { @@ -104,8 +105,13 @@ pub struct OperatorMetadata< pub blueprint_ids: BoundedVec, } -impl, MaxBlueprints: Get> Default - for OperatorMetadata +impl< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxDelegations: Get, + MaxBlueprints: Get, + > Default for OperatorMetadata where Balance: Default, { @@ -123,7 +129,7 @@ where /// Represents a stake for an operator #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond { +pub struct DelegatorBond { /// The account ID of the delegator. pub delegator: AccountId, /// The amount bonded. diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 621f0107..8e5df081 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -624,7 +624,7 @@ pub enum ApprovalState { } /// Different types of assets that can be used. -#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Copy, Clone, MaxEncodedLen)] +#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Copy, Clone, MaxEncodedLen, Ord, PartialOrd)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Asset { /// Use the specified AssetId. diff --git a/primitives/src/traits/services.rs b/primitives/src/traits/services.rs index ba28f487..20b463c4 100644 --- a/primitives/src/traits/services.rs +++ b/primitives/src/traits/services.rs @@ -1,4 +1,6 @@ use scale_info::prelude::vec::Vec; +use sp_core::{H160, U256}; + /// A trait to manage and query services and blueprints for operators. /// /// This trait defines methods to retrieve information about the number of active @@ -58,3 +60,12 @@ pub trait ServiceManager { /// `true` if the operator can exit, otherwise `false`. fn can_exit(operator: &AccountId) -> bool; } + +/// Trait to be implemented for evm address mapping. +pub trait EvmAddressMapping { + /// Convert an address to an account id. + fn into_account_id(address: H160) -> A; + + /// Convert an account id to an address. + fn into_address(account_id: A) -> H160; +} \ No newline at end of file From 4d6b596f229f683b02c1502c8e445b1a559e1073 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:04:01 +0530 Subject: [PATCH 09/63] wip --- .../src/functions/deposit.rs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 500861e6..24671844 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -158,7 +158,7 @@ impl Pallet { /// /// Returns an error if the user is not a delegator, if there are no withdraw requests, or if /// the withdraw request is not ready. - pub fn process_execute_withdraw(who: T::AccountId) -> DispatchResult { + pub fn process_execute_withdraw(who: T::AccountId, evm_address: Option) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; @@ -172,15 +172,23 @@ impl Pallet { metadata.withdraw_requests.retain(|request| { if current_round >= delay + request.requested_round { // Transfer the amount back to the delegator - T::Fungibles::transfer( - request.asset_id, - &Self::pallet_account(), - &who, - request.amount, - Preservation::Expendable, - ) - .expect("Transfer should not fail"); - + match request.asset_id { + Asset::Custom(asset_id) => { + T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &who, + request.amount, + Preservation::Expendable, + ) + .expect("Transfer should not fail"); + }, + Asset::Erc20(asset_address) => { + let (success, _weight) = + Self::erc20_transfer(asset_address, &Self::pallet_evm_account(), evm_address.unwrap(), request.amount).map_err(|_| Error::::ERC20TransferFailed)?; + ensure!(success, Error::::ERC20TransferFailed); + } + } false // Remove this request } else { true // Keep this request From c214aca5280a1857c232e191cf922784fe84aa59 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:04:19 +0530 Subject: [PATCH 10/63] fix compile --- .../evm-tracing/src/formatters/blockscout.rs | 2 +- .../evm-tracing/src/formatters/call_tracer.rs | 37 +++++---- .../src/formatters/trace_filter.rs | 15 ++-- client/evm-tracing/src/listeners/call_list.rs | 71 ++++++++++------- client/evm-tracing/src/listeners/raw.rs | 12 +-- client/evm-tracing/src/types/serialization.rs | 4 +- client/rpc-core/txpool/src/types/content.rs | 15 ++-- client/rpc/debug/src/lib.rs | 78 +++++++++++-------- client/rpc/trace/src/lib.rs | 47 ++++++----- client/rpc/txpool/src/lib.rs | 2 +- frost/frost-ristretto255/src/lib.rs | 5 +- frost/src/keys.rs | 2 +- frost/src/lib.rs | 10 +-- frost/src/round1.rs | 6 +- frost/src/scalar_mul.rs | 6 +- frost/src/signature.rs | 6 +- frost/src/signing_key.rs | 2 +- node/src/distributions/mainnet.rs | 42 +++++----- node/src/manual_seal.rs | 2 +- node/src/service.rs | 8 +- node/src/utils.rs | 2 +- pallets/claims/src/lib.rs | 15 ++-- pallets/claims/src/utils/mod.rs | 5 +- .../multi-asset-delegation/src/functions.rs | 2 +- .../src/functions/deposit.rs | 29 +++++-- .../src/functions/evm.rs | 13 +--- pallets/multi-asset-delegation/src/lib.rs | 2 +- pallets/services/rpc/src/lib.rs | 10 ++- pallets/services/src/functions.rs | 5 +- pallets/services/src/lib.rs | 5 +- pallets/services/src/mock.rs | 7 +- pallets/services/src/mock_evm.rs | 14 ++-- pallets/services/src/tests.rs | 5 +- pallets/tangle-lst/src/lib.rs | 11 +-- pallets/tangle-lst/src/types/bonded_pool.rs | 12 +-- pallets/tangle-lst/src/types/commission.rs | 8 +- precompiles/assets-erc20/src/lib.rs | 6 +- precompiles/assets-erc20/src/tests.rs | 4 +- precompiles/balances-erc20/src/lib.rs | 10 +-- precompiles/balances-erc20/src/tests.rs | 4 +- precompiles/batch/src/lib.rs | 40 ++++++---- precompiles/call-permit/src/lib.rs | 7 +- precompiles/multi-asset-delegation/src/lib.rs | 2 +- .../multi-asset-delegation/src/tests.rs | 8 +- precompiles/pallet-democracy/src/lib.rs | 2 +- precompiles/pallet-democracy/src/tests.rs | 36 +++++---- precompiles/precompile-registry/src/lib.rs | 7 +- precompiles/proxy/src/lib.rs | 25 +++--- precompiles/services/src/lib.rs | 9 ++- precompiles/services/src/mock.rs | 2 +- precompiles/services/src/mock_evm.rs | 14 ++-- precompiles/services/src/tests.rs | 5 +- precompiles/staking/src/lib.rs | 2 +- precompiles/tangle-lst/src/lib.rs | 2 +- .../verify-bls381-signature/src/lib.rs | 4 +- .../src/lib.rs | 19 +---- .../src/lib.rs | 19 +---- .../verify-ecdsa-stark-signature/src/lib.rs | 32 +++----- .../verify-schnorr-signatures/src/lib.rs | 2 +- precompiles/vesting/src/lib.rs | 4 +- primitives/rpc/evm-tracing-events/src/evm.rs | 20 +++-- .../rpc/evm-tracing-events/src/gasometer.rs | 20 +++-- .../rpc/evm-tracing-events/src/runtime.rs | 15 ++-- primitives/src/chain_identifier.rs | 16 ++-- primitives/src/services/field.rs | 20 ++--- primitives/src/services/mod.rs | 30 +++++-- primitives/src/traits/services.rs | 2 +- primitives/src/verifier/circom.rs | 10 +-- runtime/mainnet/src/filters.rs | 4 +- runtime/mainnet/src/frontier_evm.rs | 15 ++-- runtime/mainnet/src/lib.rs | 26 ++++--- runtime/testnet/src/filters.rs | 4 +- runtime/testnet/src/frontier_evm.rs | 6 +- runtime/testnet/src/lib.rs | 26 ++++--- 74 files changed, 539 insertions(+), 457 deletions(-) diff --git a/client/evm-tracing/src/formatters/blockscout.rs b/client/evm-tracing/src/formatters/blockscout.rs index 9efe1505..61b8033e 100644 --- a/client/evm-tracing/src/formatters/blockscout.rs +++ b/client/evm-tracing/src/formatters/blockscout.rs @@ -36,7 +36,7 @@ impl super::ResponseFormatter for Formatter { if let Some(entry) = listener.entries.last() { return Some(TransactionTrace::CallList( entry.iter().map(|(_, value)| Call::Blockscout(value.clone())).collect(), - )) + )); } None } diff --git a/client/evm-tracing/src/formatters/call_tracer.rs b/client/evm-tracing/src/formatters/call_tracer.rs index b72ea0c9..6b2d7ae4 100644 --- a/client/evm-tracing/src/formatters/call_tracer.rs +++ b/client/evm-tracing/src/formatters/call_tracer.rs @@ -56,13 +56,14 @@ impl super::ResponseFormatter for Formatter { gas_used, trace_address: Some(trace_address.clone()), inner: match inner.clone() { - BlockscoutCallInner::Call { input, to, res, call_type } => + BlockscoutCallInner::Call { input, to, res, call_type } => { CallTracerInner::Call { call_type: match call_type { CallType::Call => "CALL".as_bytes().to_vec(), CallType::CallCode => "CALLCODE".as_bytes().to_vec(), - CallType::DelegateCall => - "DELEGATECALL".as_bytes().to_vec(), + CallType::DelegateCall => { + "DELEGATECALL".as_bytes().to_vec() + }, CallType::StaticCall => "STATICCALL".as_bytes().to_vec(), }, to, @@ -73,7 +74,8 @@ impl super::ResponseFormatter for Formatter { CallResult::Output { .. } => it.logs.clone(), CallResult::Error { .. } => Vec::new(), }, - }, + } + }, BlockscoutCallInner::Create { init, res } => CallTracerInner::Create { input: init, error: match res { @@ -87,19 +89,21 @@ impl super::ResponseFormatter for Formatter { CreateResult::Error { .. } => None, }, output: match res { - CreateResult::Success { created_contract_code, .. } => - Some(created_contract_code), + CreateResult::Success { created_contract_code, .. } => { + Some(created_contract_code) + }, CreateResult::Error { .. } => None, }, value, call_type: "CREATE".as_bytes().to_vec(), }, - BlockscoutCallInner::SelfDestruct { balance, to } => + BlockscoutCallInner::SelfDestruct { balance, to } => { CallTracerInner::SelfDestruct { value: balance, to, call_type: "SELFDESTRUCT".as_bytes().to_vec(), - }, + } + }, }, calls: Vec::new(), }) @@ -161,11 +165,11 @@ impl super::ResponseFormatter for Formatter { let sibling_greater_than = |a: &Vec, b: &Vec| -> bool { for (i, a_value) in a.iter().enumerate() { if a_value > &b[i] { - return true + return true; } else if a_value < &b[i] { - return false + return false; } else { - continue + continue; } } false @@ -189,10 +193,11 @@ impl super::ResponseFormatter for Formatter { ( Call::CallTracer(CallTracerCall { trace_address: Some(a), .. }), Call::CallTracer(CallTracerCall { trace_address: Some(b), .. }), - ) => - &b[..] == - a.get(0..a.len() - 1) - .expect("non-root element while traversing trace result"), + ) => { + &b[..] + == a.get(0..a.len() - 1) + .expect("non-root element while traversing trace result") + }, _ => unreachable!(), }) { // Remove `trace_address` from result. @@ -223,7 +228,7 @@ impl super::ResponseFormatter for Formatter { } } if traces.is_empty() { - return None + return None; } Some(traces) } diff --git a/client/evm-tracing/src/formatters/trace_filter.rs b/client/evm-tracing/src/formatters/trace_filter.rs index f8844c8f..9bb03210 100644 --- a/client/evm-tracing/src/formatters/trace_filter.rs +++ b/client/evm-tracing/src/formatters/trace_filter.rs @@ -56,11 +56,12 @@ impl super::ResponseFormatter for Formatter { // Can't be known here, must be inserted upstream. block_number: 0, output: match res { - CallResult::Output(output) => + CallResult::Output(output) => { TransactionTraceOutput::Result(TransactionTraceResult::Call { gas_used: trace.gas_used, output, - }), + }) + }, CallResult::Error(error) => TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, @@ -86,14 +87,16 @@ impl super::ResponseFormatter for Formatter { CreateResult::Success { created_contract_address_hash, created_contract_code, - } => + } => { TransactionTraceOutput::Result(TransactionTraceResult::Create { gas_used: trace.gas_used, code: created_contract_code, address: created_contract_address_hash, - }), - CreateResult::Error { error } => - TransactionTraceOutput::Error(error), + }) + }, + CreateResult::Error { error } => { + TransactionTraceOutput::Error(error) + }, }, subtraces: trace.subtraces, trace_address: trace.trace_address.clone(), diff --git a/client/evm-tracing/src/listeners/call_list.rs b/client/evm-tracing/src/listeners/call_list.rs index 5ca1eb15..9da8a66a 100644 --- a/client/evm-tracing/src/listeners/call_list.rs +++ b/client/evm-tracing/src/listeners/call_list.rs @@ -224,9 +224,9 @@ impl Listener { pub fn gasometer_event(&mut self, event: GasometerEvent) { match event { - GasometerEvent::RecordCost { snapshot, .. } | - GasometerEvent::RecordDynamicCost { snapshot, .. } | - GasometerEvent::RecordStipend { snapshot, .. } => { + GasometerEvent::RecordCost { snapshot, .. } + | GasometerEvent::RecordDynamicCost { snapshot, .. } + | GasometerEvent::RecordStipend { snapshot, .. } => { if let Some(context) = self.context_stack.last_mut() { if context.start_gas.is_none() { context.start_gas = Some(snapshot.gas()); @@ -497,12 +497,13 @@ impl Listener { // behavior (like batch precompile does) thus we simply consider this a call. self.call_type = Some(CallType::Call); }, - EvmEvent::Log { address, topics, data } => + EvmEvent::Log { address, topics, data } => { if self.with_log { if let Some(stack) = self.context_stack.last_mut() { stack.logs.push(Log { address, topics, data }); } - }, + } + }, // We ignore other kinds of message if any (new ones may be added in the future). #[allow(unreachable_patterns)] @@ -536,13 +537,15 @@ impl Listener { match context.context_type { ContextType::Call(call_type) => { let res = match &reason { - ExitReason::Succeed(ExitSucceed::Returned) => - CallResult::Output(return_value.to_vec()), + ExitReason::Succeed(ExitSucceed::Returned) => { + CallResult::Output(return_value.to_vec()) + }, ExitReason::Succeed(_) => CallResult::Output(vec![]), ExitReason::Error(error) => CallResult::Error(error_message(error)), - ExitReason::Revert(_) => - CallResult::Error(b"execution reverted".to_vec()), + ExitReason::Revert(_) => { + CallResult::Error(b"execution reverted".to_vec()) + }, ExitReason::Fatal(_) => CallResult::Error(vec![]), }; @@ -568,10 +571,12 @@ impl Listener { created_contract_address_hash: context.to, created_contract_code: return_value.to_vec(), }, - ExitReason::Error(error) => - CreateResult::Error { error: error_message(error) }, - ExitReason::Revert(_) => - CreateResult::Error { error: b"execution reverted".to_vec() }, + ExitReason::Error(error) => { + CreateResult::Error { error: error_message(error) } + }, + ExitReason::Revert(_) => { + CreateResult::Error { error: b"execution reverted".to_vec() } + }, ExitReason::Fatal(_) => CreateResult::Error { error: vec![] }, }; @@ -620,14 +625,15 @@ impl ListenerT for Listener { Event::Gasometer(gasometer_event) => self.gasometer_event(gasometer_event), Event::Runtime(runtime_event) => self.runtime_event(runtime_event), Event::Evm(evm_event) => self.evm_event(evm_event), - Event::CallListNew() => + Event::CallListNew() => { if !self.call_list_first_transaction { self.finish_transaction(); self.skip_next_context = false; self.entries.push(BTreeMap::new()); } else { self.call_list_first_transaction = false; - }, + } + }, }; } @@ -726,8 +732,9 @@ mod tests { target: H160::default(), balance: U256::zero(), }, - TestEvmEvent::Exit => - EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() }, + TestEvmEvent::Exit => { + EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() } + }, TestEvmEvent::TransactCall => EvmEvent::TransactCall { caller: H160::default(), address: H160::default(), @@ -750,8 +757,9 @@ mod tests { gas_limit: 0u64, address: H160::default(), }, - TestEvmEvent::Log => - EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() }, + TestEvmEvent::Log => { + EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() } + }, } } @@ -764,8 +772,9 @@ mod tests { stack: test_stack(), memory: test_memory(), }, - TestRuntimeEvent::StepResult => - RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() }, + TestRuntimeEvent::StepResult => { + RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() } + }, TestRuntimeEvent::SLoad => RuntimeEvent::SLoad { address: H160::default(), index: H256::default(), @@ -781,20 +790,24 @@ mod tests { fn test_emit_gasometer_event(event_type: TestGasometerEvent) -> GasometerEvent { match event_type { - TestGasometerEvent::RecordCost => - GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() }, - TestGasometerEvent::RecordRefund => - GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() }, - TestGasometerEvent::RecordStipend => - GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordCost => { + GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() } + }, + TestGasometerEvent::RecordRefund => { + GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() } + }, + TestGasometerEvent::RecordStipend => { + GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() } + }, TestGasometerEvent::RecordDynamicCost => GasometerEvent::RecordDynamicCost { gas_cost: 0u64, memory_gas: 0u64, gas_refund: 0i64, snapshot: test_snapshot(), }, - TestGasometerEvent::RecordTransaction => - GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordTransaction => { + GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() } + }, } } diff --git a/client/evm-tracing/src/listeners/raw.rs b/client/evm-tracing/src/listeners/raw.rs index 2b39fe23..483ea0a3 100644 --- a/client/evm-tracing/src/listeners/raw.rs +++ b/client/evm-tracing/src/listeners/raw.rs @@ -161,7 +161,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(memory.data.len())); if self.remaining_memory_usage.is_none() { - return + return; } Some(memory.data.clone()) @@ -176,7 +176,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(stack.data.len())); if self.remaining_memory_usage.is_none() { - return + return; } Some(stack.data.clone()) @@ -205,7 +205,7 @@ impl Listener { }); if self.remaining_memory_usage.is_none() { - return + return; } Some(context.storage_cache.clone()) @@ -277,8 +277,8 @@ impl Listener { _ => (), } }, - RuntimeEvent::SLoad { address: _, index, value } | - RuntimeEvent::SStore { address: _, index, value } => { + RuntimeEvent::SLoad { address: _, index, value } + | RuntimeEvent::SStore { address: _, index, value } => { if let Some(context) = self.context_stack.last_mut() { if !self.disable_storage { context.storage_cache.insert(index, value); @@ -295,7 +295,7 @@ impl Listener { impl ListenerT for Listener { fn event(&mut self, event: Event) { if self.remaining_memory_usage.is_none() { - return + return; } match event { diff --git a/client/evm-tracing/src/types/serialization.rs b/client/evm-tracing/src/types/serialization.rs index 9f31f709..f786ffaf 100644 --- a/client/evm-tracing/src/types/serialization.rs +++ b/client/evm-tracing/src/types/serialization.rs @@ -54,7 +54,7 @@ where S: Serializer, { if let Some(bytes) = bytes.as_ref() { - return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))) + return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))); } Err(S::Error::custom("String serialize error.")) } @@ -87,7 +87,7 @@ where let d = std::str::from_utf8(&value[..]) .map_err(|_| S::Error::custom("String serialize error."))? .to_string(); - return serializer.serialize_str(&d) + return serializer.serialize_str(&d); } Err(S::Error::custom("String serialize error.")) } diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index 581be173..ec98a00f 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -66,12 +66,15 @@ where impl GetT for Transaction { fn get(hash: H256, from_address: H160, txn: &EthereumTransaction) -> Self { let (nonce, action, value, gas_price, gas_limit, input) = match txn { - EthereumTransaction::Legacy(t) => - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), - EthereumTransaction::EIP2930(t) => - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), - EthereumTransaction::EIP1559(t) => - (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()), + EthereumTransaction::Legacy(t) => { + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) + }, + EthereumTransaction::EIP2930(t) => { + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) + }, + EthereumTransaction::EIP1559(t) => { + (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()) + }, }; Self { hash, diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index c1878aca..aa85097d 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -353,12 +353,15 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => - Ok(BlockId::Number(client.info().best_number)), - RequestBlockId::Tag(RequestBlockTag::Earliest) => - Ok(BlockId::Number(0u32.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Pending) => - Err(internal_err("'pending' blocks are not supported")), + RequestBlockId::Tag(RequestBlockTag::Latest) => { + Ok(BlockId::Number(client.info().best_number)) + }, + RequestBlockId::Tag(RequestBlockTag::Earliest) => { + Ok(BlockId::Number(0u32.unique_saturated_into())) + }, + RequestBlockId::Tag(RequestBlockTag::Pending) => { + Err(internal_err("'pending' blocks are not supported")) + }, RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -378,7 +381,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -395,7 +398,7 @@ where // If there are no ethereum transactions in the block return empty trace right away. if eth_tx_hashes.is_empty() { - return Ok(Response::Block(vec![])) + return Ok(Response::Block(vec![])); } // Get block extrinsics. @@ -410,7 +413,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; // Trace the block. @@ -425,7 +428,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (core)".to_string())) + return Err(internal_err("Runtime api version call failed (core)".to_string())); }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -470,10 +473,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::CallTracer => + TracerInput::CallTracer => { client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, _ => Err(internal_err("Bug: failed to resolve the tracer format.".to_string())), }?; @@ -533,7 +537,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(reference_hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(reference_hash) { Ok(Some(h)) => h, @@ -554,7 +558,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; let reference_block = overrides.current_block(reference_hash); @@ -576,7 +580,7 @@ where } else { return Err(internal_err( "Runtime api version call failed (core)".to_string(), - )) + )); }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -608,17 +612,20 @@ where // Pre-london update, legacy transactions. match transaction { ethereum::TransactionV2::Legacy(tx) => + { #[allow(deprecated)] api.trace_transaction_before_version_4( parent_block_hash, exts, tx, - ), - _ => + ) + }, + _ => { return Err(internal_err( "Bug: pre-london runtime expects legacy transactions" .to_string(), - )), + )) + }, } } }; @@ -659,10 +666,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => + TracerInput::Blockscout => { client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) @@ -680,7 +688,7 @@ where "Bug: `handle_transaction_request` does not support {:?}.", not_supported ))), - } + }; } } Err(internal_err("Runtime block call failed".to_string())) @@ -698,12 +706,15 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => - Ok(BlockId::Number(client.info().best_number)), - RequestBlockId::Tag(RequestBlockTag::Earliest) => - Ok(BlockId::Number(0u32.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Pending) => - Err(internal_err("'pending' blocks are not supported")), + RequestBlockId::Tag(RequestBlockTag::Latest) => { + Ok(BlockId::Number(client.info().best_number)) + }, + RequestBlockId::Tag(RequestBlockTag::Earliest) => { + Ok(BlockId::Number(0u32.unique_saturated_into())) + }, + RequestBlockId::Tag(RequestBlockTag::Pending) => { + Err(internal_err("'pending' blocks are not supported")) + }, RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -721,7 +732,7 @@ where let api = client.runtime_api(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -736,11 +747,11 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; if trace_api_version <= 5 { - return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())) + return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); } let TraceCallParams { @@ -795,7 +806,7 @@ where } else { return Err(internal_err( "block unavailable, cannot query gas limit".to_string(), - )) + )); } }, }; @@ -847,10 +858,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => + TracerInput::Blockscout => { client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 4514ce79..72c564df 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -100,8 +100,9 @@ where .try_into() .map_err(|_| "Block number overflow")?), Some(RequestBlockId::Tag(RequestBlockTag::Earliest)) => Ok(0), - Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => - Err("'pending' is not supported"), + Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => { + Err("'pending' is not supported") + }, Some(RequestBlockId::Hash(_)) => Err("Block hash not supported"), } } @@ -117,14 +118,14 @@ where return Err(format!( "count ({}) can't be greater than maximum ({})", count, self.max_count - )) + )); } // Build a list of all the Substrate block hashes that need to be traced. let mut block_hashes = vec![]; for block_height in block_heights { if block_height == 0 { - continue // no traces for genesis block. + continue; // no traces for genesis block. } let block_hash = self @@ -173,15 +174,18 @@ where let mut block_traces: Vec<_> = block_traces .iter() .filter(|trace| match trace.action { - block::TransactionTraceAction::Call { from, to, .. } => - (from_address.is_empty() || from_address.contains(&from)) && - (to_address.is_empty() || to_address.contains(&to)), - block::TransactionTraceAction::Create { from, .. } => - (from_address.is_empty() || from_address.contains(&from)) && - to_address.is_empty(), - block::TransactionTraceAction::Suicide { address, .. } => - (from_address.is_empty() || from_address.contains(&address)) && - to_address.is_empty(), + block::TransactionTraceAction::Call { from, to, .. } => { + (from_address.is_empty() || from_address.contains(&from)) + && (to_address.is_empty() || to_address.contains(&to)) + }, + block::TransactionTraceAction::Create { from, .. } => { + (from_address.is_empty() || from_address.contains(&from)) + && to_address.is_empty() + }, + block::TransactionTraceAction::Suicide { address, .. } => { + (from_address.is_empty() || from_address.contains(&address)) + && to_address.is_empty() + }, }) .cloned() .collect(); @@ -207,11 +211,11 @@ where "the amount of traces goes over the maximum ({}), please use 'after' \ and 'count' in your request", self.max_count - )) + )); } traces = traces.into_iter().take(count).collect(); - break + break; } } } @@ -648,8 +652,8 @@ where // We remove early the block cache if this batch is the last // pooling this block. if let Some(block_cache) = self.cached_blocks.get_mut(block) { - if block_cache.active_batch_count == 1 && - matches!( + if block_cache.active_batch_count == 1 + && matches!( block_cache.state, CacheBlockState::Pooled { started: false, .. } ) { @@ -756,11 +760,12 @@ where overrides.current_transaction_statuses(substrate_hash), ) { (Some(a), Some(b)) => (a, b), - _ => + _ => { return Err(format!( "Failed to get Ethereum block data for Substrate block {}", substrate_hash - )), + )) + }, }; let eth_block_hash = eth_block.header.hash(); @@ -781,7 +786,7 @@ where { api_version } else { - return Err("Runtime api version call failed (trace)".to_string()) + return Err("Runtime api version call failed (trace)".to_string()); }; // Trace the block. @@ -795,7 +800,7 @@ where { api_version } else { - return Err("Runtime api version call failed (core)".to_string()) + return Err("Runtime api version call failed (core)".to_string()); }; // Initialize block: calls the "on_initialize" hook on every pallet diff --git a/client/rpc/txpool/src/lib.rs b/client/rpc/txpool/src/lib.rs index c00ad935..101050c5 100644 --- a/client/rpc/txpool/src/lib.rs +++ b/client/rpc/txpool/src/lib.rs @@ -74,7 +74,7 @@ where if let Ok(Some(api_version)) = api.api_version::>(best_block) { api_version } else { - return Err(internal_err("failed to retrieve Runtime Api version".to_string())) + return Err(internal_err("failed to retrieve Runtime Api version".to_string())); }; let ethereum_txns: TxPoolResponse = if api_version == 1 { #[allow(deprecated)] diff --git a/frost/frost-ristretto255/src/lib.rs b/frost/frost-ristretto255/src/lib.rs index a3322ef4..a4d955fc 100644 --- a/frost/frost-ristretto255/src/lib.rs +++ b/frost/frost-ristretto255/src/lib.rs @@ -102,12 +102,13 @@ impl Group for RistrettoGroup { .map_err(|_| GroupError::MalformedElement)? .decompress() { - Some(point) => + Some(point) => { if point == RistrettoPoint::identity() { Err(GroupError::InvalidIdentityElement) } else { Ok(WrappedRistrettoPoint(point)) - }, + } + }, None => Err(GroupError::MalformedElement), } } diff --git a/frost/src/keys.rs b/frost/src/keys.rs index 5069d93f..1c2656da 100644 --- a/frost/src/keys.rs +++ b/frost/src/keys.rs @@ -384,7 +384,7 @@ where let result = evaluate_vss(self.identifier, &self.commitment); if !(f_result == result) { - return Err(Error::InvalidSecretShare) + return Err(Error::InvalidSecretShare); } Ok((VerifyingShare(result), self.commitment.verifying_key()?)) diff --git a/frost/src/lib.rs b/frost/src/lib.rs index 5bd2fdff..ede2024d 100644 --- a/frost/src/lib.rs +++ b/frost/src/lib.rs @@ -66,7 +66,7 @@ pub fn random_nonzero(rng: &mut R) -> Sc let scalar = <::Field>::random(rng); if scalar != <::Field>::zero() { - return scalar + return scalar; } } } @@ -203,7 +203,7 @@ fn compute_lagrange_coefficient( x_i: Identifier, ) -> Result, Error> { if x_set.is_empty() { - return Err(Error::IncorrectNumberOfIdentifiers) + return Err(Error::IncorrectNumberOfIdentifiers); } let mut num = <::Field>::one(); let mut den = <::Field>::one(); @@ -213,7 +213,7 @@ fn compute_lagrange_coefficient( for x_j in x_set.iter() { if x_i == *x_j { x_i_found = true; - continue + continue; } if let Some(x) = x { @@ -226,7 +226,7 @@ fn compute_lagrange_coefficient( } } if !x_i_found { - return Err(Error::UnknownIdentifier) + return Err(Error::UnknownIdentifier); } Ok(num * <::Field>::invert(&den).map_err(|_| Error::DuplicatedIdentifier)?) @@ -396,7 +396,7 @@ where // The following check prevents a party from accidentally revealing their share. // Note that the '&&' operator would be sufficient. if identity == commitment.binding.0 || identity == commitment.hiding.0 { - return Err(Error::IdentityCommitment) + return Err(Error::IdentityCommitment); } let binding_factor = diff --git a/frost/src/round1.rs b/frost/src/round1.rs index 52f7d61a..54039c00 100644 --- a/frost/src/round1.rs +++ b/frost/src/round1.rs @@ -106,9 +106,9 @@ where /// Checks if the commitments are valid. pub fn is_valid(&self) -> bool { - element_is_valid::(&self.hiding.0) && - element_is_valid::(&self.binding.0) && - self.hiding.0 != self.binding.0 + element_is_valid::(&self.hiding.0) + && element_is_valid::(&self.binding.0) + && self.hiding.0 != self.binding.0 } } diff --git a/frost/src/scalar_mul.rs b/frost/src/scalar_mul.rs index a80b98b3..8211ac83 100644 --- a/frost/src/scalar_mul.rs +++ b/frost/src/scalar_mul.rs @@ -118,7 +118,7 @@ where // If carry == 1 and window & 1 == 0, then bit_buf & 1 == 1 so the next carry should // be 1 pos += 1; - continue + continue; } if window < width / 2 { @@ -197,14 +197,14 @@ where .collect::>>()?; if nafs.len() != lookup_tables.len() { - return None + return None; } let mut r = ::identity(); // All NAFs will have the same size, so get it from the first if nafs.is_empty() { - return Some(r) + return Some(r); } let naf_length = nafs[0].len(); diff --git a/frost/src/signature.rs b/frost/src/signature.rs index c7f059e5..5a1f89be 100644 --- a/frost/src/signature.rs +++ b/frost/src/signature.rs @@ -210,10 +210,10 @@ where lambda_i: Scalar, challenge: &Challenge, ) -> Result<(), Error> { - if (::generator() * self.share) != - (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) + if (::generator() * self.share) + != (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) { - return Err(Error::InvalidSignatureShare) + return Err(Error::InvalidSignatureShare); } Ok(()) diff --git a/frost/src/signing_key.rs b/frost/src/signing_key.rs index 9307d5ed..758600f5 100644 --- a/frost/src/signing_key.rs +++ b/frost/src/signing_key.rs @@ -44,7 +44,7 @@ where <::Field as Field>::deserialize(&bytes).map_err(Error::from)?; if scalar == <::Field as Field>::zero() { - return Err(Error::MalformedSigningKey) + return Err(Error::MalformedSigningKey); } Ok(Self { scalar }) diff --git a/node/src/distributions/mainnet.rs b/node/src/distributions/mainnet.rs index cfbec875..a88ba554 100644 --- a/node/src/distributions/mainnet.rs +++ b/node/src/distributions/mainnet.rs @@ -44,7 +44,7 @@ fn read_contents_to_substrate_accounts(path_str: &str) -> BTreeMap BTreeMap BTreeMap Result<(), S // Ensure key is present if !ensure_keytype_exists_in_keystore(key_type, key_store.clone()) { println!("{key_type:?} key not found!"); - return Err("Key not found!".to_string()) + return Err("Key not found!".to_string()); } } diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 40964208..161de15d 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -94,14 +94,16 @@ impl StatementKind { /// Convert this to the (English) statement it represents. fn to_text(self) -> &'static [u8] { match self { - StatementKind::Regular => + StatementKind::Regular => { &b"I hereby agree to the terms of the statement whose sha2256sum is \ 5627de05cfe235cd4ffa0d6375c8a5278b89cc9b9e75622fa2039f4d1b43dadf. (This may be found at the URL: \ - https://statement.tangle.tools/airdrop-statement.html)"[..], - StatementKind::Safe => + https://statement.tangle.tools/airdrop-statement.html)"[..] + }, + StatementKind::Safe => { &b"I hereby agree to the terms of the statement whose sha2256sum is \ 7eae145b00c1912c8b01674df5df4ad9abcf6d18ea3f33d27eb6897a762f4273. (This may be found at the URL: \ - https://statement.tangle.tools/safe-claim-statement)"[..], + https://statement.tangle.tools/safe-claim-statement)"[..] + }, } } } @@ -639,9 +641,10 @@ impl Pallet { statement: Vec, ) -> Result> { let signer = match signature { - MultiAddressSignature::EVM(ethereum_signature) => + MultiAddressSignature::EVM(ethereum_signature) => { Self::eth_recover(ðereum_signature, &data, &statement[..]) - .ok_or(Error::::InvalidEthereumSignature)?, + .ok_or(Error::::InvalidEthereumSignature)? + }, MultiAddressSignature::Native(sr25519_signature) => { ensure!(!signer.is_none(), Error::::InvalidNativeAccount); Self::sr25519_recover(signer.unwrap(), &sr25519_signature, &data, &statement[..]) diff --git a/pallets/claims/src/utils/mod.rs b/pallets/claims/src/utils/mod.rs index f2559685..a387457f 100644 --- a/pallets/claims/src/utils/mod.rs +++ b/pallets/claims/src/utils/mod.rs @@ -45,8 +45,9 @@ impl Hash for MultiAddress { impl MultiAddress { pub fn to_account_id_32(&self) -> AccountId32 { match self { - MultiAddress::EVM(ethereum_address) => - HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)), + MultiAddress::EVM(ethereum_address) => { + HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)) + }, MultiAddress::Native(substrate_address) => substrate_address.clone(), } } diff --git a/pallets/multi-asset-delegation/src/functions.rs b/pallets/multi-asset-delegation/src/functions.rs index bcf33acf..9ee9c028 100644 --- a/pallets/multi-asset-delegation/src/functions.rs +++ b/pallets/multi-asset-delegation/src/functions.rs @@ -17,7 +17,7 @@ use super::*; pub mod delegate; pub mod deposit; +pub mod evm; pub mod operator; pub mod rewards; pub mod session_manager; -pub mod evm; diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 24671844..daa87875 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -22,8 +22,8 @@ use frame_support::{ traits::{tokens::Preservation, Get}, }; use sp_core::H160; -use tangle_primitives::EvmAddressMapping; use tangle_primitives::services::Asset; +use tangle_primitives::EvmAddressMapping; impl Pallet { /// Returns the account ID of the pallet. @@ -58,10 +58,15 @@ impl Pallet { ); }, Asset::Erc20(asset_address) => { - let (success, _weight) = - Self::erc20_transfer(asset_address, &sender, Self::pallet_evm_account(), amount).map_err(|_| Error::::ERC20TransferFailed)?; + let (success, _weight) = Self::erc20_transfer( + asset_address, + &sender, + Self::pallet_evm_account(), + amount, + ) + .map_err(|_| Error::::ERC20TransferFailed)?; ensure!(success, Error::::ERC20TransferFailed); - } + }, } Ok(()) } @@ -158,7 +163,10 @@ impl Pallet { /// /// Returns an error if the user is not a delegator, if there are no withdraw requests, or if /// the withdraw request is not ready. - pub fn process_execute_withdraw(who: T::AccountId, evm_address: Option) -> DispatchResult { + pub fn process_execute_withdraw( + who: T::AccountId, + evm_address: Option, + ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; @@ -184,10 +192,15 @@ impl Pallet { .expect("Transfer should not fail"); }, Asset::Erc20(asset_address) => { - let (success, _weight) = - Self::erc20_transfer(asset_address, &Self::pallet_evm_account(), evm_address.unwrap(), request.amount).map_err(|_| Error::::ERC20TransferFailed)?; + let (success, _weight) = Self::erc20_transfer( + asset_address, + &Self::pallet_evm_account(), + evm_address.unwrap(), + request.amount, + ) + .map_err(|_| Error::::ERC20TransferFailed)?; ensure!(success, Error::::ERC20TransferFailed); - } + }, } false // Remove this request } else { diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index bccc44b0..11996527 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -1,14 +1,13 @@ use super::*; +use crate::types::BalanceOf; use ethabi::{Function, StateMutability, Token}; use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; -use sp_core::{H160, U256}; -use crate::types::BalanceOf; use frame_support::pallet_prelude::Weight; +use sp_core::{H160, U256}; use tangle_primitives::EvmAddressMapping; impl Pallet { - - /// Moves a `value` amount of tokens from the caller's account to `to`. + /// Moves a `value` amount of tokens from the caller's account to `to`. pub fn erc20_transfer( erc20: H160, caller: &T::AccountId, @@ -67,8 +66,4 @@ impl Pallet { Ok((success, weight)) } - - - - -} \ No newline at end of file +} diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 81ca7c3d..2280838f 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -416,7 +416,7 @@ pub mod pallet { /// The blueprint is not selected BlueprintNotSelected, /// Erc20 transfer failed - ERC20TransferFailed + ERC20TransferFailed, } /// Hooks for the pallet. diff --git a/pallets/services/rpc/src/lib.rs b/pallets/services/rpc/src/lib.rs index e25f3c23..ce67fb1b 100644 --- a/pallets/services/rpc/src/lib.rs +++ b/pallets/services/rpc/src/lib.rs @@ -113,10 +113,12 @@ impl From for i32 { fn custom_error_into_rpc_err(err: Error) -> ErrorObjectOwned { match err { - Error::RuntimeError(e) => - ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))), - Error::DecodeError => - ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")), + Error::RuntimeError(e) => { + ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))) + }, + Error::DecodeError => { + ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")) + }, Error::CustomDispatchError(msg) => ErrorObject::owned(3, "Dispatch error", Some(msg)), } } diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index d35386dd..2196ecb2 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -77,8 +77,9 @@ impl Pallet { pub fn mbsm_address_of(blueprint: &ServiceBlueprint) -> Result> { match blueprint.master_manager_revision { MasterBlueprintServiceManagerRevision::Specific(rev) => Self::mbsm_address(rev), - MasterBlueprintServiceManagerRevision::Latest => - Self::mbsm_address(Self::mbsm_latest_revision()), + MasterBlueprintServiceManagerRevision::Latest => { + Self::mbsm_address(Self::mbsm_latest_revision()) + }, other => unimplemented!("Got unexpected case for {:?}", other), } } diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index 96ba3212..57cdc44d 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -1040,8 +1040,9 @@ pub mod module { .operators_with_approval_state .into_iter() .filter_map(|(v, state)| match state { - ApprovalState::Approved { restaking_percent } => - Some((v, restaking_percent)), + ApprovalState::Approved { restaking_percent } => { + Some((v, restaking_percent)) + }, // N.B: this should not happen, as all operators are approved and checked // above. _ => None, diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 54fe44b0..163ad8c8 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -279,7 +279,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false + return false; } true } @@ -758,10 +758,11 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => + (left_val, right_val) => { if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - }, + } + }, }; } } diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index 46b7ea04..02bc329c 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -163,7 +163,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation as OnChargeEVMTransaction< @@ -180,7 +180,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation as OnChargeEVMTransaction< @@ -266,8 +266,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -277,8 +278,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, _ => None, } } diff --git a/pallets/services/src/tests.rs b/pallets/services/src/tests.rs index 738dde1f..cb78110c 100644 --- a/pallets/services/src/tests.rs +++ b/pallets/services/src/tests.rs @@ -59,8 +59,9 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, + MachineKind::Small => { + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } + }, } } diff --git a/pallets/tangle-lst/src/lib.rs b/pallets/tangle-lst/src/lib.rs index 028e5c54..b439669f 100644 --- a/pallets/tangle-lst/src/lib.rs +++ b/pallets/tangle-lst/src/lib.rs @@ -844,7 +844,7 @@ pub mod pallet { let pool_id = member.get_by_pool_id(current_era, pool_id); if pool_id.is_none() { - return Err(Error::::PoolNotFound.into()) + return Err(Error::::PoolNotFound.into()); } // checked above @@ -1506,7 +1506,7 @@ impl Pallet { let balance = T::U256ToBalance::convert; if current_balance.is_zero() || current_points.is_zero() || points.is_zero() { // There is nothing to unbond - return Zero::zero() + return Zero::zero(); } // Equivalent of (current_balance / current_points) * points @@ -1614,8 +1614,9 @@ impl Pallet { bonded_pool.ok_to_join()?; let (_points_issued, bonded) = match extra { - BondExtra::FreeBalance(amount) => - (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount), + BondExtra::FreeBalance(amount) => { + (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount) + }, }; bonded_pool.ok_to_be_open()?; @@ -1681,7 +1682,7 @@ impl Pallet { let min_balance = T::Currency::minimum_balance(); if pre_frozen_balance == min_balance { - return Err(Error::::NothingToAdjust.into()) + return Err(Error::::NothingToAdjust.into()); } // Update frozen amount with current ED. diff --git a/pallets/tangle-lst/src/types/bonded_pool.rs b/pallets/tangle-lst/src/types/bonded_pool.rs index bcddfb94..bca83493 100644 --- a/pallets/tangle-lst/src/types/bonded_pool.rs +++ b/pallets/tangle-lst/src/types/bonded_pool.rs @@ -160,8 +160,8 @@ impl BondedPool { } pub fn can_nominate(&self, who: &T::AccountId) -> bool { - self.is_root(who) || - self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) + self.is_root(who) + || self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) } pub fn can_kick(&self, who: &T::AccountId) -> bool { @@ -262,9 +262,9 @@ impl BondedPool { // any unbond must comply with the balance condition: ensure!( - is_full_unbond || - balance_after_unbond >= - if is_depositor { + is_full_unbond + || balance_after_unbond + >= if is_depositor { Pallet::::depositor_min_bond() } else { MinJoinBond::::get() @@ -296,7 +296,7 @@ impl BondedPool { }, (false, true) => { // the depositor can simply not be unbonded permissionlessly, period. - return Err(Error::::DoesNotHavePermission.into()) + return Err(Error::::DoesNotHavePermission.into()); }, }; diff --git a/pallets/tangle-lst/src/types/commission.rs b/pallets/tangle-lst/src/types/commission.rs index 01ecdd0e..9fbee755 100644 --- a/pallets/tangle-lst/src/types/commission.rs +++ b/pallets/tangle-lst/src/types/commission.rs @@ -55,13 +55,13 @@ impl Commission { // do not throttle if `to` is the same or a decrease in commission. if *to <= commission_as_percent { - return false + return false; } // Test for `max_increase` throttling. // // Throttled if the attempted increase in commission is greater than `max_increase`. if (*to).saturating_sub(commission_as_percent) > t.max_increase { - return true + return true; } // Test for `min_delay` throttling. @@ -84,7 +84,7 @@ impl Commission { blocks_surpassed < t.min_delay } }, - ) + ); } false } @@ -145,7 +145,7 @@ impl Commission { ); if let Some(old) = self.max.as_mut() { if new_max > *old { - return Err(Error::::MaxCommissionRestricted.into()) + return Err(Error::::MaxCommissionRestricted.into()); } *old = new_max; } else { diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index fae8c1d3..91a07416 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -127,7 +127,7 @@ where fn discriminant(address: H160, gas: u64) -> DiscriminantResult> { let extra_cost = RuntimeHelper::::db_read_gas_cost(); if gas < extra_cost { - return DiscriminantResult::OutOfGas + return DiscriminantResult::OutOfGas; } let asset_id = match Runtime::address_to_asset_id(address) { @@ -254,8 +254,8 @@ where handle.record_db_read::(136)?; // If previous approval exists, we need to clean it - if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) != - 0u32.into() + if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) + != 0u32.into() { RuntimeHelper::::try_dispatch( handle, diff --git a/precompiles/assets-erc20/src/tests.rs b/precompiles/assets-erc20/src/tests.rs index 05d48cf8..7152d4c4 100644 --- a/precompiles/assets-erc20/src/tests.rs +++ b/precompiles/assets-erc20/src/tests.rs @@ -441,8 +441,8 @@ fn transfer_not_enough_founds() { ForeignPCall::transfer { to: Address(Charlie.into()), value: 50.into() }, ) .execute_reverts(|output| { - from_utf8(output).unwrap().contains("Dispatched call failed with error: ") && - from_utf8(output).unwrap().contains("BalanceLow") + from_utf8(output).unwrap().contains("Dispatched call failed with error: ") + && from_utf8(output).unwrap().contains("BalanceLow") }); }); } diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index 8c05ca46..aa3a6b4f 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -437,7 +437,7 @@ where fn deposit(handle: &mut impl PrecompileHandle) -> EvmResult { // Deposit only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()) + return Err(RevertReason::UnknownSelector.into()); } let caller: Runtime::AccountId = @@ -446,7 +446,7 @@ where let amount = Self::u256_to_amount(handle.context().apparent_value)?; if amount.into() == U256::from(0u32) { - return Err(revert("deposited amount must be non-zero")) + return Err(revert("deposited amount must be non-zero")); } handle.record_log_costs_manual(2, 32)?; @@ -476,7 +476,7 @@ where fn withdraw(handle: &mut impl PrecompileHandle, value: U256) -> EvmResult { // Withdraw only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()) + return Err(RevertReason::UnknownSelector.into()); } handle.record_log_costs_manual(2, 32)?; @@ -488,7 +488,7 @@ where }; if value > account_amount { - return Err(revert("Trying to withdraw more than owned")) + return Err(revert("Trying to withdraw more than owned")); } log2( @@ -548,7 +548,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/balances-erc20/src/tests.rs b/precompiles/balances-erc20/src/tests.rs index f62c1a4d..6e176e80 100644 --- a/precompiles/balances-erc20/src/tests.rs +++ b/precompiles/balances-erc20/src/tests.rs @@ -306,8 +306,8 @@ fn transfer_not_enough_funds() { PCall::transfer { to: Address(Bob.into()), value: 1400.into() }, ) .execute_reverts(|output| { - from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") && - from_utf8(&output).unwrap().contains("FundsUnavailable") + from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") + && from_utf8(&output).unwrap().contains("FundsUnavailable") }); }); } diff --git a/precompiles/batch/src/lib.rs b/precompiles/batch/src/lib.rs index 943216e3..d26ac2ba 100644 --- a/precompiles/batch/src/lib.rs +++ b/precompiles/batch/src/lib.rs @@ -146,8 +146,9 @@ where let forwarded_gas = match (remaining_gas.checked_sub(log_cost), mode) { (Some(remaining), _) => remaining, - (None, Mode::BatchAll) => - return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), + (None, Mode::BatchAll) => { + return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) + }, (None, _) => return Ok(()), }; @@ -162,10 +163,11 @@ where log.record(handle)?; match mode { - Mode::BatchAll => + Mode::BatchAll => { return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }), + }) + }, Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -182,10 +184,11 @@ where log.record(handle)?; match mode { - Mode::BatchAll => + Mode::BatchAll => { return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }), + }) + }, Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -216,19 +219,23 @@ where // How to proceed match (mode, reason) { // _: Fatal is always fatal - (_, ExitReason::Fatal(exit_status)) => - return Err(PrecompileFailure::Fatal { exit_status }), + (_, ExitReason::Fatal(exit_status)) => { + return Err(PrecompileFailure::Fatal { exit_status }) + }, // BatchAll : Reverts and errors are immediatly forwarded. - (Mode::BatchAll, ExitReason::Revert(exit_status)) => - return Err(PrecompileFailure::Revert { exit_status, output }), - (Mode::BatchAll, ExitReason::Error(exit_status)) => - return Err(PrecompileFailure::Error { exit_status }), + (Mode::BatchAll, ExitReason::Revert(exit_status)) => { + return Err(PrecompileFailure::Revert { exit_status, output }) + }, + (Mode::BatchAll, ExitReason::Error(exit_status)) => { + return Err(PrecompileFailure::Error { exit_status }) + }, // BatchSomeUntilFailure : Reverts and errors prevent subsequent subcalls to // be executed but the precompile still succeed. - (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => - return Ok(()), + (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => { + return Ok(()) + }, // Success or ignored revert/error. (_, _) => (), @@ -263,8 +270,9 @@ where match mode { Mode::BatchSome => Self::batch_some { to, value, call_data, gas_limit }, - Mode::BatchSomeUntilFailure => - Self::batch_some_until_failure { to, value, call_data, gas_limit }, + Mode::BatchSomeUntilFailure => { + Self::batch_some_until_failure { to, value, call_data, gas_limit } + }, Mode::BatchAll => Self::batch_all { to, value, call_data, gas_limit }, } } diff --git a/precompiles/call-permit/src/lib.rs b/precompiles/call-permit/src/lib.rs index 0f5df485..ea1906ba 100644 --- a/precompiles/call-permit/src/lib.rs +++ b/precompiles/call-permit/src/lib.rs @@ -170,7 +170,7 @@ where .ok_or_else(|| revert("Call require too much gas (uint64 overflow)"))?; if total_cost > handle.remaining_gas() { - return Err(revert("Gaslimit is too low to dispatch provided call")) + return Err(revert("Gaslimit is too low to dispatch provided call")); } // VERIFY PERMIT @@ -216,8 +216,9 @@ where match reason { ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(_) => - Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }), + ExitReason::Revert(_) => { + Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }) + }, ExitReason::Succeed(_) => Ok(output.into()), } } diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 0056bcf6..6c3650bd 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -82,7 +82,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index 2c7d6533..c6ed8d64 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -432,8 +432,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status == - OperatorStatus::Inactive + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Inactive ); PrecompilesValue::get() @@ -441,8 +441,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status == - OperatorStatus::Active + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Active ); assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); diff --git a/precompiles/pallet-democracy/src/lib.rs b/precompiles/pallet-democracy/src/lib.rs index 7371074c..ca29013f 100644 --- a/precompiles/pallet-democracy/src/lib.rs +++ b/precompiles/pallet-democracy/src/lib.rs @@ -467,7 +467,7 @@ where if !<::Preimages as QueryPreimage>::is_requested( &proposal_hash, ) { - return Err(revert("not imminent preimage (preimage not requested)")) + return Err(revert("not imminent preimage (preimage not requested)")); }; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); diff --git a/precompiles/pallet-democracy/src/tests.rs b/precompiles/pallet-democracy/src/tests.rs index 9fdb6a6f..697eae1b 100644 --- a/precompiles/pallet-democracy/src/tests.rs +++ b/precompiles/pallet-democracy/src/tests.rs @@ -220,8 +220,9 @@ fn lowest_unbaked_non_zero() { .dispatch(RuntimeOrigin::signed(Alice.into()))); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -243,9 +244,9 @@ fn lowest_unbaked_non_zero() { // Run it through until it is baked roll_to( - ::VotingPeriod::get() + - ::LaunchPeriod::get() + - 1000, + ::VotingPeriod::get() + + ::LaunchPeriod::get() + + 1000, ); precompiles() @@ -558,8 +559,9 @@ fn standard_vote_aye_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -642,8 +644,9 @@ fn standard_vote_nay_conviction_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -721,8 +724,9 @@ fn remove_vote_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -793,8 +797,9 @@ fn delegate_works() { ); let alice_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Delegating { balance, target, conviction, delegations, prior } => - (balance, target, conviction, delegations, prior), + Voting::Delegating { balance, target, conviction, delegations, prior } => { + (balance, target, conviction, delegations, prior) + }, _ => panic!("Votes are not delegating"), }; @@ -807,8 +812,9 @@ fn delegate_works() { let bob_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Bob)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; diff --git a/precompiles/precompile-registry/src/lib.rs b/precompiles/precompile-registry/src/lib.rs index 554e1cd6..15e94ee0 100644 --- a/precompiles/precompile-registry/src/lib.rs +++ b/precompiles/precompile-registry/src/lib.rs @@ -69,8 +69,9 @@ where .is_active_precompile(address.0, handle.remaining_gas()) { IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile), - IsPrecompileResult::OutOfGas => - Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), + IsPrecompileResult::OutOfGas => { + Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) + }, } } @@ -85,7 +86,7 @@ where // Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15) handle.record_db_read::(175)?; if !is_precompile_or_fail::(address.0, handle.remaining_gas())? { - return Err(revert("provided address is not a precompile")) + return Err(revert("provided address is not a precompile")); } // pallet_evm::create_account read storage item pallet_evm::AccountCodes diff --git a/precompiles/proxy/src/lib.rs b/precompiles/proxy/src/lib.rs index 92e27d5a..8cf81816 100644 --- a/precompiles/proxy/src/lib.rs +++ b/precompiles/proxy/src/lib.rs @@ -60,8 +60,9 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector), + Some(selector) => { + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) + }, } } @@ -91,11 +92,12 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) || - ProxyPrecompileCall::::proxy_selectors().contains(&selector) || - ProxyPrecompileCall::::proxy_force_type_selectors() - .contains(&selector), + Some(selector) => { + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) + || ProxyPrecompileCall::::proxy_selectors().contains(&selector) + || ProxyPrecompileCall::::proxy_force_type_selectors() + .contains(&selector) + }, } } @@ -185,7 +187,7 @@ where .iter() .any(|pd| pd.delegate == delegate) { - return Err(revert("Cannot add more than one proxy")) + return Err(revert("Cannot add more than one proxy")); } let delegate: ::Source = @@ -341,7 +343,7 @@ where // Check that we only perform proxy calls on behalf of externally owned accounts let AddressType::EOA = precompile_set::get_address_type::(handle, real.into())? else { - return Err(revert("real address must be EOA")) + return Err(revert("real address must be EOA")); }; // Read proxy @@ -417,8 +419,9 @@ where // Return subcall result match reason { ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(exit_status) => - Err(PrecompileFailure::Revert { exit_status, output }), + ExitReason::Revert(exit_status) => { + Err(PrecompileFailure::Revert { exit_status, output }) + }, ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Succeed(_) => Ok(()), } diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 402679e8..fba4ea43 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -205,18 +205,19 @@ where (0, ZERO_ADDRESS) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)) + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); } (Asset::Erc20(erc20_token.into()), amount) }, (other_asset_id, ZERO_ADDRESS) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)) + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); } (Asset::Custom(other_asset_id.into()), amount) }, - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; let call = pallet_services::Call::::request { diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 76677de7..7ab17b0b 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -407,7 +407,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false + return false; } true } diff --git a/precompiles/services/src/mock_evm.rs b/precompiles/services/src/mock_evm.rs index c3bdf41b..cd0ccbcf 100644 --- a/precompiles/services/src/mock_evm.rs +++ b/precompiles/services/src/mock_evm.rs @@ -151,7 +151,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation as OnChargeEVMTransaction< @@ -168,7 +168,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation as OnChargeEVMTransaction< @@ -254,8 +254,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -265,8 +266,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, _ => None, } } diff --git a/precompiles/services/src/tests.rs b/precompiles/services/src/tests.rs index 0cde095d..43a0aa01 100644 --- a/precompiles/services/src/tests.rs +++ b/precompiles/services/src/tests.rs @@ -45,8 +45,9 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, + MachineKind::Small => { + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } + }, } } diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 1ab81ec6..aa08dbe3 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -78,7 +78,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index cabd6dd6..b49fdc01 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -344,7 +344,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/verify-bls381-signature/src/lib.rs b/precompiles/verify-bls381-signature/src/lib.rs index 13695778..08e14fd2 100644 --- a/precompiles/verify-bls381-signature/src/lib.rs +++ b/precompiles/verify-bls381-signature/src/lib.rs @@ -55,14 +55,14 @@ impl Bls381Precompile { { p_key } else { - return Ok(false) + return Ok(false); }; let signature = if let Ok(sig) = snowbridge_milagro_bls::Signature::from_bytes(&signature_bytes) { sig } else { - return Ok(false) + return Ok(false); }; let is_confirmed = signature.verify(&message, &public_key); diff --git a/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs b/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs index 03977ad6..c999b30a 100644 --- a/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-secp256k1-signature/src/lib.rs @@ -58,25 +58,14 @@ impl EcdsaSecp256k1Precompile { let maybe_pub_key_point = k256::AffinePoint::from_bytes(public_bytes.as_slice().into()); - let pub_key_point = if let Some(x) = maybe_pub_key_point.into() { - x - } else { - return Ok(false) - }; + let pub_key_point = + if let Some(x) = maybe_pub_key_point.into() { x } else { return Ok(false) }; let maybe_verifying_key = k256::ecdsa::VerifyingKey::from_affine(pub_key_point); - let verifying_key = if let Ok(x) = maybe_verifying_key { - x - } else { - return Ok(false) - }; + let verifying_key = if let Ok(x) = maybe_verifying_key { x } else { return Ok(false) }; let maybe_signature = k256::ecdsa::Signature::from_slice(signature_bytes.as_slice()); - let signature = if let Ok(x) = maybe_signature { - x - } else { - return Ok(false) - }; + let signature = if let Ok(x) = maybe_signature { x } else { return Ok(false) }; let is_confirmed = verifying_key.verify_prehash(&message, &signature).map(|_| signature).is_ok(); diff --git a/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs b/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs index 287bcce6..0c26fcd8 100644 --- a/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-secp256r1-signature/src/lib.rs @@ -58,25 +58,14 @@ impl EcdsaSecp256r1Precompile { let maybe_pub_key_point = p256::AffinePoint::from_bytes(public_bytes.as_slice().into()); - let pub_key_point = if let Some(x) = maybe_pub_key_point.into() { - x - } else { - return Ok(false) - }; + let pub_key_point = + if let Some(x) = maybe_pub_key_point.into() { x } else { return Ok(false) }; let maybe_verifying_key = p256::ecdsa::VerifyingKey::from_affine(pub_key_point); - let verifying_key = if let Ok(x) = maybe_verifying_key { - x - } else { - return Ok(false) - }; + let verifying_key = if let Ok(x) = maybe_verifying_key { x } else { return Ok(false) }; let maybe_signature = p256::ecdsa::Signature::from_slice(signature_bytes.as_slice()); - let signature = if let Ok(x) = maybe_signature { - x - } else { - return Ok(false) - }; + let signature = if let Ok(x) = maybe_signature { x } else { return Ok(false) }; let is_confirmed = verifying_key.verify_prehash(&message, &signature).map(|_| signature).is_ok(); diff --git a/precompiles/verify-ecdsa-stark-signature/src/lib.rs b/precompiles/verify-ecdsa-stark-signature/src/lib.rs index 750c1c07..9bf30160 100644 --- a/precompiles/verify-ecdsa-stark-signature/src/lib.rs +++ b/precompiles/verify-ecdsa-stark-signature/src/lib.rs @@ -59,29 +59,15 @@ impl EcdsaStarkPrecompile { // Parse Signature let r_bytes = &signature_bytes[0..signature_bytes.len() / 2]; let s_bytes = &signature_bytes[signature_bytes.len() / 2..]; - let r = if let Ok(x) = Scalar::from_be_bytes(r_bytes) { - x - } else { - return Ok(false) - }; - - let s = if let Ok(x) = Scalar::from_be_bytes(s_bytes) { - x - } else { - return Ok(false) - }; - - let public_key_point = if let Ok(x) = Point::from_bytes(public_bytes) { - x - } else { - return Ok(false) - }; - - let public_key_x: Scalar = if let Some(x) = public_key_point.x() { - x.to_scalar() - } else { - return Ok(false) - }; + let r = if let Ok(x) = Scalar::from_be_bytes(r_bytes) { x } else { return Ok(false) }; + + let s = if let Ok(x) = Scalar::from_be_bytes(s_bytes) { x } else { return Ok(false) }; + + let public_key_point = + if let Ok(x) = Point::from_bytes(public_bytes) { x } else { return Ok(false) }; + + let public_key_x: Scalar = + if let Some(x) = public_key_point.x() { x.to_scalar() } else { return Ok(false) }; let public_key = convert_stark_scalar(&public_key_x); let msg = convert_stark_scalar(&Scalar::::from_be_bytes_mod_order(message)); diff --git a/precompiles/verify-schnorr-signatures/src/lib.rs b/precompiles/verify-schnorr-signatures/src/lib.rs index 24246325..19b5636b 100644 --- a/precompiles/verify-schnorr-signatures/src/lib.rs +++ b/precompiles/verify-schnorr-signatures/src/lib.rs @@ -55,7 +55,7 @@ pub fn to_slice_32(val: &[u8]) -> Option<[u8; 32]> { let mut key = [0u8; 32]; key[..32].copy_from_slice(val); - return Some(key) + return Some(key); } None } diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index 173396a5..d4c48406 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -79,7 +79,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; @@ -153,7 +153,7 @@ where match pallet_vesting::Vesting::::get(origin.clone()) { Some(schedules) => { if index >= schedules.len() as u8 { - return Err(revert("Invalid vesting schedule index")) + return Err(revert("Invalid vesting schedule index")); } // Make the call to transfer the vested funds to the `target` account. let target = Self::convert_to_account_id(target)?; diff --git a/primitives/rpc/evm-tracing-events/src/evm.rs b/primitives/rpc/evm-tracing-events/src/evm.rs index 688861fd..2b997eae 100644 --- a/primitives/rpc/evm-tracing-events/src/evm.rs +++ b/primitives/rpc/evm-tracing-events/src/evm.rs @@ -61,8 +61,9 @@ impl From for CreateScheme { fn from(i: evm_runtime::CreateScheme) -> Self { match i { evm_runtime::CreateScheme::Legacy { caller } => Self::Legacy { caller }, - evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => - Self::Create2 { caller, code_hash, salt }, + evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => { + Self::Create2 { caller, code_hash, salt } + }, evm_runtime::CreateScheme::Fixed(address) => Self::Fixed(address), } } @@ -166,12 +167,15 @@ impl<'a> From> for EvmEvent { init_code: init_code.to_vec(), target_gas, }, - evm::tracing::Event::Suicide { address, target, balance } => - Self::Suicide { address, target, balance }, - evm::tracing::Event::Exit { reason, return_value } => - Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() }, - evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => - Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit }, + evm::tracing::Event::Suicide { address, target, balance } => { + Self::Suicide { address, target, balance } + }, + evm::tracing::Event::Exit { reason, return_value } => { + Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() } + }, + evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => { + Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit } + }, evm::tracing::Event::TransactCreate { caller, value, diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index d1fbb453..85d8352b 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -59,12 +59,15 @@ pub enum GasometerEvent { impl From for GasometerEvent { fn from(i: evm_gasometer::tracing::Event) -> Self { match i { - evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => - Self::RecordCost { cost, snapshot: snapshot.into() }, - evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => - Self::RecordRefund { refund, snapshot: snapshot.into() }, - evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => - Self::RecordStipend { stipend, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => { + Self::RecordCost { cost, snapshot: snapshot.into() } + }, + evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => { + Self::RecordRefund { refund, snapshot: snapshot.into() } + }, + evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => { + Self::RecordStipend { stipend, snapshot: snapshot.into() } + }, evm_gasometer::tracing::Event::RecordDynamicCost { gas_cost, memory_gas, @@ -76,8 +79,9 @@ impl From for GasometerEvent { gas_refund, snapshot: snapshot.into(), }, - evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => - Self::RecordTransaction { cost, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => { + Self::RecordTransaction { cost, snapshot: snapshot.into() } + }, } } } diff --git a/primitives/rpc/evm-tracing-events/src/runtime.rs b/primitives/rpc/evm-tracing-events/src/runtime.rs index ad738f73..089932d5 100644 --- a/primitives/rpc/evm-tracing-events/src/runtime.rs +++ b/primitives/rpc/evm-tracing-events/src/runtime.rs @@ -92,7 +92,7 @@ impl RuntimeEvent { filter: crate::StepEventFilter, ) -> Self { match i { - evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => + evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => { Self::Step { context: context.clone().into(), opcode: opcodes_string(opcode), @@ -102,7 +102,8 @@ impl RuntimeEvent { }, stack: if filter.enable_stack { Some(stack.into()) } else { None }, memory: if filter.enable_memory { Some(memory.into()) } else { None }, - }, + } + }, evm_runtime::tracing::Event::StepResult { result, return_value } => Self::StepResult { result: match result { Ok(_) => Ok(()), @@ -113,10 +114,12 @@ impl RuntimeEvent { }, return_value: return_value.to_vec(), }, - evm_runtime::tracing::Event::SLoad { address, index, value } => - Self::SLoad { address, index, value }, - evm_runtime::tracing::Event::SStore { address, index, value } => - Self::SStore { address, index, value }, + evm_runtime::tracing::Event::SLoad { address, index, value } => { + Self::SLoad { address, index, value } + }, + evm_runtime::tracing::Event::SStore { address, index, value } => { + Self::SStore { address, index, value } + }, } } } diff --git a/primitives/src/chain_identifier.rs b/primitives/src/chain_identifier.rs index d916c2a2..72155a8a 100644 --- a/primitives/src/chain_identifier.rs +++ b/primitives/src/chain_identifier.rs @@ -65,14 +65,14 @@ impl TypedChainId { #[must_use] pub const fn underlying_chain_id(&self) -> u32 { match self { - TypedChainId::Evm(id) | - TypedChainId::Substrate(id) | - TypedChainId::PolkadotParachain(id) | - TypedChainId::KusamaParachain(id) | - TypedChainId::RococoParachain(id) | - TypedChainId::Cosmos(id) | - TypedChainId::Solana(id) | - TypedChainId::Ink(id) => *id, + TypedChainId::Evm(id) + | TypedChainId::Substrate(id) + | TypedChainId::PolkadotParachain(id) + | TypedChainId::KusamaParachain(id) + | TypedChainId::RococoParachain(id) + | TypedChainId::Cosmos(id) + | TypedChainId::Solana(id) + | TypedChainId::Ink(id) => *id, Self::None => 0, } } diff --git a/primitives/src/services/field.rs b/primitives/src/services/field.rs index 8fd27a35..c03869aa 100644 --- a/primitives/src/services/field.rs +++ b/primitives/src/services/field.rs @@ -172,13 +172,13 @@ impl PartialEq for Field { (Self::AccountId(l0), Self::AccountId(r0)) => l0 == r0, (Self::Struct(l_name, l_fields), Self::Struct(r_name, r_fields)) => { if l_name != r_name || l_fields.len() != r_fields.len() { - return false + return false; } for ((l_field_name, l_field_value), (r_field_name, r_field_value)) in l_fields.iter().zip(r_fields.iter()) { if l_field_name != r_field_name || l_field_value != r_field_value { - return false + return false; } } true @@ -307,16 +307,18 @@ impl PartialEq for Field { (Self::Int64(_), FieldType::Int64) => true, (Self::String(_), FieldType::String) => true, (Self::Bytes(_), FieldType::Bytes) => true, - (Self::Array(a), FieldType::Array(len, b)) => - a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())), + (Self::Array(a), FieldType::Array(len, b)) => { + a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())) + }, (Self::List(a), FieldType::List(b)) => a.iter().all(|f| f.eq(b.as_ref())), (Self::AccountId(_), FieldType::AccountId) => true, - (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => - fields_a.into_iter().len() == fields_b.into_iter().len() && - fields_a + (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => { + fields_a.into_iter().len() == fields_b.into_iter().len() + && fields_a .into_iter() .zip(fields_b) - .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)), + .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)) + }, _ => false, } } @@ -420,7 +422,7 @@ impl Field { /// Encode the fields to ethabi bytes. pub fn encode_to_ethabi(fields: &[Self]) -> ethabi::Bytes { if fields.is_empty() { - return Default::default() + return Default::default(); } let tokens: Vec = fields.iter().map(Self::to_ethabi_token).collect(); ethabi::encode(&tokens) diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 8e5df081..4bc9255c 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -161,7 +161,7 @@ pub fn type_checker( return Err(TypeCheckError::NotEnoughArguments { expected: params.len() as u8, actual: args.len() as u8, - }) + }); } for i in 0..args.len() { let arg = &args[i]; @@ -171,7 +171,7 @@ pub fn type_checker( index: i as u8, expected: expected.clone(), actual: arg.clone().into(), - }) + }); } } Ok(()) @@ -485,10 +485,12 @@ impl ServiceBlueprint { }, // Master Manager Revision match self.master_manager_revision { - MasterBlueprintServiceManagerRevision::Latest => - ethabi::Token::Uint(ethabi::Uint::MAX), - MasterBlueprintServiceManagerRevision::Specific(rev) => - ethabi::Token::Uint(rev.into()), + MasterBlueprintServiceManagerRevision::Latest => { + ethabi::Token::Uint(ethabi::Uint::MAX) + }, + MasterBlueprintServiceManagerRevision::Specific(rev) => { + ethabi::Token::Uint(rev.into()) + }, }, // Gadget ? ]) @@ -624,9 +626,21 @@ pub enum ApprovalState { } /// Different types of assets that can be used. -#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Copy, Clone, MaxEncodedLen, Ord, PartialOrd)] +#[derive( + PartialEq, + Eq, + Encode, + Decode, + RuntimeDebug, + TypeInfo, + Copy, + Clone, + MaxEncodedLen, + Ord, + PartialOrd, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Asset { +pub enum Asset { /// Use the specified AssetId. #[codec(index = 0)] Custom(AssetId), diff --git a/primitives/src/traits/services.rs b/primitives/src/traits/services.rs index 20b463c4..4d1d8ef1 100644 --- a/primitives/src/traits/services.rs +++ b/primitives/src/traits/services.rs @@ -68,4 +68,4 @@ pub trait EvmAddressMapping { /// Convert an account id to an address. fn into_address(account_id: A) -> H160; -} \ No newline at end of file +} diff --git a/primitives/src/verifier/circom.rs b/primitives/src/verifier/circom.rs index 34251912..4dbf7303 100644 --- a/primitives/src/verifier/circom.rs +++ b/primitives/src/verifier/circom.rs @@ -51,28 +51,28 @@ impl super::InstanceVerifier for CircomVerifierGroth16Bn254 { Ok(v) => v, Err(e) => { log::error!("Failed to convert public input bytes to field elements: {e:?}",); - return Err(e) + return Err(e); }, }; let vk = match ArkVerifyingKey::deserialize_compressed(vk_bytes) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize verifying key: {e:?}"); - return Err(e.into()) + return Err(e.into()); }, }; let proof = match Proof::decode(proof_bytes).and_then(|v| v.try_into()) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize proof: {e:?}"); - return Err(e) + return Err(e); }, }; let res = match verify_groth16(&vk, &public_input_field_elts, &proof) { Ok(v) => v, Err(e) => { log::error!("Failed to verify proof: {e:?}"); - return Err(e) + return Err(e); }, }; @@ -246,7 +246,7 @@ fn point_to_u256(point: F) -> Result { let point = point.into_bigint(); let point_bytes = point.to_bytes_be(); if point_bytes.len() != 32 { - return Err(CircomError::InvalidProofBytes.into()) + return Err(CircomError::InvalidProofBytes.into()); } Ok(U256::from(&point_bytes[..])) } diff --git a/runtime/mainnet/src/filters.rs b/runtime/mainnet/src/filters.rs index de74c9ff..1307096e 100644 --- a/runtime/mainnet/src/filters.rs +++ b/runtime/mainnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for MainnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true + return true; } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false + return false; } true diff --git a/runtime/mainnet/src/frontier_evm.rs b/runtime/mainnet/src/frontier_evm.rs index 39b31cd1..8f135bae 100644 --- a/runtime/mainnet/src/frontier_evm.rs +++ b/runtime/mainnet/src/frontier_evm.rs @@ -61,7 +61,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); } None } @@ -119,20 +119,21 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { ) -> precompile_utils::EvmResult { Ok(match self { ProxyType::Any => true, - ProxyType::Governance => - call.value == U256::zero() && - matches!( + ProxyType::Governance => { + call.value == U256::zero() + && matches!( PrecompileName::from_address(call.to.0), Some(ref precompile) if is_governance_precompile(precompile) - ), + ) + }, // The proxy precompile does not contain method cancel_proxy ProxyType::CancelProxy => false, ProxyType::Balances => { // Allow only "simple" accounts as recipient (no code nor precompile). // Note: Checking the presence of the code is not enough because some precompiles // have no code. - !recipient_has_code && - !precompile_utils::precompile_set::is_precompile_or_fail::( + !recipient_has_code + && !precompile_utils::precompile_set::is_precompile_or_fail::( call.to.0, gas, )? }, diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index daeafe63..bc7bc542 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -656,8 +656,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") % - max.saturating_add(1); + .expect("input is padded with zeroes; qed") + % max.saturating_add(1); random as usize }, }; @@ -1148,15 +1148,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) | - RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) + | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) | - RuntimeCall::Council(..) | - RuntimeCall::Elections(..) | - RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) + | RuntimeCall::Council(..) + | RuntimeCall::Elections(..) + | RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1465,8 +1465,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -1476,10 +1477,11 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))), + ))) + }, _ => None, } } diff --git a/runtime/testnet/src/filters.rs b/runtime/testnet/src/filters.rs index 65e021b6..d46f0914 100644 --- a/runtime/testnet/src/filters.rs +++ b/runtime/testnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for TestnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true + return true; } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false + return false; } true diff --git a/runtime/testnet/src/frontier_evm.rs b/runtime/testnet/src/frontier_evm.rs index a11fe1f7..23fb1f1a 100644 --- a/runtime/testnet/src/frontier_evm.rs +++ b/runtime/testnet/src/frontier_evm.rs @@ -64,7 +64,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); } None } @@ -99,7 +99,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation > as OnChargeEVMTransaction< @@ -116,7 +116,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation > as OnChargeEVMTransaction< diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 1ab674fe..5ce483da 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -663,8 +663,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") % - max.saturating_add(1); + .expect("input is padded with zeroes; qed") + % max.saturating_add(1); random as usize }, }; @@ -1146,15 +1146,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) | - RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) + | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) | - RuntimeCall::Council(..) | - RuntimeCall::Elections(..) | - RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) + | RuntimeCall::Council(..) + | RuntimeCall::Elections(..) + | RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1387,8 +1387,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -1398,10 +1399,11 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))), + ))) + }, _ => None, } } From a704da22d6f2b56752e01442828f0b6bb270fef4 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Sat, 14 Dec 2024 00:15:30 +0530 Subject: [PATCH 11/63] cleanup --- client/rpc/debug/src/lib.rs | 4 +++- pallets/multi-asset-delegation/src/functions/evm.rs | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index aa85097d..09b2b932 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -751,7 +751,9 @@ where }; if trace_api_version <= 5 { - return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); + return Err(internal_err( + "debug_traceCall not supported with old runtimes".to_string(), + )); } let TraceCallParams { diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index 11996527..ebb83696 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -10,11 +10,10 @@ impl Pallet { /// Moves a `value` amount of tokens from the caller's account to `to`. pub fn erc20_transfer( erc20: H160, - caller: &T::AccountId, + from: &H160, to: H160, value: BalanceOf, ) -> Result<(bool, Weight), DispatchErrorWithPostInfo> { - let from = T::EvmAddressMapping::into_address(caller.clone()); #[allow(deprecated)] let transfer_fn = Function { name: String::from("transfer"), From 6b51c970ea0e3eb5e4dbee085e47eb4750bf2dce Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:24:01 +0530 Subject: [PATCH 12/63] compiling --- Cargo.lock | 6 + pallets/multi-asset-delegation/Cargo.toml | 9 +- .../src/functions/deposit.rs | 51 +++++---- .../src/functions/evm.rs | 92 ++++++++++++++- .../src/functions/rewards.rs | 107 ++++++++++-------- pallets/multi-asset-delegation/src/lib.rs | 39 ++++--- pallets/multi-asset-delegation/src/traits.rs | 5 +- .../src/types/operator.rs | 6 +- pallets/services/src/traits.rs | 42 ------- primitives/Cargo.toml | 6 +- primitives/src/services/mod.rs | 45 +++++++- .../src/traits/multi_asset_delegation.rs | 11 +- 12 files changed, 274 insertions(+), 145 deletions(-) delete mode 100644 pallets/services/src/traits.rs diff --git a/Cargo.lock b/Cargo.lock index fd8bfcbb..6fafd877 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8283,14 +8283,18 @@ name = "pallet-multi-asset-delegation" version = "1.2.3" dependencies = [ "ethabi", + "fp-evm", "frame-benchmarking", "frame-support", "frame-system", + "hex", + "itertools 0.13.0", "log", "pallet-assets", "pallet-balances", "parity-scale-codec", "scale-info", + "serde", "sp-core", "sp-io", "sp-runtime", @@ -14233,7 +14237,9 @@ dependencies = [ "ark-std", "educe 0.6.0", "ethabi", + "fp-evm", "frame-support", + "frame-system", "hex", "log", "parity-scale-codec", diff --git a/pallets/multi-asset-delegation/Cargo.toml b/pallets/multi-asset-delegation/Cargo.toml index 379b972a..4c1cb335 100644 --- a/pallets/multi-asset-delegation/Cargo.toml +++ b/pallets/multi-asset-delegation/Cargo.toml @@ -22,6 +22,10 @@ ethabi = { workspace = true } pallet-balances = { workspace = true } tangle-primitives = { workspace = true } pallet-assets = { workspace = true, default-features = false } +fp-evm = { workspace = true } +itertools = { workspace = true, features = ["use_alloc"] } +serde = { workspace = true, features = ["derive"], optional = true } +hex = { workspace = true, features = ["alloc"] } [features] default = ["std"] @@ -37,7 +41,10 @@ std = [ "pallet-assets/std", "tangle-primitives/std", "ethabi/std", - "log/std" + "log/std", + "fp-evm/std", + "serde/std", + "hex/std", ] try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index daa87875..5b8eb6d7 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -46,6 +46,7 @@ impl Pallet { sender: &T::AccountId, asset_id: Asset, amount: BalanceOf, + evm_sender: Option, ) -> DispatchResult { match asset_id { Asset::Custom(asset_id) => { @@ -58,13 +59,14 @@ impl Pallet { ); }, Asset::Erc20(asset_address) => { + let sender = evm_sender.ok_or(Error::::ERC20TransferFailed)?; let (success, _weight) = Self::erc20_transfer( asset_address, &sender, Self::pallet_evm_account(), amount, ) - .map_err(|_| Error::::ERC20TransferFailed)?; + .map_err(|e| Error::::ERC20TransferFailed)?; ensure!(success, Error::::ERC20TransferFailed); }, } @@ -87,11 +89,12 @@ impl Pallet { who: T::AccountId, asset_id: Asset, amount: BalanceOf, + evm_address: Option, ) -> DispatchResult { ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); // Transfer the amount to the pallet account - Self::handle_transfer_to_pallet(&who, asset_id, amount)?; + Self::handle_transfer_to_pallet(&who, asset_id, amount, evm_address)?; // Update storage Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { @@ -179,32 +182,34 @@ impl Pallet { // Process all ready withdraw requests metadata.withdraw_requests.retain(|request| { if current_round >= delay + request.requested_round { - // Transfer the amount back to the delegator match request.asset_id { - Asset::Custom(asset_id) => { - T::Fungibles::transfer( - asset_id, - &Self::pallet_account(), - &who, - request.amount, - Preservation::Expendable, - ) - .expect("Transfer should not fail"); - }, + Asset::Custom(asset_id) => T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &who, + request.amount, + Preservation::Expendable, + ) + .is_ok(), Asset::Erc20(asset_address) => { - let (success, _weight) = Self::erc20_transfer( - asset_address, - &Self::pallet_evm_account(), - evm_address.unwrap(), - request.amount, - ) - .map_err(|_| Error::::ERC20TransferFailed)?; - ensure!(success, Error::::ERC20TransferFailed); + if let Some(evm_addr) = evm_address { + if let Ok((success, _weight)) = Self::erc20_transfer( + asset_address, + &Self::pallet_evm_account(), + evm_addr, + request.amount, + ) { + success + } else { + false + } + } else { + false + } }, } - false // Remove this request } else { - true // Keep this request + true } }); diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index ebb83696..cd2e79b5 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -2,8 +2,13 @@ use super::*; use crate::types::BalanceOf; use ethabi::{Function, StateMutability, Token}; use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; +use frame_support::pallet_prelude::Pays; use frame_support::pallet_prelude::Weight; +use parity_scale_codec::Encode; use sp_core::{H160, U256}; +use sp_runtime::traits::UniqueSaturatedInto; +use tangle_primitives::services::EvmGasWeightMapping; +use tangle_primitives::services::EvmRunner; use tangle_primitives::EvmAddressMapping; impl Pallet { @@ -46,7 +51,7 @@ impl Pallet { log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(transfer_fn.short_signature()), transfer_fn.signature()); let data = transfer_fn.encode_input(&args).map_err(|_| Error::::EVMAbiEncode)?; let gas_limit = 300_000; - let info = Self::evm_call(from, erc20, U256::zero(), data, gas_limit)?; + let info = Self::evm_call(*from, erc20, U256::zero(), data, gas_limit)?; let weight = Self::weight_from_call_info(&info); // decode the result and return it @@ -65,4 +70,89 @@ impl Pallet { Ok((success, weight)) } + + /// Dispatches a hook to the EVM and returns if the result with the used weight. + fn dispatch_evm_call( + contract: H160, + f: Function, + args: &[ethabi::Token], + value: BalanceOf, + ) -> Result<(fp_evm::CallInfo, Weight), DispatchErrorWithPostInfo> { + log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(f.short_signature()), f.signature()); + let data = f.encode_input(args).map_err(|_| Error::::EVMAbiEncode)?; + let gas_limit = 300_000; + let value = value.using_encoded(U256::from_little_endian); + let info = Self::evm_call(Self::pallet_evm_account(), contract, value, data, gas_limit)?; + let weight = Self::weight_from_call_info(&info); + Ok((info, weight)) + } + + /// Dispatches a call to the EVM and returns the result. + fn evm_call( + from: H160, + to: H160, + value: U256, + data: Vec, + gas_limit: u64, + ) -> Result { + let transactional = true; + let validate = false; + let result = + T::EvmRunner::call(from, to, data.clone(), value, gas_limit, transactional, validate); + match result { + Ok(info) => { + log::debug!( + target: "evm", + "Call from: {:?}, to: {:?}, data: 0x{}, gas_limit: {:?}, result: {:?}", + from, + to, + hex::encode(&data), + gas_limit, + info, + ); + // if we have a revert reason, emit an event + if info.exit_reason.is_revert() { + log::debug!( + target: "evm", + "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", + to, + hex::encode(&data), + hex::encode(&info.value), + ); + #[cfg(test)] + eprintln!( + "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", + to, + hex::encode(&data), + hex::encode(&info.value), + ); + Self::deposit_event(Event::::EvmReverted { + from, + to, + data, + reason: info.value.clone(), + }); + } + Ok(info) + }, + Err(e) => Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: Some(e.weight), pays_fee: Pays::Yes }, + error: e.error.into(), + }), + } + } + + /// Convert the gas used in the call info to weight. + pub fn weight_from_call_info(info: &fp_evm::CallInfo) -> Weight { + let mut gas_to_weight = T::EvmGasWeightMapping::gas_to_weight( + info.used_gas.standard.unique_saturated_into(), + true, + ); + if let Some(weight_info) = info.weight_info { + if let Some(proof_size_usage) = weight_info.proof_size_usage { + *gas_to_weight.proof_size_mut() = proof_size_usage; + } + } + gas_to_weight + } } diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs index 860e971e..06cf9ef5 100644 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ b/pallets/multi-asset-delegation/src/functions/rewards.rs @@ -21,59 +21,60 @@ use crate::{ use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; use sp_runtime::{traits::Zero, DispatchError, Saturating}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use tangle_primitives::services::Asset; use tangle_primitives::RoundIndex; impl Pallet { #[allow(clippy::type_complexity)] pub fn distribute_rewards(round: RoundIndex) -> DispatchResult { - let mut delegation_info: BTreeMap< - T::AssetId, - Vec, T::AssetId>>, - > = BTreeMap::new(); - - // Iterate through all operator snapshots for the given round - // TODO: Could be dangerous with many operators - for (_, operator_snapshot) in AtStake::::iter_prefix(round) { - for delegation in &operator_snapshot.delegations { - delegation_info.entry(delegation.asset_id).or_default().push(delegation.clone()); - } - } - - // Get the reward configuration - if let Some(reward_config) = RewardConfigStorage::::get() { - // Distribute rewards for each asset - for (asset_id, delegations) in delegation_info.iter() { - // We only reward asset in a reward vault - if let Some(vault_id) = AssetLookupRewardVaults::::get(asset_id) { - if let Some(config) = reward_config.configs.get(&vault_id) { - // Calculate total amount and distribute rewards - let total_amount: BalanceOf = - delegations.iter().fold(Zero::zero(), |acc, d| acc + d.amount); - let cap: BalanceOf = config.cap; - - if total_amount >= cap { - // Calculate the total reward based on the APY - let total_reward = - Self::calculate_total_reward(config.apy, total_amount)?; - - for delegation in delegations { - // Calculate the percentage of the cap that the user is staking - let staking_percentage = - delegation.amount.saturating_mul(100u32.into()) / cap; - // Calculate the reward based on the staking percentage - let reward = - total_reward.saturating_mul(staking_percentage) / 100u32.into(); - // Distribute the reward to the delegator - Self::distribute_reward_to_delegator( - &delegation.delegator, - reward, - )?; - } - } - } - } - } - } + // let mut delegation_info: BTreeMap< + // T::AssetId, + // Vec, T::AssetId>>, + // > = BTreeMap::new(); + + // // Iterate through all operator snapshots for the given round + // // TODO: Could be dangerous with many operators + // for (_, operator_snapshot) in AtStake::::iter_prefix(round) { + // for delegation in &operator_snapshot.delegations { + // delegation_info.entry(delegation.asset_id).or_default().push(delegation.clone()); + // } + // } + + // // Get the reward configuration + // if let Some(reward_config) = RewardConfigStorage::::get() { + // // Distribute rewards for each asset + // for (asset_id, delegations) in delegation_info.iter() { + // // We only reward asset in a reward vault + // if let Some(vault_id) = AssetLookupRewardVaults::::get(asset_id) { + // if let Some(config) = reward_config.configs.get(&vault_id) { + // // Calculate total amount and distribute rewards + // let total_amount: BalanceOf = + // delegations.iter().fold(Zero::zero(), |acc, d| acc + d.amount); + // let cap: BalanceOf = config.cap; + + // if total_amount >= cap { + // // Calculate the total reward based on the APY + // let total_reward = + // Self::calculate_total_reward(config.apy, total_amount)?; + + // for delegation in delegations { + // // Calculate the percentage of the cap that the user is staking + // let staking_percentage = + // delegation.amount.saturating_mul(100u32.into()) / cap; + // // Calculate the reward based on the staking percentage + // let reward = + // total_reward.saturating_mul(staking_percentage) / 100u32.into(); + // // Distribute the reward to the delegator + // Self::distribute_reward_to_delegator( + // &delegation.delegator, + // reward, + // )?; + // } + // } + // } + // } + // } + // } Ok(()) } @@ -95,7 +96,10 @@ impl Pallet { Ok(()) } - pub fn add_asset_to_vault(vault_id: &T::VaultId, asset_id: &T::AssetId) -> DispatchResult { + pub fn add_asset_to_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { // Ensure the asset is not already associated with any vault ensure!( !AssetLookupRewardVaults::::contains_key(asset_id), @@ -120,7 +124,10 @@ impl Pallet { Ok(()) } - pub fn remove_asset_from_vault(vault_id: &T::VaultId, asset_id: &T::AssetId) -> DispatchResult { + pub fn remove_asset_from_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { // Update RewardVaults storage RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { let assets = maybe_assets.as_mut().ok_or(Error::::VaultNotFound)?; diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 2280838f..61ec3256 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -86,6 +86,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; use scale_info::TypeInfo; + use sp_core::H160; use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; use sp_std::vec::Vec; use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; @@ -190,6 +191,14 @@ pub mod pallet { /// The address that receives slashed funds type SlashedAmountRecipient: Get; + /// A type that implements the `EvmRunner` trait for the execution of EVM + /// transactions. + type EvmRunner: tangle_primitives::services::EvmRunner; + + /// A type that implements the `EvmGasWeightMapping` trait for the conversion of EVM gas to + /// Substrate weight and vice versa. + type EvmGasWeightMapping: tangle_primitives::services::EvmGasWeightMapping; + /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address type EvmAddressMapping: tangle_primitives::traits::EvmAddressMapping; @@ -236,13 +245,13 @@ pub mod pallet { #[pallet::getter(fn reward_vaults)] /// Storage for the reward vaults pub type RewardVaults = - StorageMap<_, Blake2_128Concat, T::VaultId, Vec, OptionQuery>; + StorageMap<_, Blake2_128Concat, T::VaultId, Vec>, OptionQuery>; #[pallet::storage] #[pallet::getter(fn asset_reward_vault_lookup)] /// Storage for the reward vaults pub type AssetLookupRewardVaults = - StorageMap<_, Blake2_128Concat, T::AssetId, T::VaultId, OptionQuery>; + StorageMap<_, Blake2_128Concat, Asset, T::VaultId, OptionQuery>; #[pallet::storage] #[pallet::getter(fn reward_config)] @@ -276,9 +285,9 @@ pub mod pallet { /// An operator has gone online. OperatorWentOnline { who: T::AccountId }, /// A deposit has been made. - Deposited { who: T::AccountId, amount: BalanceOf, asset_id: T::AssetId }, + Deposited { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, /// An withdraw has been scheduled. - Scheduledwithdraw { who: T::AccountId, amount: BalanceOf, asset_id: T::AssetId }, + Scheduledwithdraw { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, /// An withdraw has been executed. Executedwithdraw { who: T::AccountId }, /// An withdraw has been cancelled. @@ -316,6 +325,8 @@ pub mod pallet { OperatorSlashed { who: T::AccountId, amount: BalanceOf }, /// Delegator has been slashed DelegatorSlashed { who: T::AccountId, amount: BalanceOf }, + /// EVM execution reverted with a reason. + EvmReverted { from: H160, to: H160, data: Vec, reason: Vec }, } /// Errors emitted by the pallet. @@ -417,6 +428,10 @@ pub mod pallet { BlueprintNotSelected, /// Erc20 transfer failed ERC20TransferFailed, + /// EVM encode error + EVMAbiEncode, + /// EVM decode error + EVMAbiDecode, } /// Hooks for the pallet. @@ -539,9 +554,10 @@ pub mod pallet { origin: OriginFor, asset_id: Asset, amount: BalanceOf, + evm_address: Option, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::process_deposit(who.clone(), asset_id, amount)?; + Self::process_deposit(who.clone(), asset_id, amount, evm_address)?; Self::deposit_event(Event::Deposited { who, amount, asset_id }); Ok(()) } @@ -563,9 +579,9 @@ pub mod pallet { /// Executes a scheduled withdraw request. #[pallet::call_index(12)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn execute_withdraw(origin: OriginFor) -> DispatchResult { + pub fn execute_withdraw(origin: OriginFor, evm_address: Option) -> DispatchResult { let who = ensure_signed(origin)?; - Self::process_execute_withdraw(who.clone())?; + Self::process_execute_withdraw(who.clone(), evm_address)?; Self::deposit_event(Event::Executedwithdraw { who }); Ok(()) } @@ -680,15 +696,6 @@ pub mod pallet { // Validate cap is not zero ensure!(!cap.is_zero(), Error::::CapCannotBeZero); - // Validate the cap is not greater than the total supply - let asset_ids = RewardVaults::::get(vault_id).ok_or(Error::::VaultNotFound)?; - for asset_id in asset_ids.iter() { - ensure!( - T::Fungibles::total_issuance(*asset_id) >= cap, - Error::::CapExceedsTotalSupply - ); - } - // Initialize the reward config if not already initialized RewardConfigStorage::::mutate(|maybe_config| { let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { diff --git a/pallets/multi-asset-delegation/src/traits.rs b/pallets/multi-asset-delegation/src/traits.rs index d7877ba6..ff65ded0 100644 --- a/pallets/multi-asset-delegation/src/traits.rs +++ b/pallets/multi-asset-delegation/src/traits.rs @@ -18,6 +18,7 @@ use crate::types::{BalanceOf, OperatorStatus}; use sp_runtime::traits::Zero; use sp_runtime::Percent; use sp_std::prelude::*; +use tangle_primitives::services::Asset; use tangle_primitives::BlueprintId; use tangle_primitives::{traits::MultiAssetDelegationInfo, RoundIndex}; @@ -43,7 +44,7 @@ impl MultiAssetDelegationInfo> for fn get_total_delegation_by_asset_id( operator: &T::AccountId, - asset_id: &T::AssetId, + asset_id: &Asset, ) -> BalanceOf { Operators::::get(operator).map_or(Zero::zero(), |metadata| { metadata @@ -56,7 +57,7 @@ impl MultiAssetDelegationInfo> for fn get_delegators_for_operator( operator: &T::AccountId, - ) -> Vec<(T::AccountId, BalanceOf, Self::AssetId)> { + ) -> Vec<(T::AccountId, BalanceOf, Asset)> { Operators::::get(operator).map_or(Vec::new(), |metadata| { metadata .delegations diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 47ab4a06..88f81670 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -37,7 +37,7 @@ where Balance: Default + core::ops::AddAssign + Copy, { /// Calculates the total stake for a specific asset ID from all delegations. - pub fn get_stake_by_asset_id(&self, asset_id: AssetId) -> Balance { + pub fn get_stake_by_asset_id(&self, asset_id: Asset) -> Balance { let mut total_stake = Balance::default(); for stake in &self.delegations { if stake.asset_id == asset_id { @@ -48,8 +48,8 @@ where } /// Calculates the total stake for each asset and returns a list of (asset_id, total_stake). - pub fn get_total_stake_by_assets(&self) -> Vec<(AssetId, Balance)> { - let mut stake_by_asset: BTreeMap = BTreeMap::new(); + pub fn get_total_stake_by_assets(&self) -> Vec<(Asset, Balance)> { + let mut stake_by_asset: BTreeMap, Balance> = BTreeMap::new(); for stake in &self.delegations { let entry = stake_by_asset.entry(stake.asset_id).or_default(); diff --git a/pallets/services/src/traits.rs b/pallets/services/src/traits.rs deleted file mode 100644 index c8f50155..00000000 --- a/pallets/services/src/traits.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::Weight; -use fp_evm::CallInfo; -use sp_core::{H160, U256}; -use sp_std::vec::Vec; - -#[derive(Debug)] -pub struct RunnerError> { - pub error: E, - pub weight: Weight, -} - -#[allow(clippy::too_many_arguments)] -pub trait EvmRunner { - type Error: Into; - - fn call( - source: H160, - target: H160, - input: Vec, - value: U256, - gas_limit: u64, - is_transactional: bool, - validate: bool, - ) -> Result>; -} - -/// A mapping function that converts EVM gas to Substrate weight and vice versa -pub trait EvmGasWeightMapping { - /// Convert EVM gas to Substrate weight - fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight; - /// Convert Substrate weight to EVM gas - fn weight_to_gas(weight: Weight) -> u64; -} - -/// Trait to be implemented for evm address mapping. -pub trait EvmAddressMapping { - /// Convert an address to an account id. - fn into_account_id(address: H160) -> A; - - /// Convert an account id to an address. - fn into_address(account_id: A) -> H160; -} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 20cadd20..6dda244e 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -21,6 +21,8 @@ sp-runtime = { workspace = true } sp-std = { workspace = true } sp-staking = { workspace = true } ethabi = { workspace = true } +fp-evm = { workspace = true } +frame-system = { workspace = true } # Arkworks ark-bn254 = { workspace = true, optional = true } @@ -69,7 +71,9 @@ std = [ "ark-groth16?/std", "ark-serialize?/std", "ethabi/std", - "sp-staking/std" + "sp-staking/std", + "fp-evm/std", + "frame-system/std", ] verifying = [ "ark-crypto-primitives", diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 4bc9255c..69f674da 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -31,13 +31,16 @@ // along with Tangle. If not, see . //! Services primitives. - +use crate::Weight; use educe::Educe; +use fp_evm::CallInfo; use frame_support::pallet_prelude::*; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; use sp_core::{ecdsa, RuntimeDebug}; +use sp_core::{H160, U256}; use sp_runtime::Percent; +use sp_std::vec::Vec; #[cfg(not(feature = "std"))] use alloc::{string::String, vec, vec::Vec}; @@ -640,7 +643,7 @@ pub enum ApprovalState { PartialOrd, )] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum Asset { +pub enum Asset { /// Use the specified AssetId. #[codec(index = 0)] Custom(AssetId), @@ -1116,3 +1119,41 @@ pub struct RpcServicesWithBlueprint>, } + +#[derive(Debug)] +pub struct RunnerError> { + pub error: E, + pub weight: Weight, +} + +#[allow(clippy::too_many_arguments)] +pub trait EvmRunner { + type Error: Into; + + fn call( + source: H160, + target: H160, + input: Vec, + value: U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result>; +} + +/// A mapping function that converts EVM gas to Substrate weight and vice versa +pub trait EvmGasWeightMapping { + /// Convert EVM gas to Substrate weight + fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight; + /// Convert Substrate weight to EVM gas + fn weight_to_gas(weight: Weight) -> u64; +} + +/// Trait to be implemented for evm address mapping. +pub trait EvmAddressMapping { + /// Convert an address to an account id. + fn into_account_id(address: H160) -> A; + + /// Convert an account id to an address. + fn into_address(account_id: A) -> H160; +} diff --git a/primitives/src/traits/multi_asset_delegation.rs b/primitives/src/traits/multi_asset_delegation.rs index 73b0d900..7afc1835 100644 --- a/primitives/src/traits/multi_asset_delegation.rs +++ b/primitives/src/traits/multi_asset_delegation.rs @@ -1,6 +1,6 @@ -use sp_std::prelude::*; - +use crate::services::Asset; use crate::types::RoundIndex; +use sp_std::prelude::*; /// A trait to provide information about multi-asset delegation. /// @@ -81,7 +81,10 @@ pub trait MultiAssetDelegationInfo { /// # Returns /// /// The total delegation amount as a `Balance`. - fn get_total_delegation_by_asset_id(operator: &AccountId, asset_id: &Self::AssetId) -> Balance; + fn get_total_delegation_by_asset_id( + operator: &AccountId, + asset_id: &Asset, + ) -> Balance; /// Get all delegators for a specific operator. /// @@ -98,7 +101,7 @@ pub trait MultiAssetDelegationInfo { /// delegator account identifier, delegation amount, and asset identifier. fn get_delegators_for_operator( operator: &AccountId, - ) -> Vec<(AccountId, Balance, Self::AssetId)>; + ) -> Vec<(AccountId, Balance, Asset)>; fn slash_operator( operator: &AccountId, From 4cc8780675fd034cd02aaaf0c16cf7e1352be713 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:05:29 +0530 Subject: [PATCH 13/63] precompiles fixes --- pallets/multi-asset-delegation/src/lib.rs | 7 +- pallets/services/src/functions.rs | 3 + pallets/services/src/impls.rs | 34 ----- pallets/services/src/lib.rs | 8 +- precompiles/multi-asset-delegation/src/lib.rs | 127 ++++++++++++++---- primitives/src/services/mod.rs | 9 ++ 6 files changed, 121 insertions(+), 67 deletions(-) diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 61ec3256..57a77ec3 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -604,12 +604,11 @@ pub mod pallet { #[pallet::call_index(14)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn delegate( - origin: OriginFor, // 5cxssdfsd - operator: T::AccountId, // xcxcv - asset_id: Asset, // evm(usdt) + origin: OriginFor, + operator: T::AccountId, + asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, - //evm_address : Option, // Some(shady_evm_address) ) -> DispatchResult { let who = ensure_signed(origin)?; Self::process_delegate( diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index 2196ecb2..dc6773f9 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -8,6 +8,9 @@ use ethabi::{Function, StateMutability, Token}; use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; use sp_core::{H160, U256}; use sp_runtime::traits::{UniqueSaturatedInto, Zero}; +use tangle_primitives::services::EvmAddressMapping; +use tangle_primitives::services::EvmGasWeightMapping; +use tangle_primitives::services::EvmRunner; use tangle_primitives::services::{ Asset, BlueprintServiceManager, Field, MasterBlueprintServiceManagerRevision, OperatorPreferences, Service, ServiceBlueprint, diff --git a/pallets/services/src/impls.rs b/pallets/services/src/impls.rs index 69297d07..e5e477a7 100644 --- a/pallets/services/src/impls.rs +++ b/pallets/services/src/impls.rs @@ -7,31 +7,6 @@ use sp_std::vec; use std::vec::Vec; use tangle_primitives::{services::Constraints, traits::ServiceManager, BlueprintId}; -impl traits::EvmRunner for () { - type Error = crate::Error; - - fn call( - _source: sp_core::H160, - _target: sp_core::H160, - _input: Vec, - _value: sp_core::U256, - _gas_limit: u64, - _is_transactional: bool, - _validate: bool, - ) -> Result> { - Ok(fp_evm::CallInfo { - exit_reason: fp_evm::ExitReason::Succeed(fp_evm::ExitSucceed::Stopped), - value: Default::default(), - used_gas: fp_evm::UsedGas { - standard: Default::default(), - effective: Default::default(), - }, - weight_info: Default::default(), - logs: Default::default(), - }) - } -} - impl Constraints for types::ConstraintsOf { type MaxFields = T::MaxFields; @@ -74,15 +49,6 @@ impl Constraints for types::ConstraintsOf { type MaxAssetsPerService = T::MaxAssetsPerService; } -impl traits::EvmGasWeightMapping for () { - fn gas_to_weight(_gas: u64, _without_base_weight: bool) -> Weight { - Default::default() - } - fn weight_to_gas(_weight: Weight) -> u64 { - Default::default() - } -} - impl ServiceManager> for crate::Pallet { fn get_active_services_count(operator: &T::AccountId) -> usize { OperatorsProfile::::get(operator) diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index 57cdc44d..ec80c752 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -31,7 +31,6 @@ use sp_runtime::{traits::Get, DispatchResult}; mod functions; mod impls; mod rpc; -pub mod traits; pub mod types; #[cfg(test)] @@ -48,7 +47,6 @@ pub mod weights; pub use module::*; use tangle_primitives::BlueprintId; -pub use traits::*; pub use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] @@ -95,14 +93,14 @@ pub mod module { /// A type that implements the `EvmRunner` trait for the execution of EVM /// transactions. - type EvmRunner: traits::EvmRunner; + type EvmRunner: tangle_primitives::services::EvmRunner; /// A type that implements the `EvmGasWeightMapping` trait for the conversion of EVM gas to /// Substrate weight and vice versa. - type EvmGasWeightMapping: traits::EvmGasWeightMapping; + type EvmGasWeightMapping: tangle_primitives::services::EvmGasWeightMapping; /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address - type EvmAddressMapping: traits::EvmAddressMapping; + type EvmAddressMapping: tangle_primitives::services::EvmAddressMapping; /// The asset ID type. type AssetId: AtLeast32BitUnsigned diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 6c3650bd..c044883a 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -38,17 +38,19 @@ mod mock; #[cfg(test)] mod tests; -use fp_evm::PrecompileHandle; +use fp_evm::{PrecompileFailure, PrecompileHandle}; use frame_support::{ dispatch::{GetDispatchInfo, PostDispatchInfo}, traits::Currency, }; use pallet_evm::AddressMapping; use pallet_multi_asset_delegation::types::DelegatorBlueprintSelection; +use parity_scale_codec::Decode; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; use sp_runtime::traits::{Dispatchable, TryConvert}; use sp_std::{marker::PhantomData, vec::Vec}; +use tangle_primitives::services::Asset; use tangle_primitives::types::WrappedAccountId32; type BalanceOf = @@ -117,9 +119,21 @@ where ::RuntimeOrigin: From>, Runtime::RuntimeCall: From>, BalanceOf: TryFrom + Into + solidity::Codec, - AssetIdOf: TryFrom + Into, + AssetIdOf: TryFrom + Into + From, Runtime::AccountId: From, { + // Errors for the `MultiAssetDelegation` precompile. + + /// Found an invalid amount / value. + const INVALID_AMOUNT: [u8; 32] = keccak256!("InvalidAmount()"); + /// Value must be zero for ERC20 payment asset. + const VALUE_NOT_ZERO_FOR_ERC20: [u8; 32] = keccak256!("ValueMustBeZeroForERC20()"); + /// Value must be zero for custom payment asset. + const VALUE_NOT_ZERO_FOR_CUSTOM_ASSET: [u8; 32] = keccak256!("ValueMustBeZeroForCustomAsset()"); + /// Payment asset should be either custom or ERC20. + const PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20: [u8; 32] = + keccak256!("PaymentAssetShouldBeCustomOrERC20()"); + #[precompile::public("joinOperators(uint256)")] fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -243,10 +257,21 @@ where } #[precompile::public("deposit(uint256,uint256)")] - fn deposit(handle: &mut impl PrecompileHandle, asset_id: U256, amount: U256) -> EvmResult { + fn deposit( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; + + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; // Get origin account. let msg_sender = handle.context().caller; @@ -254,7 +279,11 @@ where // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::deposit { asset_id, amount }; + let call = pallet_multi_asset_delegation::Call::::deposit { + asset_id: deposit_asset, + amount, + evm_address: Some(msg_sender), + }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -265,11 +294,10 @@ where fn schedule_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, + token_address: Address, amount: U256, ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; // Get origin account. let msg_sender = handle.context().caller; @@ -277,8 +305,19 @@ where // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = - pallet_multi_asset_delegation::Call::::schedule_withdraw { asset_id, amount }; + + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; + + let call = pallet_multi_asset_delegation::Call::::schedule_withdraw { + asset_id: deposit_asset, + amount, + }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -289,7 +328,9 @@ where fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_withdraw {}; + let call = pallet_multi_asset_delegation::Call::::execute_withdraw { + evm_address: Some(handle.context().caller), + }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -300,20 +341,29 @@ where fn cancel_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, + token_address: Address, amount: U256, ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; // Get origin account. let msg_sender = handle.context().caller; let origin = Runtime::AddressMapping::into_account_id(msg_sender); + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; + // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = - pallet_multi_asset_delegation::Call::::cancel_withdraw { asset_id, amount }; + let call = pallet_multi_asset_delegation::Call::::cancel_withdraw { + asset_id: deposit_asset, + amount, + }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -325,12 +375,11 @@ where handle: &mut impl PrecompileHandle, operator: H256, asset_id: U256, + token_address: Address, amount: U256, blueprint_selection: Vec, ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; // Get origin account. let msg_sender = handle.context().caller; @@ -343,11 +392,19 @@ where let blueprint_selection = DelegatorBlueprintSelection::try_from(blueprint_selection) .map_err(|_| revert("error converting blueprint selection"))?; + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; + // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::delegate { operator, - asset_id, + asset_id: deposit_asset, amount, blueprint_selection, }; @@ -362,11 +419,10 @@ where handle: &mut impl PrecompileHandle, operator: H256, asset_id: U256, + token_address: Address, amount: U256, ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; // Get origin account. let msg_sender = handle.context().caller; @@ -375,11 +431,19 @@ where // Parse operator address let operator = Self::convert_to_account_id(operator)?; + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; + // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { operator, - asset_id, + asset_id: deposit_asset, amount, }; @@ -404,11 +468,10 @@ where handle: &mut impl PrecompileHandle, operator: H256, asset_id: U256, + token_address: Address, amount: U256, ) -> EvmResult { let amount = Self::u256_to_amount(amount)?; - let asset_id = AssetIdOf::::try_from(asset_id) - .map_err(|_| revert("error converting to asset id"))?; // Get origin account. let msg_sender = handle.context().caller; @@ -417,11 +480,19 @@ where // Parse operator address let operator = Self::convert_to_account_id(operator)?; + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), + (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, + }; + // Build call with origin. handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; let call = pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { operator, - asset_id, + asset_id: deposit_asset, amount, }; @@ -430,3 +501,11 @@ where Ok(()) } } + +/// Revert with Custom Error Selector +fn revert_custom_error(err: [u8; 32]) -> PrecompileFailure { + let selector = &err[0..4]; + let mut output = sp_std::vec![0u8; 32]; + output[0..4].copy_from_slice(selector); + PrecompileFailure::Revert { exit_status: fp_evm::ExitRevert::Reverted, output } +} diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 69f674da..83e61ae7 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -1149,6 +1149,15 @@ pub trait EvmGasWeightMapping { fn weight_to_gas(weight: Weight) -> u64; } +impl EvmGasWeightMapping for () { + fn gas_to_weight(_gas: u64, _without_base_weight: bool) -> Weight { + Default::default() + } + fn weight_to_gas(_weight: Weight) -> u64 { + Default::default() + } +} + /// Trait to be implemented for evm address mapping. pub trait EvmAddressMapping { /// Convert an address to an account id. From 4a2a2a843cc8e822151a8bce2c5c3415bed098c3 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:09:44 +0530 Subject: [PATCH 14/63] runtimes building --- client/rpc/debug/src/lib.rs | 4 +--- .../src/functions/delegate.rs | 18 ++++++++++-------- .../src/functions/deposit.rs | 9 ++++----- .../src/functions/evm.rs | 13 +++++++------ .../src/functions/operator.rs | 16 +++++++--------- .../src/functions/rewards.rs | 3 +-- pallets/multi-asset-delegation/src/lib.rs | 18 ++++++++---------- .../src/tests/operator.rs | 6 ++++-- pallets/multi-asset-delegation/src/traits.rs | 9 ++++----- .../src/types/delegator.rs | 3 +-- pallets/services/src/functions.rs | 7 ++----- pallets/services/src/lib.rs | 6 ++++-- precompiles/multi-asset-delegation/src/lib.rs | 10 ++++++---- primitives/src/services/mod.rs | 6 ++---- .../src/traits/multi_asset_delegation.rs | 3 +-- primitives/src/traits/services.rs | 9 --------- runtime/mainnet/src/lib.rs | 3 +++ runtime/mainnet/src/tangle_services.rs | 10 +++++----- runtime/testnet/src/lib.rs | 3 +++ runtime/testnet/src/tangle_services.rs | 10 +++++----- 20 files changed, 78 insertions(+), 88 deletions(-) diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index 09b2b932..aa85097d 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -751,9 +751,7 @@ where }; if trace_api_version <= 5 { - return Err(internal_err( - "debug_traceCall not supported with old runtimes".to_string(), - )); + return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); } let TraceCallParams { diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 39322fc0..03c95e66 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,15 +15,17 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::fungibles::Mutate; -use frame_support::traits::tokens::Preservation; -use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Get}; -use sp_runtime::traits::{CheckedSub, Zero}; -use sp_runtime::DispatchError; -use sp_runtime::Percent; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{fungibles::Mutate, tokens::Preservation, Get}, +}; +use sp_runtime::{ + traits::{CheckedSub, Zero}, + DispatchError, Percent, +}; use sp_std::vec::Vec; -use tangle_primitives::services::Asset; -use tangle_primitives::BlueprintId; +use tangle_primitives::{services::Asset, BlueprintId}; impl Pallet { /// Processes the delegation of an amount of an asset to an operator. diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 5b8eb6d7..7711ecf7 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -15,15 +15,14 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::fungibles::Mutate; -use frame_support::{ensure, pallet_prelude::DispatchResult}; use frame_support::{ + ensure, + pallet_prelude::DispatchResult, sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, - traits::{tokens::Preservation, Get}, + traits::{fungibles::Mutate, tokens::Preservation, Get}, }; use sp_core::H160; -use tangle_primitives::services::Asset; -use tangle_primitives::EvmAddressMapping; +use tangle_primitives::services::{Asset, EvmAddressMapping}; impl Pallet { /// Returns the account ID of the pallet. diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index cd2e79b5..e42d65be 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -1,15 +1,16 @@ use super::*; use crate::types::BalanceOf; use ethabi::{Function, StateMutability, Token}; -use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; -use frame_support::pallet_prelude::Pays; -use frame_support::pallet_prelude::Weight; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + pallet_prelude::{Pays, Weight}, +}; use parity_scale_codec::Encode; +use scale_info::prelude::string::String; use sp_core::{H160, U256}; use sp_runtime::traits::UniqueSaturatedInto; -use tangle_primitives::services::EvmGasWeightMapping; -use tangle_primitives::services::EvmRunner; -use tangle_primitives::EvmAddressMapping; +use sp_std::{vec, vec::Vec}; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; impl Pallet { /// Moves a `value` amount of tokens from the caller's account to `to`. diff --git a/pallets/multi-asset-delegation/src/functions/operator.rs b/pallets/multi-asset-delegation/src/functions/operator.rs index e35a5fa2..9e6e2b39 100644 --- a/pallets/multi-asset-delegation/src/functions/operator.rs +++ b/pallets/multi-asset-delegation/src/functions/operator.rs @@ -17,19 +17,17 @@ /// Functions for the pallet. use super::*; use crate::{types::*, Pallet}; -use frame_support::traits::Currency; -use frame_support::traits::ExistenceRequirement; -use frame_support::BoundedVec; use frame_support::{ ensure, pallet_prelude::DispatchResult, - traits::{Get, ReservableCurrency}, + traits::{Currency, ExistenceRequirement, Get, ReservableCurrency}, + BoundedVec, }; -use sp_runtime::traits::{CheckedAdd, CheckedSub}; -use sp_runtime::DispatchError; -use sp_runtime::Percent; -use tangle_primitives::BlueprintId; -use tangle_primitives::ServiceManager; +use sp_runtime::{ + traits::{CheckedAdd, CheckedSub}, + DispatchError, Percent, +}; +use tangle_primitives::{BlueprintId, ServiceManager}; impl Pallet { /// Handles the deposit of stake amount and creation of an operator. diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs index 06cf9ef5..deff06ab 100644 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ b/pallets/multi-asset-delegation/src/functions/rewards.rs @@ -21,8 +21,7 @@ use crate::{ use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; use sp_runtime::{traits::Zero, DispatchError, Saturating}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; -use tangle_primitives::services::Asset; -use tangle_primitives::RoundIndex; +use tangle_primitives::{services::Asset, RoundIndex}; impl Pallet { #[allow(clippy::type_complexity)] diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 57a77ec3..491e6376 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -76,23 +76,21 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { - use crate::types::*; - use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction}; - use frame_support::traits::fungibles::Inspect; + use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; use frame_support::{ pallet_prelude::*, - traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, + traits::{ + fungibles::Inspect, tokens::fungibles, Currency, Get, LockableCurrency, + ReservableCurrency, + }, PalletId, }; use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_core::H160; use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; - use sp_std::vec::Vec; - use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*}; - use tangle_primitives::services::Asset; - use tangle_primitives::BlueprintId; - use tangle_primitives::{traits::ServiceManager, RoundIndex}; + use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; + use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex}; /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] @@ -200,7 +198,7 @@ pub mod pallet { type EvmGasWeightMapping: tangle_primitives::services::EvmGasWeightMapping; /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address - type EvmAddressMapping: tangle_primitives::traits::EvmAddressMapping; + type EvmAddressMapping: tangle_primitives::services::EvmAddressMapping; /// A type representing the weights required by the dispatchables of this pallet. type WeightInfo: crate::weights::WeightInfo; diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 27a855d3..ca0be840 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -14,8 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::types::DelegatorBlueprintSelection::Fixed; -use crate::{types::OperatorStatus, CurrentRound, Error}; +use crate::{ + types::{DelegatorBlueprintSelection::Fixed, OperatorStatus}, + CurrentRound, Error, +}; use frame_support::{assert_noop, assert_ok}; use sp_runtime::Percent; diff --git a/pallets/multi-asset-delegation/src/traits.rs b/pallets/multi-asset-delegation/src/traits.rs index ff65ded0..653ad9ef 100644 --- a/pallets/multi-asset-delegation/src/traits.rs +++ b/pallets/multi-asset-delegation/src/traits.rs @@ -15,12 +15,11 @@ // along with Tangle. If not, see . use super::*; use crate::types::{BalanceOf, OperatorStatus}; -use sp_runtime::traits::Zero; -use sp_runtime::Percent; +use sp_runtime::{traits::Zero, Percent}; use sp_std::prelude::*; -use tangle_primitives::services::Asset; -use tangle_primitives::BlueprintId; -use tangle_primitives::{traits::MultiAssetDelegationInfo, RoundIndex}; +use tangle_primitives::{ + services::Asset, traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex, +}; impl MultiAssetDelegationInfo> for crate::Pallet { type AssetId = T::AssetId; diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 0dbfc1b0..4885c8c3 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -16,8 +16,7 @@ use super::*; use frame_support::{pallet_prelude::Get, BoundedVec}; -use tangle_primitives::services::Asset; -use tangle_primitives::BlueprintId; +use tangle_primitives::{services::Asset, BlueprintId}; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index 4cfdfffb..5080ebe2 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -8,12 +8,9 @@ use ethabi::{Function, StateMutability, Token}; use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; use sp_core::{H160, U256}; use sp_runtime::traits::{UniqueSaturatedInto, Zero}; -use tangle_primitives::services::EvmAddressMapping; -use tangle_primitives::services::EvmGasWeightMapping; -use tangle_primitives::services::EvmRunner; use tangle_primitives::services::{ - Asset, BlueprintServiceManager, Field, MasterBlueprintServiceManagerRevision, - OperatorPreferences, Service, ServiceBlueprint, + Asset, BlueprintServiceManager, EvmAddressMapping, EvmGasWeightMapping, EvmRunner, Field, + MasterBlueprintServiceManagerRevision, OperatorPreferences, Service, ServiceBlueprint, }; use super::*; diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index 7939f990..7a8d82c3 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -69,8 +69,10 @@ pub mod module { Percent, }; use sp_std::vec::Vec; - use tangle_primitives::services::MasterBlueprintServiceManagerRevision; - use tangle_primitives::{services::*, Account, MultiAssetDelegationInfo}; + use tangle_primitives::{ + services::{MasterBlueprintServiceManagerRevision, *}, + Account, MultiAssetDelegationInfo, + }; use types::*; #[pallet::config] diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index c044883a..81bfb839 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -50,8 +50,7 @@ use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; use sp_runtime::traits::{Dispatchable, TryConvert}; use sp_std::{marker::PhantomData, vec::Vec}; -use tangle_primitives::services::Asset; -use tangle_primitives::types::WrappedAccountId32; +use tangle_primitives::{services::Asset, types::WrappedAccountId32}; type BalanceOf = <::Currency as Currency< @@ -389,8 +388,11 @@ where let operator = Self::convert_to_account_id(operator)?; // Parse blueprint selection - let blueprint_selection = DelegatorBlueprintSelection::try_from(blueprint_selection) - .map_err(|_| revert("error converting blueprint selection"))?; + let bounded_blueprint_selection: frame_support::BoundedVec<_, _> = + frame_support::BoundedVec::try_from(blueprint_selection) + .map_err(|_| revert("error converting blueprint selection"))?; + + let blueprint_selection = DelegatorBlueprintSelection::Fixed(bounded_blueprint_selection); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 97682a6f..ee4138bf 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -21,10 +21,8 @@ use fp_evm::CallInfo; use frame_support::pallet_prelude::*; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -use sp_core::{H160, U256}; -use sp_core::{ecdsa, ByteArray, RuntimeDebug}; +use sp_core::{ecdsa, ByteArray, RuntimeDebug, H160, U256}; use sp_runtime::Percent; -use sp_std::vec::Vec; #[cfg(not(feature = "std"))] use alloc::{string::String, vec, vec::Vec}; @@ -670,7 +668,7 @@ pub enum Asset { Erc20(sp_core::H160), } -impl Default for Asset { +impl Default for Asset { fn default() -> Self { Asset::Custom(sp_runtime::traits::Zero::zero()) } diff --git a/primitives/src/traits/multi_asset_delegation.rs b/primitives/src/traits/multi_asset_delegation.rs index 7afc1835..985c8ba2 100644 --- a/primitives/src/traits/multi_asset_delegation.rs +++ b/primitives/src/traits/multi_asset_delegation.rs @@ -1,5 +1,4 @@ -use crate::services::Asset; -use crate::types::RoundIndex; +use crate::{services::Asset, types::RoundIndex}; use sp_std::prelude::*; /// A trait to provide information about multi-asset delegation. diff --git a/primitives/src/traits/services.rs b/primitives/src/traits/services.rs index 4d1d8ef1..087586b7 100644 --- a/primitives/src/traits/services.rs +++ b/primitives/src/traits/services.rs @@ -60,12 +60,3 @@ pub trait ServiceManager { /// `true` if the operator can exit, otherwise `false`. fn can_exit(operator: &AccountId) -> bool; } - -/// Trait to be implemented for evm address mapping. -pub trait EvmAddressMapping { - /// Convert an address to an account id. - fn into_account_id(address: H160) -> A; - - /// Convert an account id to an address. - fn into_address(account_id: A) -> H160; -} diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index bc7bc542..5db6de9b 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -1272,6 +1272,9 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MaxWithdrawRequests = MaxWithdrawRequests; type MaxUnstakeRequests = MaxUnstakeRequests; type MaxDelegations = MaxDelegations; + type EvmRunner = crate::tangle_services::PalletEvmRunner; + type EvmGasWeightMapping = crate::tangle_services::PalletEVMGasWeightMapping; + type EvmAddressMapping = crate::tangle_services::PalletEVMAddressMapping; type WeightInfo = (); } diff --git a/runtime/mainnet/src/tangle_services.rs b/runtime/mainnet/src/tangle_services.rs index 1cf4c43a..a6cbcf26 100644 --- a/runtime/mainnet/src/tangle_services.rs +++ b/runtime/mainnet/src/tangle_services.rs @@ -9,7 +9,7 @@ parameter_types! { pub struct PalletEvmRunner; -impl pallet_services::EvmRunner for PalletEvmRunner { +impl tangle_primitives::services::EvmRunner for PalletEvmRunner { type Error = pallet_evm::Error; fn call( @@ -20,7 +20,7 @@ impl pallet_services::EvmRunner for PalletEvmRunner { gas_limit: u64, is_transactional: bool, validate: bool, - ) -> Result> { + ) -> Result> { let max_fee_per_gas = DefaultBaseFeePerGas::get(); let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(3) / U256::from(2)); @@ -44,13 +44,13 @@ impl pallet_services::EvmRunner for PalletEvmRunner { proof_size_base_cost, ::config(), ) - .map_err(|o| pallet_services::RunnerError { error: o.error, weight: o.weight }) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) } } pub struct PalletEVMGasWeightMapping; -impl pallet_services::EvmGasWeightMapping for PalletEVMGasWeightMapping { +impl tangle_primitives::services::EvmGasWeightMapping for PalletEVMGasWeightMapping { fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) } @@ -62,7 +62,7 @@ impl pallet_services::EvmGasWeightMapping for PalletEVMGasWeightMapping { pub struct PalletEVMAddressMapping; -impl pallet_services::EvmAddressMapping for PalletEVMAddressMapping { +impl tangle_primitives::services::EvmAddressMapping for PalletEVMAddressMapping { fn into_account_id(address: H160) -> AccountId { use pallet_evm::AddressMapping; ::AddressMapping::into_account_id(address) diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 5ce483da..7fb9e15b 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -1492,6 +1492,9 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MaxWithdrawRequests = MaxWithdrawRequests; type MaxUnstakeRequests = MaxUnstakeRequests; type MaxDelegations = MaxDelegations; + type EvmRunner = crate::tangle_services::PalletEvmRunner; + type EvmGasWeightMapping = crate::tangle_services::PalletEVMGasWeightMapping; + type EvmAddressMapping = crate::tangle_services::PalletEVMAddressMapping; type WeightInfo = (); } diff --git a/runtime/testnet/src/tangle_services.rs b/runtime/testnet/src/tangle_services.rs index 0cd11350..a2beafd8 100644 --- a/runtime/testnet/src/tangle_services.rs +++ b/runtime/testnet/src/tangle_services.rs @@ -6,7 +6,7 @@ parameter_types! { pub struct PalletEvmRunner; -impl pallet_services::EvmRunner for PalletEvmRunner { +impl tangle_primitives::services::EvmRunner for PalletEvmRunner { type Error = pallet_evm::Error; fn call( @@ -17,7 +17,7 @@ impl pallet_services::EvmRunner for PalletEvmRunner { gas_limit: u64, is_transactional: bool, validate: bool, - ) -> Result> { + ) -> Result> { let max_fee_per_gas = DefaultBaseFeePerGas::get(); let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(3) / U256::from(2)); @@ -41,13 +41,13 @@ impl pallet_services::EvmRunner for PalletEvmRunner { proof_size_base_cost, ::config(), ) - .map_err(|o| pallet_services::RunnerError { error: o.error, weight: o.weight }) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) } } pub struct PalletEVMGasWeightMapping; -impl pallet_services::EvmGasWeightMapping for PalletEVMGasWeightMapping { +impl tangle_primitives::services::EvmGasWeightMapping for PalletEVMGasWeightMapping { fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) } @@ -59,7 +59,7 @@ impl pallet_services::EvmGasWeightMapping for PalletEVMGasWeightMapping { pub struct PalletEVMAddressMapping; -impl pallet_services::EvmAddressMapping for PalletEVMAddressMapping { +impl tangle_primitives::services::EvmAddressMapping for PalletEVMAddressMapping { fn into_account_id(address: H160) -> AccountId { use pallet_evm::AddressMapping; ::AddressMapping::into_account_id(address) From 35f93942173b9915249cefee585b484fc3a9810f Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:35:45 +0530 Subject: [PATCH 15/63] update mocks --- Cargo.lock | 34 + client/rpc/debug/src/lib.rs | 4 +- pallets/multi-asset-delegation/Cargo.toml | 66 ++ pallets/multi-asset-delegation/src/lib.rs | 3 + pallets/multi-asset-delegation/src/mock.rs | 619 +++++++++++++++--- .../multi-asset-delegation/src/mock_evm.rs | 344 ++++++++++ .../src/tests/delegate.rs | 54 +- .../src/tests/deposit.rs | 24 +- .../src/tests/operator.rs | 48 +- .../src/tests/session_manager.rs | 8 +- precompiles/multi-asset-delegation/src/lib.rs | 12 +- precompiles/services/src/lib.rs | 6 +- 12 files changed, 1071 insertions(+), 151 deletions(-) create mode 100644 pallets/multi-asset-delegation/src/mock_evm.rs diff --git a/Cargo.lock b/Cargo.lock index 6fafd877..6e4a2151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8283,21 +8283,55 @@ name = "pallet-multi-asset-delegation" version = "1.2.3" dependencies = [ "ethabi", + "ethereum", + "ethers", + "fp-account", + "fp-consensus", + "fp-dynamic-fee", + "fp-ethereum", "fp-evm", + "fp-rpc", + "fp-self-contained", + "fp-storage", "frame-benchmarking", + "frame-election-provider-support", "frame-support", "frame-system", "hex", + "hex-literal 0.4.1", "itertools 0.13.0", + "libsecp256k1", "log", + "num_enum", "pallet-assets", "pallet-balances", + "pallet-base-fee", + "pallet-dynamic-fee", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-chain-id", + "pallet-evm-precompile-blake2", + "pallet-evm-precompile-bn128", + "pallet-evm-precompile-curve25519", + "pallet-evm-precompile-ed25519", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", + "pallet-session", + "pallet-staking", + "pallet-timestamp", "parity-scale-codec", + "precompile-utils", "scale-info", "serde", + "serde_json", + "smallvec", "sp-core", "sp-io", + "sp-keyring", + "sp-keystore", "sp-runtime", + "sp-staking", "sp-std", "tangle-primitives", ] diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index aa85097d..09b2b932 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -751,7 +751,9 @@ where }; if trace_api_version <= 5 { - return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); + return Err(internal_err( + "debug_traceCall not supported with old runtimes".to_string(), + )); } let TraceCallParams { diff --git a/pallets/multi-asset-delegation/Cargo.toml b/pallets/multi-asset-delegation/Cargo.toml index 4c1cb335..24a6f9f7 100644 --- a/pallets/multi-asset-delegation/Cargo.toml +++ b/pallets/multi-asset-delegation/Cargo.toml @@ -27,6 +27,52 @@ itertools = { workspace = true, features = ["use_alloc"] } serde = { workspace = true, features = ["derive"], optional = true } hex = { workspace = true, features = ["alloc"] } +[dev-dependencies] +ethereum = { workspace = true, features = ["with-codec"] } +ethers = "2.0" +num_enum = { workspace = true } +hex-literal = { workspace = true } +libsecp256k1 = { workspace = true } +pallet-assets = { workspace = true } +pallet-balances = { workspace = true } +pallet-timestamp = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +smallvec = { workspace = true } +sp-io = { workspace = true } +sp-keystore = { workspace = true } + +# Frontier Primitive +fp-account = { workspace = true } +fp-consensus = { workspace = true } +fp-dynamic-fee = { workspace = true } +fp-ethereum = { workspace = true } +fp-rpc = { workspace = true } +fp-self-contained = { workspace = true } +fp-storage = { workspace = true } + +# Frontier FRAME +pallet-base-fee = { workspace = true } +pallet-dynamic-fee = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } + +pallet-evm-precompile-blake2 = { workspace = true } +pallet-evm-precompile-bn128 = { workspace = true } +pallet-evm-precompile-curve25519 = { workspace = true } +pallet-evm-precompile-ed25519 = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-sha3fips = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } + +precompile-utils = { workspace = true } +sp-keyring ={ workspace = true} +pallet-session = { workspace = true } +pallet-staking = { workspace = true } +sp-staking = { workspace = true } +frame-election-provider-support = { workspace = true } + [features] default = ["std"] std = [ @@ -45,6 +91,26 @@ std = [ "fp-evm/std", "serde/std", "hex/std", + + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-precompile-blake2/std", + "pallet-evm-precompile-bn128/std", + "pallet-evm-precompile-curve25519/std", + "pallet-evm-precompile-ed25519/std", + "precompile-utils/std", + "pallet-staking/std", + "fp-account/std", + "fp-consensus/std", + "fp-dynamic-fee/std", + "fp-ethereum/std", + "fp-evm/std", + "fp-rpc/std", + "fp-self-contained/std", + "fp-storage/std", + "ethabi/std", + "sp-keyring/std", ] try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 491e6376..33378eb2 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -60,6 +60,9 @@ pub use pallet::*; #[cfg(test)] mod mock; +#[cfg(test)] +mod mock_evm; + #[cfg(test)] mod tests; diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 3efa2be6..74231224 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -13,75 +13,93 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate as pallet_multi_asset_delegation; +#![allow(clippy::all)] +use super::*; +use crate::{self as pallet_multi_asset_delegation}; +use ethabi::Uint; +use frame_election_provider_support::{ + bounds::{ElectionBounds, ElectionBoundsBuilder}, + onchain, SequentialPhragmen, +}; +use frame_support::pallet_prelude::Hooks; +use frame_support::pallet_prelude::Weight; +use frame_support::PalletId; use frame_support::{ - derive_impl, parameter_types, - traits::{AsEnsureOriginWithArg, ConstU16, ConstU32, ConstU64}, - PalletId, + construct_runtime, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, }; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use frame_system::EnsureRoot; +use mock_evm::MockedEvmRunner; +use pallet_evm::GasWeightMapping; +use pallet_session::historical as pallet_session_historical; +use parity_scale_codec::Decode; +use parity_scale_codec::Encode; +use parity_scale_codec::MaxEncodedLen; use scale_info::TypeInfo; -use sp_core::H256; +use serde_json::json; +use sp_core::{sr25519, H160}; +use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; +use sp_runtime::traits::ConstU64; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - BuildStorage, + testing::UintAuthorityId, + traits::{ConvertInto, IdentityLookup}, + AccountId32, BuildStorage, Perbill, }; +use tangle_primitives::services::EvmAddressMapping; +use tangle_primitives::services::EvmGasWeightMapping; +use tangle_primitives::services::EvmRunner; +use tangle_primitives::services::RunnerError; -type Block = frame_system::mocking::MockBlock; -pub type Balance = u64; -pub type AssetId = u32; +use core::ops::Mul; +use std::{collections::BTreeMap, sync::Arc}; -pub const ALICE: u64 = 1; -pub const BOB: u64 = 2; -pub const CHARLIE: u64 = 3; -pub const DAVE: u64 = 4; -pub const EVE: u64 = 5; +pub type AccountId = AccountId32; +pub type Balance = u128; +type Nonce = u32; +pub type AssetId = u128; +// AssetIds for tests pub const VDOT: AssetId = 1; -// Configure a mock runtime to test the pallet. -frame_support::construct_runtime!( - pub enum Test - { - System: frame_system, - Balances: pallet_balances, - Assets: pallet_assets, - MultiAssetDelegation: pallet_multi_asset_delegation, - } -); +// AccountIds for tests +pub const ALICE: u8 = 1; +pub const BOB: u8 = 2; +pub const CHARLIE: u8 = 3; +pub const DAVE: u8 = 4; +pub const EVE: u8 = 5; -#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] -impl frame_system::Config for Test { +#[frame_support::derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; + type Nonce = Nonce; type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; + type Hash = sp_core::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; type Lookup = IdentityLookup; type Block = Block; type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; + type BlockHashCount = (); type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; + type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } -impl pallet_balances::Config for Test { +impl pallet_balances::Config for Runtime { type Balance = Balance; type DustRemoval = (); type RuntimeEvent = RuntimeEvent; - type ExistentialDeposit = ConstU64<1>; + type ExistentialDeposit = ConstU128<1>; type AccountStore = System; type MaxLocks = (); type MaxReserves = ConstU32<50>; @@ -93,25 +111,193 @@ impl pallet_balances::Config for Test { type MaxFreezes = (); } +parameter_types! { + pub ElectionBoundsOnChain: ElectionBounds = ElectionBoundsBuilder::default() + .voters_count(5_000.into()).targets_count(1_250.into()).build(); + pub ElectionBoundsMultiPhase: ElectionBounds = ElectionBoundsBuilder::default() + .voters_count(10_000.into()).targets_count(1_500.into()).build(); +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = AccountId; + type FullIdentificationOf = ConvertInto; +} + +sp_runtime::impl_opaque_keys! { + pub struct MockSessionKeys { + pub other: MockSessionHandler, + } +} + +pub struct MockSessionHandler; +impl OneSessionHandler for MockSessionHandler { + type Key = UintAuthorityId; + + fn on_genesis_session<'a, I: 'a>(_: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_: bool, _: I, _: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_disabled(_validator_index: u32) {} +} + +impl sp_runtime::BoundToRuntimeAppPublic for MockSessionHandler { + type Public = UintAuthorityId; +} + +pub struct MockSessionManager; + +impl pallet_session::SessionManager for MockSessionManager { + fn end_session(_: sp_staking::SessionIndex) {} + fn start_session(_: sp_staking::SessionIndex) {} + fn new_session(idx: sp_staking::SessionIndex) -> Option> { + if idx == 0 || idx == 1 || idx == 2 { + Some(vec![mock_pub_key(1), mock_pub_key(2), mock_pub_key(3), mock_pub_key(4)]) + } else { + None + } + } +} + +parameter_types! { + pub const Period: u64 = 1; + pub const Offset: u64 = 0; +} + +impl pallet_session::Config for Runtime { + type SessionManager = MockSessionManager; + type Keys = MockSessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionHandler = (MockSessionHandler,); + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type WeightInfo = (); +} + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); + type MaxWinners = ConstU32<100>; + type Bounds = ElectionBoundsOnChain; +} + +/// Upper limit on the number of NPOS nominations. +const MAX_QUOTA_NOMINATIONS: u32 = 16; + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = ::Balance; + type UnixTime = pallet_timestamp::Pallet; + type CurrencyToVote = (); + type RewardRemainder = (); + type RuntimeEvent = RuntimeEvent; + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type AdminOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = (); + type EraPayout = (); + type NextNewSession = Session; + type MaxExposurePageSize = ConstU32<64>; + type MaxControllersInDeprecationBatch = ConstU32<100>; + type ElectionProvider = onchain::OnChainExecution; + type GenesisElectionProvider = Self::ElectionProvider; + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type TargetList = pallet_staking::UseValidatorsMap; + type MaxUnlockingChunks = ConstU32<32>; + type HistoryDepth = ConstU32<84>; + type EventListeners = (); + type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; + type NominationsQuota = pallet_staking::FixedNominationsQuota; + type WeightInfo = (); + type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; +} + +parameter_types! { + pub const ServicesEVMAddress: H160 = H160([0x11; 20]); +} + +pub struct PalletEVMGasWeightMapping; + +impl EvmGasWeightMapping for PalletEVMGasWeightMapping { + fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { + pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) + } + + fn weight_to_gas(weight: Weight) -> u64 { + pallet_evm::FixedGasWeightMapping::::weight_to_gas(weight) + } +} + +pub struct PalletEVMAddressMapping; + +impl EvmAddressMapping for PalletEVMAddressMapping { + fn into_account_id(address: H160) -> AccountId { + use pallet_evm::AddressMapping; + ::AddressMapping::into_account_id(address) + } + + fn into_address(account_id: AccountId) -> H160 { + H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) + } +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = u128; + type AssetId = AssetId; + type AssetIdParameter = AssetId; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU128<1>; + type AssetAccountDeposit = ConstU128<10>; + type MetadataDepositBase = ConstU128<1>; + type MetadataDepositPerByte = ConstU128<1>; + type ApprovalDeposit = ConstU128<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; +} + pub struct MockServiceManager; -impl tangle_primitives::ServiceManager for MockServiceManager { - fn get_active_blueprints_count(_account: &u64) -> usize { +impl tangle_primitives::ServiceManager for MockServiceManager { + fn get_active_blueprints_count(_account: &AccountId) -> usize { // we dont care Default::default() } - fn get_active_services_count(_account: &u64) -> usize { + fn get_active_services_count(_account: &AccountId) -> usize { // we dont care Default::default() } - fn can_exit(_account: &u64) -> bool { + fn can_exit(_account: &AccountId) -> bool { // Mock logic to determine if the given account can exit true } - fn get_blueprints_by_operator(_account: &u64) -> Vec { + fn get_blueprints_by_operator(_account: &AccountId) -> Vec { todo!(); // we dont care } } @@ -122,7 +308,7 @@ parameter_types! { pub const MinOperatorBondAmount: u64 = 10_000; pub const BondDuration: u32 = 10; pub PID: PalletId = PalletId(*b"PotStake"); - pub const SlashedAmountRecipient : u64 = 0; + pub const SlashedAmountRecipient : AccountId = mock_pub_key(ALICE).into(); #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub const MaxDelegatorBlueprints : u32 = 50; #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] @@ -135,7 +321,7 @@ parameter_types! { pub const MaxDelegations: u32 = 50; } -impl pallet_multi_asset_delegation::Config for Test { +impl pallet_multi_asset_delegation::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type MinOperatorBondAmount = MinOperatorBondAmount; @@ -145,11 +331,11 @@ impl pallet_multi_asset_delegation::Config for Test { type OperatorBondLessDelay = ConstU32<1>; type LeaveDelegatorsDelay = ConstU32<1>; type DelegationBondLessDelay = ConstU32<5>; - type MinDelegateAmount = ConstU64<100>; + type MinDelegateAmount = ConstU128<100>; type Fungibles = Assets; type AssetId = AssetId; type VaultId = AssetId; - type ForceOrigin = frame_system::EnsureRoot; + type ForceOrigin = frame_system::EnsureRoot; type PalletId = PID; type MaxDelegatorBlueprints = MaxDelegatorBlueprints; type MaxOperatorBlueprints = MaxOperatorBlueprints; @@ -157,46 +343,323 @@ impl pallet_multi_asset_delegation::Config for Test { type MaxUnstakeRequests = MaxUnstakeRequests; type MaxDelegations = MaxDelegations; type SlashedAmountRecipient = SlashedAmountRecipient; + type EvmRunner = MockedEvmRunner; + type EvmGasWeightMapping = PalletEVMGasWeightMapping; + type EvmAddressMapping = PalletEVMAddressMapping; type WeightInfo = (); } -impl pallet_assets::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Balance = u64; - type AssetId = AssetId; - type AssetIdParameter = u32; - type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = ConstU64<1>; - type AssetAccountDeposit = ConstU64<10>; - type MetadataDepositBase = ConstU64<1>; - type MetadataDepositPerByte = ConstU64<1>; - type ApprovalDeposit = ConstU64<1>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type WeightInfo = (); - type CallbackHandle = (); - type Extra = (); - type RemoveItemsLimit = ConstU32<5>; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Assets: pallet_assets, + MultiAssetDelegation: pallet_multi_asset_delegation, + EVM: pallet_evm, + Ethereum: pallet_ethereum, + Session: pallet_session, + Staking: pallet_staking, + Historical: pallet_session_historical, + } +); + +pub struct ExtBuilder; + +impl Default for ExtBuilder { + fn default() -> Self { + ExtBuilder + } +} + +pub fn mock_pub_key(id: u8) -> AccountId { + sr25519::Public::from_raw([id; 32]).into() +} + +pub fn mock_address(id: u8) -> H160 { + H160::from_slice(&[id; 20]) +} + +pub fn account_id_to_address(account_id: AccountId) -> H160 { + H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) +} + +pub fn address_to_account_id(address: H160) -> AccountId { + use pallet_evm::AddressMapping; + ::AddressMapping::into_account_id(address) +} + +pub fn mock_authorities(vec: Vec) -> Vec { + vec.into_iter().map(|id| mock_pub_key(id)).collect() } pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![ - (ALICE, 100_000), - (BOB, 200_000), - (CHARLIE, 300_000), - (DAVE, 5_000), // Not enough to stake - (MultiAssetDelegation::pallet_account(), 100), /* give pallet some ED so it can - * receive tokens */ - (EVE, 20_000), - ], + new_test_ext_raw_authorities() +} + +pub const MBSM: H160 = H160([0x12; 20]); +pub const CGGMP21_BLUEPRINT: H160 = H160([0x21; 20]); +pub const HOOKS_TEST: H160 = H160([0x22; 20]); +pub const USDC_ERC20: H160 = H160([0x23; 20]); + +pub const TNT: AssetId = 0; +pub const USDC: AssetId = 1; +pub const WETH: AssetId = 2; +pub const WBTC: AssetId = 3; + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + let authorities = vec![mock_pub_key(1), mock_pub_key(2), mock_pub_key(3)]; + let balances: Vec<_> = authorities.iter().map(|i| (i.clone(), 20_000_u128)).collect(); + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + let mut evm_accounts = BTreeMap::new(); + + let mut create_contract = |bytecode: &str, address: H160| { + let mut raw_hex = bytecode.replace("0x", "").replace("\n", ""); + // fix odd length + if raw_hex.len() % 2 != 0 { + raw_hex = format!("0{}", raw_hex); + } + let code = hex::decode(raw_hex).unwrap(); + evm_accounts.insert( + address, + fp_evm::GenesisAccount { + code, + storage: Default::default(), + nonce: Default::default(), + balance: Default::default(), + }, + ); + }; + + for i in 1..=authorities.len() { + evm_accounts.insert( + mock_address(i as u8), + fp_evm::GenesisAccount { + code: vec![], + storage: Default::default(), + nonce: Default::default(), + balance: Uint::from(1_000).mul(Uint::from(10).pow(Uint::from(18))), + }, + ); + } + + for a in &authorities { + evm_accounts.insert( + account_id_to_address(a.clone()), + fp_evm::GenesisAccount { + code: vec![], + storage: Default::default(), + nonce: Default::default(), + balance: Uint::from(1_000).mul(Uint::from(10).pow(Uint::from(18))), + }, + ); } - .assimilate_storage(&mut t) - .unwrap(); + + let evm_config = + pallet_evm::GenesisConfig:: { accounts: evm_accounts, ..Default::default() }; + + evm_config.assimilate_storage(&mut t).unwrap(); + + let assets_config = pallet_assets::GenesisConfig:: { + assets: vec![ + (USDC, authorities[0].clone(), true, 100_000), // 1 cent. + (WETH, authorities[1].clone(), true, 100), // 100 wei. + (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. + ], + metadata: vec![ + (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), + (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), + (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), + ], + accounts: vec![ + (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), + (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), + (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), + // + (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), + (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), + (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), + // + (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), + (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), + (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), + ], + next_asset_id: Some(4), + }; + + assets_config.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); + ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); ext.execute_with(|| System::set_block_number(1)); + ext.execute_with(|| { + System::set_block_number(1); + Session::on_initialize(1); + >::on_initialize(1); + + let call = ::EvmRunner::call( + MultiAssetDelegation::pallet_evm_account(), + USDC_ERC20, + serde_json::from_value::(json!({ + "name": "initialize", + "inputs": [ + { + "name": "name_", + "type": "string", + "internalType": "string" + }, + { + "name": "symbol_", + "type": "string", + "internalType": "string" + }, + { + "name": "decimals_", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + })) + .unwrap() + .encode_input(&[ + ethabi::Token::String("USD Coin".to_string()), + ethabi::Token::String("USDC".to_string()), + ethabi::Token::Uint(6.into()), + ]) + .unwrap(), + Default::default(), + 300_000, + true, + false, + ); + + assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); + // Mint + for i in 1..=authorities.len() { + let call = ::EvmRunner::call( + MultiAssetDelegation::pallet_evm_account(), + USDC_ERC20, + serde_json::from_value::(json!({ + "name": "mint", + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + })) + .unwrap() + .encode_input(&[ + ethabi::Token::Address(mock_address(i as u8).into()), + ethabi::Token::Uint(Uint::from(100_000).mul(Uint::from(10).pow(Uint::from(6)))), + ]) + .unwrap(), + Default::default(), + 300_000, + true, + false, + ); + + assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); + } + }); + ext } + +#[macro_export] +macro_rules! evm_log { + () => { + fp_evm::Log { address: H160::zero(), topics: vec![], data: vec![] } + }; + + ($contract:expr) => { + fp_evm::Log { address: $contract, topics: vec![], data: vec![] } + }; + + ($contract:expr, $topic:expr) => { + fp_evm::Log { + address: $contract, + topics: vec![sp_core::keccak_256($topic).into()], + data: vec![], + } + }; +} + +/// Asserts that the EVM logs are as expected. +#[track_caller] +pub fn assert_evm_logs(expected: &[fp_evm::Log]) { + assert_evm_events_contains(expected.iter().cloned().collect()) +} + +/// Asserts that the EVM events are as expected. +#[track_caller] +fn assert_evm_events_contains(expected: Vec) { + let actual: Vec = System::events() + .iter() + .filter_map(|e| match e.event { + RuntimeEvent::EVM(pallet_evm::Event::Log { ref log }) => Some(log.clone()), + _ => None, + }) + .collect(); + + // Check if `expected` is a subset of `actual` + let mut any_matcher = false; + for evt in expected { + if !actual.contains(&evt) { + panic!("Events don't match\nactual: {actual:?}\nexpected: {evt:?}"); + } else { + any_matcher = true; + } + } + + // At least one event should be present + if !any_matcher { + panic!("No events found"); + } +} + +// Checks events against the latest. A contiguous set of events must be +// provided. They must include the most recent RuntimeEvent, but do not have to include +// every past RuntimeEvent. +#[track_caller] +pub fn assert_events(mut expected: Vec) { + let mut actual: Vec = System::events() + .iter() + .filter_map(|e| match e.event { + RuntimeEvent::MultiAssetDelegation(_) => Some(e.event.clone()), + _ => None, + }) + .collect(); + + expected.reverse(); + for evt in expected { + let next = actual.pop().expect("RuntimeEvent expected"); + match (&next, &evt) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); + } + }, + }; + } +} diff --git a/pallets/multi-asset-delegation/src/mock_evm.rs b/pallets/multi-asset-delegation/src/mock_evm.rs new file mode 100644 index 00000000..17ba9132 --- /dev/null +++ b/pallets/multi-asset-delegation/src/mock_evm.rs @@ -0,0 +1,344 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use crate as pallet_multi_asset_delegation; +use crate::mock::{ + AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, +}; +use fp_evm::FeeCalculator; +use frame_support::{ + parameter_types, + traits::{Currency, FindAuthor, OnUnbalanced}, + weights::Weight, + PalletId, +}; +use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; +use pallet_evm::{ + EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, OnChargeEVMTransaction, +}; +use sp_core::{keccak_256, ConstU32, H160, H256, U256}; +use sp_runtime::{ + traits::{BlakeTwo256, DispatchInfoOf, Dispatchable}, + transaction_validity::{TransactionValidity, TransactionValidityError}, + ConsensusEngineId, +}; +use tangle_primitives::services::EvmRunner; +use tangle_primitives::services::RunnerError; + +use pallet_evm_precompile_blake2::Blake2F; +use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +use precompile_utils::precompile_set::{ + AcceptDelegateCall, AddressU64, CallableByContract, CallableByPrecompile, PrecompileAt, + PrecompileSetBuilder, PrecompilesInRangeInclusive, +}; + +type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile); + +#[precompile_utils::precompile_name_from_address] +pub type DefaultPrecompiles = ( + // Ethereum precompiles: + PrecompileAt, ECRecover, EthereumPrecompilesChecks>, + PrecompileAt, Sha256, EthereumPrecompilesChecks>, + PrecompileAt, Ripemd160, EthereumPrecompilesChecks>, + PrecompileAt, Identity, EthereumPrecompilesChecks>, + PrecompileAt, Modexp, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Add, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Mul, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Pairing, EthereumPrecompilesChecks>, + PrecompileAt, Blake2F, EthereumPrecompilesChecks>, + PrecompileAt, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>, + PrecompileAt, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>, +); + +pub type TanglePrecompiles = PrecompileSetBuilder< + R, + (PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<2095>), DefaultPrecompiles>,), +>; + +parameter_types! { + pub const MinimumPeriod: u64 = 6000 / 2; + + pub PrecompilesValue: TanglePrecompiles = TanglePrecompiles::<_>::new(); +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + (1.into(), Weight::zero()) + } +} + +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(address_build(0).address) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub const TransactionByteFee: u64 = 1; + pub const ChainId: u64 = 42; + pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); +} + +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(_fees_then_tips: impl Iterator) { + // whatever + } +} +pub struct FreeEVMExecution; + +impl OnChargeEVMTransaction for FreeEVMExecution { + type LiquidityInfo = (); + + fn withdraw_fee( + _who: &H160, + _fee: U256, + ) -> Result> { + Ok(()) + } + + fn correct_and_deposit_fee( + _who: &H160, + _corrected_fee: U256, + _base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + already_withdrawn + } + + fn pay_priority_fee(_tip: Self::LiquidityInfo) {} +} + +/// Type alias for negative imbalance during fees +type RuntimeNegativeImbalance = + ::AccountId>>::NegativeImbalance; + +/// See: [`pallet_evm::EVMCurrencyAdapter`] +pub struct CustomEVMCurrencyAdapter; + +impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { + type LiquidityInfo = Option; + + fn withdraw_fee( + who: &H160, + fee: U256, + ) -> Result> { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet multi_asset_delegation account free to use + if who == &pallet_multi_asset_delegation_address { + return Ok(None); + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::withdraw_fee(who, fee) + } + + fn correct_and_deposit_fee( + who: &H160, + corrected_fee: U256, + base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet multi_asset_delegation account free to use + if who == &pallet_multi_asset_delegation_address { + return already_withdrawn; + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) + } + + fn pay_priority_fee(tip: Self::LiquidityInfo) { + as OnChargeEVMTransaction< + Runtime, + >>::pay_priority_fee(tip) + } +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = EthereumBlockHashMapping; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = HashedAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = TanglePrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = ChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = CustomEVMCurrencyAdapter; + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, + _ => None, + } + } +} + +pub struct MockedEvmRunner; + +impl tangle_primitives::services::EvmRunner for MockedEvmRunner { + type Error = pallet_evm::Error; + + fn call( + source: sp_core::H160, + target: sp_core::H160, + input: Vec, + value: sp_core::U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result> { + let max_fee_per_gas = FixedGasPrice::min_gas_price().0; + let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); + let nonce = None; + let access_list = Default::default(); + let weight_limit = None; + let proof_size_base_cost = None; + <::Runner as pallet_evm::Runner>::call( + source, + target, + input, + value, + gas_limit, + Some(max_fee_per_gas), + Some(max_priority_fee_per_gas), + nonce, + access_list, + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + ::config(), + ) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) + } +} + +pub struct AccountInfo { + pub address: H160, +} + +pub fn address_build(seed: u8) -> AccountInfo { + let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); + let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); + let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; + let address = H160::from(H256::from(keccak_256(public_key))); + + AccountInfo { address } +} diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 4bde5eb3..93931d37 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -17,6 +17,7 @@ use super::*; use crate::{types::*, CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie, One, Two}; use sp_runtime::Percent; use std::collections::BTreeMap; @@ -24,17 +25,24 @@ use std::collections::BTreeMap; fn delegate_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; + let who = Bob; + let operator = Alice; let asset_id = VDOT; let amount = 100; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who), @@ -139,7 +147,7 @@ fn execute_delegator_unstake_should_work() { )); // Simulate round passing - CurrentRound::::put(10); + CurrentRound::::put(10); assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who),)); @@ -314,7 +322,7 @@ fn delegate_should_fail_if_not_enough_balance() { amount, Default::default() ), - Error::::InsufficientBalance + Error::::InsufficientBalance ); }); } @@ -342,7 +350,7 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { asset_id, amount, ), - Error::::NoActiveDelegation + Error::::NoActiveDelegation ); }); } @@ -377,7 +385,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { asset_id, amount ), - Error::::NoBondLessRequest + Error::::NoBondLessRequest ); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -389,7 +397,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { assert_noop!( MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who),), - Error::::BondLessNotReady + Error::::BondLessNotReady ); }); } @@ -493,13 +501,13 @@ fn distribute_rewards_should_work() { }, whitelisted_blueprint_ids: vec![], }; - RewardConfigStorage::::put(reward_config); + RewardConfigStorage::::put(reward_config); // Set up asset vault lookup - AssetLookupRewardVaults::::insert(asset_id, asset_id); + AssetLookupRewardVaults::::insert(asset_id, asset_id); // Add delegation information - AtStake::::insert( + AtStake::::insert( round, operator, OperatorSnapshot { @@ -561,14 +569,14 @@ fn distribute_rewards_with_multiple_delegators_and_operators_should_work() { }, whitelisted_blueprint_ids: vec![], }; - RewardConfigStorage::::put(reward_config); + RewardConfigStorage::::put(reward_config); // Set up asset vault lookup - AssetLookupRewardVaults::::insert(asset_id1, asset_id1); - AssetLookupRewardVaults::::insert(asset_id2, asset_id2); + AssetLookupRewardVaults::::insert(asset_id1, asset_id1); + AssetLookupRewardVaults::::insert(asset_id2, asset_id2); // Add delegation information - AtStake::::insert( + AtStake::::insert( round, operator1, OperatorSnapshot { @@ -583,7 +591,7 @@ fn distribute_rewards_with_multiple_delegators_and_operators_should_work() { }, ); - AtStake::::insert( + AtStake::::insert( round, operator2, OperatorSnapshot { @@ -655,7 +663,7 @@ fn delegator_can_add_blueprints() { )); // Verify the blueprint was added - let metadata = Delegators::::get(delegator).unwrap(); + let metadata = Delegators::::get(delegator).unwrap(); assert!(metadata.delegations.iter().any(|d| match d.blueprint_selection { DelegatorBlueprintSelection::Fixed(ref blueprints) => { blueprints.contains(&blueprint_id) @@ -666,7 +674,7 @@ fn delegator_can_add_blueprints() { // Try to add the same blueprint again assert_noop!( MultiAssetDelegation::add_blueprint_id(RuntimeOrigin::signed(delegator), blueprint_id), - Error::::DuplicateBlueprintId + Error::::DuplicateBlueprintId ); }); } @@ -699,7 +707,7 @@ fn delegator_can_remove_blueprints() { )); // Verify it was added - let metadata = Delegators::::get(delegator).unwrap(); + let metadata = Delegators::::get(delegator).unwrap(); assert!(metadata.delegations.iter().any(|d| match d.blueprint_selection { DelegatorBlueprintSelection::Fixed(ref blueprints) => { blueprints.contains(&blueprint_id) @@ -714,7 +722,7 @@ fn delegator_can_remove_blueprints() { )); // Verify it was removed - let metadata = Delegators::::get(delegator).unwrap(); + let metadata = Delegators::::get(delegator).unwrap(); assert!(metadata.delegations.iter().all(|d| match d.blueprint_selection { DelegatorBlueprintSelection::Fixed(ref blueprints) => { !blueprints.contains(&blueprint_id) @@ -728,7 +736,7 @@ fn delegator_can_remove_blueprints() { RuntimeOrigin::signed(delegator), blueprint_id ), - Error::::BlueprintIdNotFound + Error::::BlueprintIdNotFound ); }); } diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 7f5aa809..c2766bd0 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -21,7 +21,7 @@ use sp_runtime::ArithmeticError; // helper function pub fn create_and_mint_tokens( asset_id: AssetId, - recipient: ::AccountId, + recipient: ::AccountId, amount: Balance, ) { assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, 1, false, 1)); @@ -29,9 +29,9 @@ pub fn create_and_mint_tokens( } pub fn mint_tokens( - owner: ::AccountId, + owner: ::AccountId, asset_id: AssetId, - recipient: ::AccountId, + recipient: ::AccountId, amount: Balance, ) { assert_ok!(Assets::mint(RuntimeOrigin::signed(owner), asset_id, recipient, amount)); @@ -128,7 +128,7 @@ fn deposit_should_fail_for_bond_too_low() { assert_noop!( MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount,), - Error::::BondTooLow + Error::::BondTooLow ); }); } @@ -174,7 +174,7 @@ fn schedule_withdraw_should_fail_if_not_delegator() { assert_noop!( MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who), asset_id, amount,), - Error::::NotDelegator + Error::::NotDelegator ); }); } @@ -194,7 +194,7 @@ fn schedule_withdraw_should_fail_for_insufficient_balance() { assert_noop!( MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who), asset_id, amount,), - Error::::InsufficientBalance + Error::::InsufficientBalance ); }); } @@ -241,7 +241,7 @@ fn execute_withdraw_should_work() { // Simulate round passing let current_round = 1; - >::put(current_round); + >::put(current_round); assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),)); @@ -264,7 +264,7 @@ fn execute_withdraw_should_fail_if_not_delegator() { assert_noop!( MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),), - Error::::NotDelegator + Error::::NotDelegator ); }); } @@ -284,7 +284,7 @@ fn execute_withdraw_should_fail_if_no_withdraw_request() { assert_noop!( MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),), - Error::::NowithdrawRequests + Error::::NowithdrawRequests ); }); } @@ -309,7 +309,7 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { // Simulate round passing but not enough let current_round = 0; - >::put(current_round); + >::put(current_round); // should not actually withdraw anything assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),)); @@ -364,7 +364,7 @@ fn cancel_withdraw_should_fail_if_not_delegator() { assert_noop!( MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who), 1, 1), - Error::::NotDelegator + Error::::NotDelegator ); }); } @@ -384,7 +384,7 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { assert_noop!( MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who), asset_id, amount), - Error::::NoMatchingwithdrawRequest + Error::::NoMatchingwithdrawRequest ); }); } diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index ca0be840..a124218b 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -49,7 +49,7 @@ fn join_operator_already_operator() { assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); assert_noop!( MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount), - Error::::AlreadyOperator + Error::::AlreadyOperator ); }); } @@ -61,7 +61,7 @@ fn join_operator_insufficient_bond() { assert_noop!( MultiAssetDelegation::join_operators(RuntimeOrigin::signed(4), insufficient_bond), - Error::::BondTooLow + Error::::BondTooLow ); }); } @@ -73,7 +73,7 @@ fn join_operator_insufficient_funds() { assert_noop!( MultiAssetDelegation::join_operators(RuntimeOrigin::signed(4), bond_amount), - pallet_balances::Error::::InsufficientBalance + pallet_balances::Error::::InsufficientBalance ); }); } @@ -99,11 +99,11 @@ fn schedule_leave_operator_success() { // Schedule leave operators without joining assert_noop!( MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1)), - Error::::NotAnOperator + Error::::NotAnOperator ); // Set the current round - >::put(5); + >::put(5); // Join operator first assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); @@ -131,7 +131,7 @@ fn cancel_leave_operator_tests() { assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); // Set the current round - >::put(5); + >::put(5); // Schedule leave operators assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1))); @@ -155,7 +155,7 @@ fn cancel_leave_operator_tests() { // Test: Cancel leave operators without being in leaving state assert_noop!( MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed(1)), - Error::::NotLeavingOperator + Error::::NotLeavingOperator ); // Test: Schedule leave operators again @@ -164,7 +164,7 @@ fn cancel_leave_operator_tests() { // Test: Cancel leave operators without being an operator assert_noop!( MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed(2)), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -204,7 +204,7 @@ fn operator_bond_more_not_an_operator() { // Attempt to stake more without being an operator assert_noop!( MultiAssetDelegation::operator_bond_more(RuntimeOrigin::signed(1), additional_bond), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -221,7 +221,7 @@ fn operator_bond_more_insufficient_balance() { // Attempt to stake more with insufficient balance assert_noop!( MultiAssetDelegation::operator_bond_more(RuntimeOrigin::signed(1), additional_bond), - pallet_balances::Error::::InsufficientBalance + pallet_balances::Error::::InsufficientBalance ); }); } @@ -271,7 +271,7 @@ fn schedule_operator_unstake_respects_minimum_stake() { RuntimeOrigin::signed(1), unstake_amount ), - Error::::InsufficientStakeRemaining + Error::::InsufficientStakeRemaining ); }); } @@ -287,7 +287,7 @@ fn schedule_operator_unstake_not_an_operator() { RuntimeOrigin::signed(1), unstake_amount ), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -303,7 +303,7 @@ fn schedule_operator_unstake_not_an_operator() { // assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); // // Manually set the operator's delegation count to simulate active services -// Operators::::mutate(1, |operator| { +// Operators::::mutate(1, |operator| { // if let Some(ref mut operator) = operator { // operator.delegation_count = 1; // } @@ -312,7 +312,7 @@ fn schedule_operator_unstake_not_an_operator() { // // Attempt to schedule unstake with active services // assert_noop!( // MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(1), -// unstake_amount), Error::::ActiveServicesUsingTNT +// unstake_amount), Error::::ActiveServicesUsingTNT // ); // }); // } @@ -333,7 +333,7 @@ fn execute_operator_unstake_success() { )); // Set the current round to simulate passage of time - >::put(15); + >::put(15); // Execute unstake assert_ok!(MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1))); @@ -356,7 +356,7 @@ fn execute_operator_unstake_not_an_operator() { // Attempt to execute unstake without being an operator assert_noop!( MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -372,7 +372,7 @@ fn execute_operator_unstake_no_scheduled_unstake() { // Attempt to execute unstake without scheduling it assert_noop!( MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), - Error::::NoScheduledBondLess + Error::::NoScheduledBondLess ); }); } @@ -395,7 +395,7 @@ fn execute_operator_unstake_request_not_satisfied() { // Attempt to execute unstake before request is satisfied assert_noop!( MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), - Error::::BondLessRequestNotSatisfied + Error::::BondLessRequestNotSatisfied ); }); } @@ -435,7 +435,7 @@ fn cancel_operator_unstake_not_an_operator() { // Attempt to cancel unstake without being an operator assert_noop!( MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed(1)), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -451,7 +451,7 @@ fn cancel_operator_unstake_no_scheduled_unstake() { // Attempt to cancel unstake without scheduling it assert_noop!( MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed(1)), - Error::::NoScheduledBondLess + Error::::NoScheduledBondLess ); }); } @@ -484,7 +484,7 @@ fn go_offline_not_an_operator() { // Attempt to go offline without being an operator assert_noop!( MultiAssetDelegation::go_offline(RuntimeOrigin::signed(1)), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -589,7 +589,7 @@ fn slash_operator_not_an_operator() { new_test_ext().execute_with(|| { assert_noop!( MultiAssetDelegation::slash_operator(&1, 1, Percent::from_percent(50)), - Error::::NotAnOperator + Error::::NotAnOperator ); }); } @@ -603,7 +603,7 @@ fn slash_operator_not_active() { assert_noop!( MultiAssetDelegation::slash_operator(&1, 1, Percent::from_percent(50)), - Error::::NotActiveOperator + Error::::NotActiveOperator ); }); } @@ -632,7 +632,7 @@ fn slash_delegator_fixed_blueprint_not_selected() { // Try to slash with unselected blueprint assert_noop!( MultiAssetDelegation::slash_delegator(&2, &1, 5, Percent::from_percent(50)), - Error::::BlueprintNotSelected + Error::::BlueprintNotSelected ); }); } diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 19224df2..d16c193d 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -26,7 +26,7 @@ fn handle_round_change_should_work() { let asset_id = VDOT; let amount = 100; - CurrentRound::::put(1); + CurrentRound::::put(1); assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); @@ -43,7 +43,7 @@ fn handle_round_change_should_work() { Default::default() )); - assert_ok!(Pallet::::handle_round_change()); + assert_ok!(Pallet::::handle_round_change()); // Assert let current_round = MultiAssetDelegation::current_round(); @@ -70,7 +70,7 @@ fn handle_round_change_with_unstake_should_work() { let amount2 = 200; let unstake_amount = 50; - CurrentRound::::put(1); + CurrentRound::::put(1); assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator1), 10_000)); assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator2), 10_000)); @@ -113,7 +113,7 @@ fn handle_round_change_with_unstake_should_work() { unstake_amount, )); - assert_ok!(Pallet::::handle_round_change()); + assert_ok!(Pallet::::handle_round_change()); // Assert let current_round = MultiAssetDelegation::current_round(); diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 81bfb839..02d87f18 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -266,7 +266,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -307,7 +307,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -351,7 +351,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -396,7 +396,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -435,7 +435,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -484,7 +484,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, ZERO_ADDRESS) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 91d2bc2d..7739a240 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -199,18 +199,18 @@ where .map_err(|_| revert_custom_error(Self::INVALID_AMOUNT))? }; - const ZERO_ADDRESS: [u8; 20] = [0; 20]; + const zero_address: [u8; 20] = [0; 20]; let (payment_asset, amount) = match (payment_asset_id.as_u32(), payment_token_address.0 .0) { - (0, ZERO_ADDRESS) => (Asset::Custom(0u32.into()), value), + (0, zero_address) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); } (Asset::Erc20(erc20_token.into()), amount) }, - (other_asset_id, ZERO_ADDRESS) => { + (other_asset_id, zero_address) => { if value != Default::default() { return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); } From 42a56feef4e19760a56ee3d3a47f30cd0fcc888e Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:22:58 +0530 Subject: [PATCH 16/63] cleanup tests --- pallets/multi-asset-delegation/Cargo.toml | 1 + .../src/tests/delegate.rs | 472 +++++------------- .../src/tests/deposit.rs | 168 +++++-- .../src/tests/operator.rs | 319 ++++++++---- 4 files changed, 479 insertions(+), 481 deletions(-) diff --git a/pallets/multi-asset-delegation/Cargo.toml b/pallets/multi-asset-delegation/Cargo.toml index 24a6f9f7..a220c7c0 100644 --- a/pallets/multi-asset-delegation/Cargo.toml +++ b/pallets/multi-asset-delegation/Cargo.toml @@ -111,6 +111,7 @@ std = [ "fp-storage/std", "ethabi/std", "sp-keyring/std", + "pallet-ethereum/std" ] try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 93931d37..7fd0c479 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -20,14 +20,15 @@ use frame_support::{assert_noop, assert_ok}; use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie, One, Two}; use sp_runtime::Percent; use std::collections::BTreeMap; +use tangle_primitives::services::Asset; #[test] fn delegate_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = Bob; - let operator = Alice; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; assert_ok!(MultiAssetDelegation::join_operators( @@ -42,11 +43,12 @@ fn delegate_should_work() { RuntimeOrigin::signed(who.into()), asset_id, amount, + None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), - operator, + RuntimeOrigin::signed(who.into()), + operator.into(), asset_id, amount, Default::default() @@ -57,7 +59,7 @@ fn delegate_should_work() { assert!(metadata.deposits.get(&asset_id).is_none()); assert_eq!(metadata.delegations.len(), 1); let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator); + assert_eq!(delegation.operator, operator.into()); assert_eq!(delegation.amount, amount); assert_eq!(delegation.asset_id, asset_id); @@ -66,7 +68,7 @@ fn delegate_should_work() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who); + assert_eq!(operator_delegation.delegator, who.into()); assert_eq!(operator_delegation.amount, amount); assert_eq!(operator_delegation.asset_id, asset_id); }); @@ -76,28 +78,36 @@ fn delegate_should_work() { fn schedule_delegator_unstake_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit and delegate first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), - operator, + RuntimeOrigin::signed(who.into()), + operator.into(), asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), - operator, + RuntimeOrigin::signed(who.into()), + operator.into(), asset_id, amount, )); @@ -121,26 +131,34 @@ fn schedule_delegator_unstake_should_work() { fn execute_delegator_unstake_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -149,7 +167,9 @@ fn execute_delegator_unstake_should_work() { // Simulate round passing CurrentRound::::put(10); - assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who),)); + assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed( + who.into() + ),)); // Assert let metadata = MultiAssetDelegation::delegators(who).unwrap(); @@ -163,19 +183,27 @@ fn execute_delegator_unstake_should_work() { fn cancel_delegator_unstake_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -183,7 +211,7 @@ fn cancel_delegator_unstake_should_work() { )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -203,7 +231,7 @@ fn cancel_delegator_unstake_should_work() { assert_eq!(operator_metadata.delegations.len(), 0); assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount @@ -229,19 +257,27 @@ fn cancel_delegator_unstake_should_work() { fn cancel_delegator_unstake_should_update_already_existing() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -249,7 +285,7 @@ fn cancel_delegator_unstake_should_update_already_existing() { )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, 10, @@ -273,7 +309,7 @@ fn cancel_delegator_unstake_should_update_already_existing() { assert_eq!(operator_delegation.asset_id, asset_id); assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, 10 @@ -299,24 +335,28 @@ fn cancel_delegator_unstake_should_update_already_existing() { fn delegate_should_fail_if_not_enough_balance() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 10_000; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), asset_id, amount - 20, + None )); assert_noop!( MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -331,21 +371,29 @@ fn delegate_should_fail_if_not_enough_balance() { fn schedule_delegator_unstake_should_fail_if_no_delegation() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_noop!( MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -359,19 +407,27 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { fn execute_delegator_unstake_should_fail_if_not_ready() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.into(), amount); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.into()), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -380,7 +436,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { assert_noop!( MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount @@ -389,14 +445,14 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { ); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, )); assert_noop!( - MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who),), + MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who.into()),), Error::::BondLessNotReady ); }); @@ -406,26 +462,30 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { fn delegate_should_not_create_multiple_on_repeat_delegation() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; let additional_amount = 50; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.into()), + 10_000 + )); create_and_mint_tokens(VDOT, who, amount + additional_amount); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), asset_id, amount + additional_amount, + None )); // Delegate first time assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, amount, @@ -452,7 +512,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { // Delegate additional amount assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.into()), operator, asset_id, additional_amount, @@ -478,265 +538,3 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_operator_delegation.asset_id, asset_id); }); } - -#[test] -fn distribute_rewards_should_work() { - new_test_ext().execute_with(|| { - let round = 1; - let operator = 1; - let delegator = 2; - let asset_id = 1; - let amount = 100; - let cap = 50; - let apy = Percent::from_percent(10); // 10% - - let initial_balance = Balances::free_balance(delegator); - - // Set up reward configuration - let reward_config = RewardConfig { - configs: { - let mut map = BTreeMap::new(); - map.insert(asset_id, RewardConfigForAssetVault { apy, cap }); - map - }, - whitelisted_blueprint_ids: vec![], - }; - RewardConfigStorage::::put(reward_config); - - // Set up asset vault lookup - AssetLookupRewardVaults::::insert(asset_id, asset_id); - - // Add delegation information - AtStake::::insert( - round, - operator, - OperatorSnapshot { - delegations: vec![DelegatorBond { delegator, amount, asset_id }] - .try_into() - .unwrap(), - stake: amount, - }, - ); - - // Distribute rewards - assert_ok!(MultiAssetDelegation::distribute_rewards(round)); - - // Check if rewards were distributed correctly - let balance = Balances::free_balance(delegator); - - // Calculate the percentage of the cap that the user is staking - let staking_percentage = amount.saturating_mul(100) / cap; - // Calculate the expected reward based on the staking percentage - let expected_reward = apy.mul_floor(amount); - let calculated_reward = expected_reward.saturating_mul(staking_percentage) / 100; - - assert_eq!(balance - initial_balance, calculated_reward); - }); -} - -#[test] -fn distribute_rewards_with_multiple_delegators_and_operators_should_work() { - new_test_ext().execute_with(|| { - let round = 1; - - let operator1 = 1; - let operator2 = 2; - let delegator1 = 3; - let delegator2 = 4; - - let asset_id1 = 1; - let asset_id2 = 2; - - let amount1 = 100; - let amount2 = 200; - - let cap1 = 50; - let cap2 = 150; - - let apy1 = Percent::from_percent(10); // 10% - let apy2 = Percent::from_percent(20); // 20% - - let initial_balance1 = Balances::free_balance(delegator1); - let initial_balance2 = Balances::free_balance(delegator2); - - // Set up reward configuration - let reward_config = RewardConfig { - configs: { - let mut map = BTreeMap::new(); - map.insert(asset_id1, RewardConfigForAssetVault { apy: apy1, cap: cap1 }); - map.insert(asset_id2, RewardConfigForAssetVault { apy: apy2, cap: cap2 }); - map - }, - whitelisted_blueprint_ids: vec![], - }; - RewardConfigStorage::::put(reward_config); - - // Set up asset vault lookup - AssetLookupRewardVaults::::insert(asset_id1, asset_id1); - AssetLookupRewardVaults::::insert(asset_id2, asset_id2); - - // Add delegation information - AtStake::::insert( - round, - operator1, - OperatorSnapshot { - delegations: vec![DelegatorBond { - delegator: delegator1, - amount: amount1, - asset_id: asset_id1, - }] - .try_into() - .unwrap(), - stake: amount1, - }, - ); - - AtStake::::insert( - round, - operator2, - OperatorSnapshot { - delegations: vec![DelegatorBond { - delegator: delegator2, - amount: amount2, - asset_id: asset_id2, - }] - .try_into() - .unwrap(), - stake: amount2, - }, - ); - - // Distribute rewards - assert_ok!(MultiAssetDelegation::distribute_rewards(round)); - - // Check if rewards were distributed correctly - let balance1 = Balances::free_balance(delegator1); - let balance2 = Balances::free_balance(delegator2); - - // Calculate the percentage of the cap that each user is staking - let staking_percentage1 = amount1.saturating_mul(100) / cap1; - let staking_percentage2 = amount2.saturating_mul(100) / cap2; - - // Calculate the expected rewards based on the staking percentages - let expected_reward1 = apy1.mul_floor(amount1); - let calculated_reward1 = expected_reward1.saturating_mul(staking_percentage1) / 100; - - let expected_reward2 = apy2.mul_floor(amount2); - let calculated_reward2 = expected_reward2.saturating_mul(staking_percentage2) / 100; - - assert_eq!(balance1 - initial_balance1, calculated_reward1); - assert_eq!(balance2 - initial_balance2, calculated_reward2); - }); -} - -#[test] -fn delegator_can_add_blueprints() { - new_test_ext().execute_with(|| { - let delegator = 1; - let blueprint_id = 1; - let operator = 2; - let asset_id = VDOT; - let amount = 100; - - create_and_mint_tokens(VDOT, delegator, amount); - - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator), - asset_id, - amount, - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator), - operator, - asset_id, - amount, - DelegatorBlueprintSelection::Fixed(vec![200].try_into().unwrap()), - )); - - // Add a blueprint - assert_ok!(MultiAssetDelegation::add_blueprint_id( - RuntimeOrigin::signed(delegator), - blueprint_id - )); - - // Verify the blueprint was added - let metadata = Delegators::::get(delegator).unwrap(); - assert!(metadata.delegations.iter().any(|d| match d.blueprint_selection { - DelegatorBlueprintSelection::Fixed(ref blueprints) => { - blueprints.contains(&blueprint_id) - }, - _ => false, - })); - - // Try to add the same blueprint again - assert_noop!( - MultiAssetDelegation::add_blueprint_id(RuntimeOrigin::signed(delegator), blueprint_id), - Error::::DuplicateBlueprintId - ); - }); -} - -#[test] -fn delegator_can_remove_blueprints() { - new_test_ext().execute_with(|| { - let delegator = 1; - let blueprint_id = 1; - let operator = 2; - let asset_id = VDOT; - let amount = 100; - - create_and_mint_tokens(VDOT, delegator, amount); - - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator), - asset_id, - amount, - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator), - operator, - asset_id, - amount, - DelegatorBlueprintSelection::Fixed(vec![blueprint_id].try_into().unwrap()), - )); - - // Verify it was added - let metadata = Delegators::::get(delegator).unwrap(); - assert!(metadata.delegations.iter().any(|d| match d.blueprint_selection { - DelegatorBlueprintSelection::Fixed(ref blueprints) => { - blueprints.contains(&blueprint_id) - }, - _ => false, - })); - - // Remove the blueprint - assert_ok!(MultiAssetDelegation::remove_blueprint_id( - RuntimeOrigin::signed(delegator), - blueprint_id - )); - - // Verify it was removed - let metadata = Delegators::::get(delegator).unwrap(); - assert!(metadata.delegations.iter().all(|d| match d.blueprint_selection { - DelegatorBlueprintSelection::Fixed(ref blueprints) => { - !blueprints.contains(&blueprint_id) - }, - _ => true, - })); - - // Try to remove a non-existent blueprint - assert_noop!( - MultiAssetDelegation::remove_blueprint_id( - RuntimeOrigin::signed(delegator), - blueprint_id - ), - Error::::BlueprintIdNotFound - ); - }); -} diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index c2766bd0..684a8d06 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -16,7 +16,9 @@ use super::*; use crate::{types::DelegatorStatus, CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie, One, Two}; use sp_runtime::ArithmeticError; +use tangle_primitives::services::Asset; // helper function pub fn create_and_mint_tokens( @@ -24,8 +26,8 @@ pub fn create_and_mint_tokens( recipient: ::AccountId, amount: Balance, ) { - assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, 1, false, 1)); - assert_ok!(Assets::mint(RuntimeOrigin::signed(1), asset_id, recipient, amount)); + assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient, false, 1)); + assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient), asset_id, recipient, amount)); } pub fn mint_tokens( @@ -41,22 +43,27 @@ pub fn mint_tokens( fn deposit_should_work_for_fungible_asset() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); let amount = 200; create_and_mint_tokens(VDOT, who, amount); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + amount, + None + )); // Assert let metadata = MultiAssetDelegation::delegators(who).unwrap(); - assert_eq!(metadata.deposits.get(&VDOT), Some(&amount)); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { who, amount, - asset_id: VDOT, + asset_id: Asset::Custom(VDOT), }) ); }); @@ -66,36 +73,46 @@ fn deposit_should_work_for_fungible_asset() { fn multiple_deposit_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); let amount = 200; create_and_mint_tokens(VDOT, who, amount * 4); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + amount, + None + )); // Assert let metadata = MultiAssetDelegation::delegators(who).unwrap(); - assert_eq!(metadata.deposits.get(&VDOT), Some(&amount)); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { who, amount, - asset_id: VDOT, + asset_id: Asset::Custom(VDOT), }) ); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + amount, + None + )); // Assert let metadata = MultiAssetDelegation::delegators(who).unwrap(); - assert_eq!(metadata.deposits.get(&VDOT), Some(&amount * 2).as_ref()); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount * 2).as_ref()); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { who, amount, - asset_id: VDOT, + asset_id: Asset::Custom(VDOT), }) ); }); @@ -105,13 +122,18 @@ fn multiple_deposit_should_work() { fn deposit_should_fail_for_insufficient_balance() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); let amount = 2000; create_and_mint_tokens(VDOT, who, 100); assert_noop!( - MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount,), + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + amount, + None + ), ArithmeticError::Underflow ); }); @@ -121,13 +143,18 @@ fn deposit_should_fail_for_insufficient_balance() { fn deposit_should_fail_for_bond_too_low() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); let amount = 50; // Below the minimum stake amount create_and_mint_tokens(VDOT, who, amount); assert_noop!( - MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), VDOT, amount,), + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + amount, + None + ), Error::::BondTooLow ); }); @@ -137,14 +164,19 @@ fn deposit_should_fail_for_bond_too_low() { fn schedule_withdraw_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who), @@ -166,8 +198,8 @@ fn schedule_withdraw_should_work() { fn schedule_withdraw_should_fail_if_not_delegator() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); @@ -183,14 +215,14 @@ fn schedule_withdraw_should_fail_if_not_delegator() { fn schedule_withdraw_should_fail_for_insufficient_balance() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 200; create_and_mint_tokens(VDOT, who, 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, 100,)); + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, 100, None)); assert_noop!( MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who), asset_id, amount,), @@ -203,14 +235,19 @@ fn schedule_withdraw_should_fail_for_insufficient_balance() { fn schedule_withdraw_should_fail_if_withdraw_request_exists() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); // Schedule the first withdraw assert_ok!(MultiAssetDelegation::schedule_withdraw( @@ -225,14 +262,19 @@ fn schedule_withdraw_should_fail_if_withdraw_request_exists() { fn execute_withdraw_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who), asset_id, @@ -243,7 +285,7 @@ fn execute_withdraw_should_work() { let current_round = 1; >::put(current_round); - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),)); + assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None)); // Assert let metadata = MultiAssetDelegation::delegators(who); @@ -260,10 +302,10 @@ fn execute_withdraw_should_work() { fn execute_withdraw_should_fail_if_not_delegator() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),), + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None), Error::::NotDelegator ); }); @@ -273,17 +315,22 @@ fn execute_withdraw_should_fail_if_not_delegator() { fn execute_withdraw_should_fail_if_no_withdraw_request() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),), + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None), Error::::NowithdrawRequests ); }); @@ -293,14 +340,19 @@ fn execute_withdraw_should_fail_if_no_withdraw_request() { fn execute_withdraw_should_fail_if_withdraw_not_ready() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who), asset_id, @@ -312,7 +364,7 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { >::put(current_round); // should not actually withdraw anything - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who),)); + assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None)); let metadata = MultiAssetDelegation::delegators(who).unwrap(); assert!(!metadata.withdraw_requests.is_empty()); @@ -323,14 +375,19 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { fn cancel_withdraw_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; create_and_mint_tokens(VDOT, who, 100); // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who), asset_id, @@ -360,10 +417,14 @@ fn cancel_withdraw_should_work() { fn cancel_withdraw_should_fail_if_not_delegator() { new_test_ext().execute_with(|| { // Arrange - let who = 1; + let who: AccountId = Bob.into(); assert_noop!( - MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who), 1, 1), + MultiAssetDelegation::cancel_withdraw( + RuntimeOrigin::signed(who), + Asset::Custom(VDOT), + 1 + ), Error::::NotDelegator ); }); @@ -373,14 +434,19 @@ fn cancel_withdraw_should_fail_if_not_delegator() { fn cancel_withdraw_should_fail_if_no_withdraw_request() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let asset_id = VDOT; + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); assert_noop!( MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who), asset_id, amount), diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index a124218b..ee7c85fc 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -19,16 +19,22 @@ use crate::{ CurrentRound, Error, }; use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::Bob; +use sp_keyring::AccountKeyring::{Alice, Eve}; use sp_runtime::Percent; +use tangle_primitives::services::Asset; #[test] fn join_operator_success() { new_test_ext().execute_with(|| { let bond_amount = 10_000; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, bond_amount); assert_eq!(operator_info.delegation_count, 0); assert_eq!(operator_info.request, None); @@ -36,7 +42,7 @@ fn join_operator_success() { // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorJoined { - who: 1, + who: Alice.to_account_id(), })); }); } @@ -46,9 +52,15 @@ fn join_operator_already_operator() { new_test_ext().execute_with(|| { let bond_amount = 10_000; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); assert_noop!( - MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount), + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + ), Error::::AlreadyOperator ); }); @@ -60,7 +72,10 @@ fn join_operator_insufficient_bond() { let insufficient_bond = 5_000; assert_noop!( - MultiAssetDelegation::join_operators(RuntimeOrigin::signed(4), insufficient_bond), + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Eve.to_account_id()), + insufficient_bond + ), Error::::BondTooLow ); }); @@ -72,7 +87,10 @@ fn join_operator_insufficient_funds() { let bond_amount = 15_000; // User 4 has only 5_000 assert_noop!( - MultiAssetDelegation::join_operators(RuntimeOrigin::signed(4), bond_amount), + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Eve.to_account_id()), + bond_amount + ), pallet_balances::Error::::InsufficientBalance ); }); @@ -84,9 +102,12 @@ fn join_operator_minimum_bond() { let minimum_bond = 10_000; let exact_bond = minimum_bond; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), exact_bond)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + exact_bond + )); - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, exact_bond); }); } @@ -98,7 +119,9 @@ fn schedule_leave_operator_success() { // Schedule leave operators without joining assert_noop!( - MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1)), + MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NotAnOperator ); @@ -106,18 +129,23 @@ fn schedule_leave_operator_success() { >::put(5); // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Schedule leave operators - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorLeavingScheduled { who: 1 }, + Event::OperatorLeavingScheduled { who: Alice.to_account_id() }, )); }); } @@ -128,42 +156,55 @@ fn cancel_leave_operator_tests() { let bond_amount = 10_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Set the current round >::put(5); // Schedule leave operators - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Verify operator metadata after cancellation - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) // Test: Cancel leave operators successfully - assert_ok!(MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Verify operator metadata after cancellation - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.status, OperatorStatus::Active); // current_round (5) + leave_operators_delay (10) // Verify event for cancellation System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorLeaveCancelled { who: 1 }, + Event::OperatorLeaveCancelled { who: Alice.to_account_id() }, )); // Test: Cancel leave operators without being in leaving state assert_noop!( - MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed(1)), + MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NotLeavingOperator ); // Test: Schedule leave operators again - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Test: Cancel leave operators without being an operator assert_noop!( - MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed(2)), + MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Bob.to_account_id() + )), Error::::NotAnOperator ); }); @@ -176,21 +217,24 @@ fn operator_bond_more_success() { let additional_bond = 5_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // stake more TNT assert_ok!(MultiAssetDelegation::operator_bond_more( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), additional_bond )); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, bond_amount + additional_bond); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorBondMore { - who: 1, + who: Alice.to_account_id(), additional_bond, })); }); @@ -203,7 +247,10 @@ fn operator_bond_more_not_an_operator() { // Attempt to stake more without being an operator assert_noop!( - MultiAssetDelegation::operator_bond_more(RuntimeOrigin::signed(1), additional_bond), + MultiAssetDelegation::operator_bond_more( + RuntimeOrigin::signed(Alice.to_account_id()), + additional_bond + ), Error::::NotAnOperator ); }); @@ -216,11 +263,17 @@ fn operator_bond_more_insufficient_balance() { let additional_bond = 115_000; // Exceeds available balance // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Attempt to stake more with insufficient balance assert_noop!( - MultiAssetDelegation::operator_bond_more(RuntimeOrigin::signed(1), additional_bond), + MultiAssetDelegation::operator_bond_more( + RuntimeOrigin::signed(Alice.to_account_id()), + additional_bond + ), pallet_balances::Error::::InsufficientBalance ); }); @@ -233,24 +286,30 @@ fn schedule_operator_unstake_success() { let unstake_amount = 5_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Schedule unstake assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount )); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.request.unwrap().amount, unstake_amount); // Verify remaining stake is above minimum - assert!(operator_info.stake.saturating_sub(unstake_amount) >= MinOperatorBondAmount::get()); + assert!( + operator_info.stake.saturating_sub(unstake_amount) + >= MinOperatorBondAmount::get().into() + ); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessScheduled { who: 1, unstake_amount }, + Event::OperatorBondLessScheduled { who: Alice.to_account_id(), unstake_amount }, )); }); } @@ -263,12 +322,15 @@ fn schedule_operator_unstake_respects_minimum_stake() { let unstake_amount = 15_000; // Would leave less than minimum required // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Attempt to schedule unstake that would leave less than minimum assert_noop!( MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount ), Error::::InsufficientStakeRemaining @@ -284,7 +346,7 @@ fn schedule_operator_unstake_not_an_operator() { // Attempt to schedule unstake without being an operator assert_noop!( MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount ), Error::::NotAnOperator @@ -300,7 +362,7 @@ fn schedule_operator_unstake_not_an_operator() { // let unstake_amount = 5_000; // // Join operator first -// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); +// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(Alice.to_account_id()), bond_amount)); // // Manually set the operator's delegation count to simulate active services // Operators::::mutate(1, |operator| { @@ -311,7 +373,7 @@ fn schedule_operator_unstake_not_an_operator() { // // Attempt to schedule unstake with active services // assert_noop!( -// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(1), +// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), // unstake_amount), Error::::ActiveServicesUsingTNT // ); // }); @@ -324,11 +386,14 @@ fn execute_operator_unstake_success() { let unstake_amount = 5_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Schedule unstake assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount )); @@ -336,16 +401,18 @@ fn execute_operator_unstake_success() { >::put(15); // Execute unstake - assert_ok!(MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, bond_amount - unstake_amount); assert_eq!(operator_info.request, None); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessExecuted { who: 1 }, + Event::OperatorBondLessExecuted { who: Alice.to_account_id() }, )); }); } @@ -355,7 +422,9 @@ fn execute_operator_unstake_not_an_operator() { new_test_ext().execute_with(|| { // Attempt to execute unstake without being an operator assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NotAnOperator ); }); @@ -367,11 +436,16 @@ fn execute_operator_unstake_no_scheduled_unstake() { let bond_amount = 10_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Attempt to execute unstake without scheduling it assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NoScheduledBondLess ); }); @@ -384,17 +458,22 @@ fn execute_operator_unstake_request_not_satisfied() { let unstake_amount = 5_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Schedule unstake assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount )); // Attempt to execute unstake before request is satisfied assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed(1)), + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::BondLessRequestNotSatisfied ); }); @@ -407,24 +486,29 @@ fn cancel_operator_unstake_success() { let unstake_amount = 5_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Schedule unstake assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(1), + RuntimeOrigin::signed(Alice.to_account_id()), unstake_amount )); // Cancel unstake - assert_ok!(MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + ))); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.request, None); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessCancelled { who: 1 }, + Event::OperatorBondLessCancelled { who: Alice.to_account_id() }, )); }); } @@ -434,7 +518,9 @@ fn cancel_operator_unstake_not_an_operator() { new_test_ext().execute_with(|| { // Attempt to cancel unstake without being an operator assert_noop!( - MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed(1)), + MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NotAnOperator ); }); @@ -446,11 +532,16 @@ fn cancel_operator_unstake_no_scheduled_unstake() { let bond_amount = 10_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Attempt to cancel unstake without scheduling it assert_noop!( - MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed(1)), + MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), Error::::NoScheduledBondLess ); }); @@ -462,18 +553,21 @@ fn go_offline_success() { let bond_amount = 10_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Go offline - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.status, OperatorStatus::Inactive); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOffline { - who: 1, + who: Alice.to_account_id(), })); }); } @@ -483,7 +577,7 @@ fn go_offline_not_an_operator() { new_test_ext().execute_with(|| { // Attempt to go offline without being an operator assert_noop!( - MultiAssetDelegation::go_offline(RuntimeOrigin::signed(1)), + MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id())), Error::::NotAnOperator ); }); @@ -495,21 +589,24 @@ fn go_online_success() { let bond_amount = 10_000; // Join operator first - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), bond_amount)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); // Go offline first - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); // Go online - assert_ok!(MultiAssetDelegation::go_online(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::go_online(RuntimeOrigin::signed(Alice.to_account_id()))); // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.status, OperatorStatus::Active); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOnline { - who: 1, + who: Alice.to_account_id(), })); }); } @@ -519,26 +616,35 @@ fn slash_operator_success() { new_test_ext().execute_with(|| { // Setup operator let operator_stake = 10_000; - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), operator_stake)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + operator_stake + )); // Setup delegators let delegator_stake = 5_000; - let asset_id = 1; + let asset_id = Asset::Custom(1); let blueprint_id = 1; - create_and_mint_tokens(asset_id, 2, delegator_stake); - mint_tokens(1, asset_id, 3, delegator_stake); + create_and_mint_tokens(asset_id, Bob.to_account_id(), delegator_stake); + mint_tokens(Bob.to_account_id(), asset_id, Bob.to_account_id(), delegator_stake); // Setup delegator with fixed blueprint selection assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(2), + RuntimeOrigin::signed(Bob.to_account_id()), asset_id, - delegator_stake + delegator_stake, + None + )); + + assert_ok!(MultiAssetDelegation::add_blueprint_id( + RuntimeOrigin::signed(Bob.to_account_id()), + blueprint_id )); - assert_ok!(MultiAssetDelegation::add_blueprint_id(RuntimeOrigin::signed(2), blueprint_id)); + assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(2), - 1, + RuntimeOrigin::signed(Bob.to_account_id()), + Alice.to_account_id(), asset_id, delegator_stake, Fixed(vec![blueprint_id].try_into().unwrap()), @@ -546,12 +652,14 @@ fn slash_operator_success() { // Setup delegator with all blueprints assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(Bob.to_account_id()), asset_id, - delegator_stake + delegator_stake, + None )); + assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(Bob.to_account_id()), 1, asset_id, delegator_stake, @@ -560,10 +668,14 @@ fn slash_operator_success() { // Slash 50% of stakes let slash_percentage = Percent::from_percent(50); - assert_ok!(MultiAssetDelegation::slash_operator(&1, blueprint_id, slash_percentage)); + assert_ok!(MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + blueprint_id, + slash_percentage + )); // Verify operator stake was slashed - let operator_info = MultiAssetDelegation::operator_info(1).unwrap(); + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, operator_stake / 2); // Verify fixed delegator stake was slashed @@ -578,7 +690,7 @@ fn slash_operator_success() { // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorSlashed { - who: 1, + who: Alice.to_account_id(), amount: operator_stake / 2, })); }); @@ -588,7 +700,11 @@ fn slash_operator_success() { fn slash_operator_not_an_operator() { new_test_ext().execute_with(|| { assert_noop!( - MultiAssetDelegation::slash_operator(&1, 1, Percent::from_percent(50)), + MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + 1, + Percent::from_percent(50) + ), Error::::NotAnOperator ); }); @@ -598,11 +714,18 @@ fn slash_operator_not_an_operator() { fn slash_operator_not_active() { new_test_ext().execute_with(|| { // Setup and deactivate operator - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), 10_000)); - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(1))); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + 10_000 + )); + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); assert_noop!( - MultiAssetDelegation::slash_operator(&1, 1, Percent::from_percent(50)), + MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + 1, + Percent::from_percent(50) + ), Error::::NotActiveOperator ); }); @@ -612,17 +735,27 @@ fn slash_operator_not_active() { fn slash_delegator_fixed_blueprint_not_selected() { new_test_ext().execute_with(|| { // Setup operator - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(1), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + 10_000 + )); - create_and_mint_tokens(1, 2, 10_000); + create_and_mint_tokens(1, Bob.to_account_id(), 10_000); // Setup delegator with fixed blueprint selection - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(2), 1, 5_000)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(Bob.to_account_id()), + 1, + 5_000 + )); - assert_ok!(MultiAssetDelegation::add_blueprint_id(RuntimeOrigin::signed(2), 1)); + assert_ok!(MultiAssetDelegation::add_blueprint_id( + RuntimeOrigin::signed(Bob.to_account_id()), + 1 + )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(2), + RuntimeOrigin::signed(Bob.to_account_id()), 1, 1, 5_000, From 145ff94599d913cfa2ea54fc34ad3905232e8caa Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:35:33 +0530 Subject: [PATCH 17/63] update js types --- types/src/interfaces/augment-api-errors.ts | 28 + types/src/interfaces/augment-api-events.ts | 16 +- types/src/interfaces/augment-api-query.ts | 14 +- types/src/interfaces/augment-api-tx.ts | 37 +- types/src/interfaces/lookup.ts | 692 ++++++++++---------- types/src/interfaces/registry.ts | 5 +- types/src/interfaces/types-lookup.ts | 694 +++++++++++---------- types/src/metadata.json | 2 +- 8 files changed, 813 insertions(+), 675 deletions(-) diff --git a/types/src/interfaces/augment-api-errors.ts b/types/src/interfaces/augment-api-errors.ts index ae1772de..6392b323 100644 --- a/types/src/interfaces/augment-api-errors.ts +++ b/types/src/interfaces/augment-api-errors.ts @@ -1089,6 +1089,18 @@ declare module '@polkadot/api-base/types/errors' { * Error returned when trying to add a blueprint ID that already exists. **/ DuplicateBlueprintId: AugmentedError; + /** + * Erc20 transfer failed + **/ + ERC20TransferFailed: AugmentedError; + /** + * EVM decode error + **/ + EVMAbiDecode: AugmentedError; + /** + * EVM encode error + **/ + EVMAbiEncode: AugmentedError; /** * The account has insufficient balance. **/ @@ -1545,6 +1557,10 @@ declare module '@polkadot/api-base/types/errors' { * The service blueprint was not found. **/ BlueprintNotFound: AugmentedError; + /** + * The ERC20 transfer failed. + **/ + ERC20TransferFailed: AugmentedError; /** * An error occurred while decoding the EVM ABI. **/ @@ -1553,6 +1569,14 @@ declare module '@polkadot/api-base/types/errors' { * An error occurred while encoding the EVM ABI. **/ EVMAbiEncode: AugmentedError; + /** + * Expected the account to be an account ID. + **/ + ExpectedAccountId: AugmentedError; + /** + * Expected the account to be an EVM address. + **/ + ExpectedEVMAddress: AugmentedError; /** * The caller does not have the requirements to call a job. **/ @@ -1611,6 +1635,10 @@ declare module '@polkadot/api-base/types/errors' { * The maximum number of services per user has been exceeded. **/ MaxServicesPerUserExceeded: AugmentedError; + /** + * Missing EVM Origin for the EVM execution. + **/ + MissingEVMOrigin: AugmentedError; /** * No assets provided for the service, at least one asset is required. **/ diff --git a/types/src/interfaces/augment-api-events.ts b/types/src/interfaces/augment-api-events.ts index 0169f426..696e97ff 100644 --- a/types/src/interfaces/augment-api-events.ts +++ b/types/src/interfaces/augment-api-events.ts @@ -9,7 +9,7 @@ import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types'; import type { Bytes, Null, Option, Result, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, H160, H256, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, PalletAirdropClaimsUtilsMultiAddress, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletDemocracyVoteThreshold, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhasePhase, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsPoolState, PalletStakingForcing, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstPoolsPoolState, SpConsensusGrandpaAppPublic, SpNposElectionsElectionScore, SpRuntimeDispatchError, SpStakingExposure, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; +import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, PalletAirdropClaimsUtilsMultiAddress, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletDemocracyVoteThreshold, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhasePhase, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsPoolState, PalletStakingForcing, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstPoolsPoolState, SpConsensusGrandpaAppPublic, SpNposElectionsElectionScore, SpRuntimeDispatchError, SpStakingExposure, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; export type __AugmentedEvent = AugmentedEvent; @@ -784,7 +784,7 @@ declare module '@polkadot/api-base/types/events' { /** * Asset has been updated to reward vault **/ - AssetUpdatedInVault: AugmentedEvent; + AssetUpdatedInVault: AugmentedEvent; /** * Event emitted when a blueprint is whitelisted for rewards **/ @@ -800,7 +800,7 @@ declare module '@polkadot/api-base/types/events' { /** * A delegation has been made. **/ - Delegated: AugmentedEvent; + Delegated: AugmentedEvent; /** * Delegator has been slashed **/ @@ -808,7 +808,11 @@ declare module '@polkadot/api-base/types/events' { /** * A deposit has been made. **/ - Deposited: AugmentedEvent; + Deposited: AugmentedEvent; + /** + * EVM execution reverted with a reason. + **/ + EvmReverted: AugmentedEvent; /** * A delegator unstake request has been executed. **/ @@ -868,11 +872,11 @@ declare module '@polkadot/api-base/types/events' { /** * A delegator unstake request has been scheduled. **/ - ScheduledDelegatorBondLess: AugmentedEvent; + ScheduledDelegatorBondLess: AugmentedEvent; /** * An withdraw has been scheduled. **/ - Scheduledwithdraw: AugmentedEvent; + Scheduledwithdraw: AugmentedEvent; /** * Generic event **/ diff --git a/types/src/interfaces/augment-api-query.ts b/types/src/interfaces/augment-api-query.ts index 2c3e907b..2a062ac4 100644 --- a/types/src/interfaces/augment-api-query.ts +++ b/types/src/interfaces/augment-api-query.ts @@ -10,7 +10,7 @@ import type { Data } from '@polkadot/types'; import type { BTreeSet, Bytes, Null, Option, U256, U8aFixed, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec'; import type { AnyNumber, ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, Call, H160, H256, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumBlock, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportDispatchPerDispatchClassWeight, FrameSupportPreimagesBounded, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCodeUpgradeAuthorization, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReserveData, PalletBountiesBounty, PalletChildBountiesChildBounty, PalletCollectiveVotes, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEvmCodeMetadata, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityAuthorityProperties, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultisigMultisig, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsClaimPermission, PalletNominationPoolsPoolMember, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesUnappliedSlash, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstClaimPermission, PalletTangleLstPoolsPoolMember, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletVestingReleases, PalletVestingVestingInfo, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusGrandpaAppPublic, SpCoreCryptoKeyTypeId, SpNposElectionsElectionScore, SpRuntimeDigest, SpStakingExposure, SpStakingExposurePage, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceRequest, TangleTestnetRuntimeOpaqueSessionKeys } from '@polkadot/types/lookup'; +import type { EthereumBlock, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportDispatchPerDispatchClassWeight, FrameSupportPreimagesBounded, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCodeUpgradeAuthorization, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReserveData, PalletBountiesBounty, PalletChildBountiesChildBounty, PalletCollectiveVotes, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEvmCodeMetadata, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityAuthorityProperties, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultisigMultisig, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsClaimPermission, PalletNominationPoolsPoolMember, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesUnappliedSlash, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstClaimPermission, PalletTangleLstPoolsPoolMember, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletVestingReleases, PalletVestingVestingInfo, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusGrandpaAppPublic, SpCoreCryptoKeyTypeId, SpNposElectionsElectionScore, SpRuntimeDigest, SpStakingExposure, SpStakingExposurePage, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, TanglePrimitivesServicesAsset, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TangleTestnetRuntimeOpaqueSessionKeys } from '@polkadot/types/lookup'; import type { Observable } from '@polkadot/types/types'; export type __AugmentedQuery = AugmentedQuery unknown>; @@ -877,7 +877,7 @@ declare module '@polkadot/api-base/types/storage' { /** * Storage for the reward vaults **/ - assetLookupRewardVaults: AugmentedQuery Observable>, [u128]> & QueryableStorageEntry; + assetLookupRewardVaults: AugmentedQuery Observable>, [TanglePrimitivesServicesAsset]> & QueryableStorageEntry; /** * Snapshot of collator delegation stake at the start of the round. **/ @@ -902,7 +902,7 @@ declare module '@polkadot/api-base/types/storage' { /** * Storage for the reward vaults **/ - rewardVaults: AugmentedQuery Observable>>, [u128]> & QueryableStorageEntry; + rewardVaults: AugmentedQuery Observable>>, [u128]> & QueryableStorageEntry; /** * Generic query **/ @@ -1165,6 +1165,14 @@ declare module '@polkadot/api-base/types/storage' { * Request ID -> Service Request **/ serviceRequests: AugmentedQuery Observable>, [u64]> & QueryableStorageEntry; + /** + * Holds the service payment information for a service request. + * Once the service is initiated, the payment is transferred to the MBSM and this + * information is removed. + * + * Service Requst ID -> Service Payment + **/ + stagingServicePayments: AugmentedQuery Observable>, [u64]> & QueryableStorageEntry; /** * All unapplied slashes that are queued for later. * diff --git a/types/src/interfaces/augment-api-tx.ts b/types/src/interfaces/augment-api-tx.ts index 5fcd0778..92a3d9d0 100644 --- a/types/src/interfaces/augment-api-tx.ts +++ b/types/src/interfaces/augment-api-tx.ts @@ -10,7 +10,7 @@ import type { Data } from '@polkadot/types'; import type { Bytes, Compact, Null, Option, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec'; import type { AnyNumber, IMethod, ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, Call, H160, H256, MultiAddress, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumTransactionTransactionV2, FrameSupportPreimagesBounded, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletBalancesAdjustmentDirection, PalletDemocracyConviction, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsPoolState, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingRewardDestination, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletTangleLstBondExtra, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstPoolsPoolState, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeMultiSignature, SpSessionMembershipProof, SpWeightsWeightV2Weight, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesServiceBlueprint, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; +import type { EthereumTransactionTransactionV2, FrameSupportPreimagesBounded, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletBalancesAdjustmentDirection, PalletDemocracyConviction, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsPoolState, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingRewardDestination, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletTangleLstBondExtra, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstPoolsPoolState, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeMultiSignature, SpSessionMembershipProof, SpWeightsWeightV2Weight, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesServiceBlueprint, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; export type __AugmentedSubmittable = AugmentedSubmittable<() => unknown>; export type __SubmittableExtrinsic = SubmittableExtrinsic; @@ -2319,7 +2319,7 @@ declare module '@polkadot/api-base/types/submittable' { /** * Cancels a scheduled request to reduce a delegator's stake. **/ - cancelDelegatorUnstake: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [AccountId32, u128, u128]>; + cancelDelegatorUnstake: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [AccountId32, TanglePrimitivesServicesAsset, u128]>; /** * Cancels a scheduled leave for an operator. **/ @@ -2331,15 +2331,15 @@ declare module '@polkadot/api-base/types/submittable' { /** * Cancels a scheduled withdraw request. **/ - cancelWithdraw: AugmentedSubmittable<(assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u128, u128]>; + cancelWithdraw: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128]>; /** * Allows a user to delegate an amount of an asset to an operator. **/ - delegate: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array, blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection | { Fixed: any } | { All: any } | string | Uint8Array) => SubmittableExtrinsic, [AccountId32, u128, u128, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection]>; + delegate: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array, blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection | { Fixed: any } | { All: any } | string | Uint8Array) => SubmittableExtrinsic, [AccountId32, TanglePrimitivesServicesAsset, u128, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection]>; /** * Allows a user to deposit an asset. **/ - deposit: AugmentedSubmittable<(assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u128, u128]>; + deposit: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array, evmAddress: Option | null | Uint8Array | H160 | string) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128, Option]>; /** * Executes a scheduled request to reduce a delegator's stake. **/ @@ -2355,7 +2355,7 @@ declare module '@polkadot/api-base/types/submittable' { /** * Executes a scheduled withdraw request. **/ - executeWithdraw: AugmentedSubmittable<() => SubmittableExtrinsic, []>; + executeWithdraw: AugmentedSubmittable<(evmAddress: Option | null | Uint8Array | H160 | string) => SubmittableExtrinsic, [Option]>; /** * Allows an operator to go offline. **/ @@ -2371,7 +2371,7 @@ declare module '@polkadot/api-base/types/submittable' { /** * Manage asset id to vault rewards **/ - manageAssetInVault: AugmentedSubmittable<(vaultId: u128 | AnyNumber | Uint8Array, assetId: u128 | AnyNumber | Uint8Array, action: PalletMultiAssetDelegationRewardsAssetAction | 'Add' | 'Remove' | number | Uint8Array) => SubmittableExtrinsic, [u128, u128, PalletMultiAssetDelegationRewardsAssetAction]>; + manageAssetInVault: AugmentedSubmittable<(vaultId: u128 | AnyNumber | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, action: PalletMultiAssetDelegationRewardsAssetAction | 'Add' | 'Remove' | number | Uint8Array) => SubmittableExtrinsic, [u128, TanglePrimitivesServicesAsset, PalletMultiAssetDelegationRewardsAssetAction]>; /** * Allows an operator to increase their stake. **/ @@ -2383,7 +2383,7 @@ declare module '@polkadot/api-base/types/submittable' { /** * Schedules a request to reduce a delegator's stake. **/ - scheduleDelegatorUnstake: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [AccountId32, u128, u128]>; + scheduleDelegatorUnstake: AugmentedSubmittable<(operator: AccountId32 | string | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [AccountId32, TanglePrimitivesServicesAsset, u128]>; /** * Schedules an operator to leave. **/ @@ -2395,7 +2395,7 @@ declare module '@polkadot/api-base/types/submittable' { /** * Schedules an withdraw request. **/ - scheduleWithdraw: AugmentedSubmittable<(assetId: u128 | AnyNumber | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u128, u128]>; + scheduleWithdraw: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128]>; /** * Sets the APY and cap for a specific asset. * The APY is the annual percentage yield that the asset will earn. @@ -3143,7 +3143,8 @@ declare module '@polkadot/api-base/types/submittable' { /** * Dispute an [UnappliedSlash] for a given era and index. * - * The caller needs to be an authorized Dispute Origin for the service in the [UnappliedSlash]. + * The caller needs to be an authorized Dispute Origin for the service in the + * [UnappliedSlash]. **/ dispute: AugmentedSubmittable<(era: Compact | AnyNumber | Uint8Array, index: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Compact, Compact]>; /** @@ -3173,16 +3174,17 @@ declare module '@polkadot/api-base/types/submittable' { reject: AugmentedSubmittable<(requestId: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Compact]>; /** * Request a new service to be initiated using the provided blueprint with a list of - * operators that will run your service. Optionally, you can specifiy who is permitted + * operators that will run your service. Optionally, you can customize who is permitted * caller of this service, by default only the caller is allowed to call the service. **/ - request: AugmentedSubmittable<(blueprintId: Compact | AnyNumber | Uint8Array, permittedCallers: Vec | (AccountId32 | string | Uint8Array)[], operators: Vec | (AccountId32 | string | Uint8Array)[], requestArgs: Vec | (TanglePrimitivesServicesField | { None: any } | { Bool: any } | { Uint8: any } | { Int8: any } | { Uint16: any } | { Int16: any } | { Uint32: any } | { Int32: any } | { Uint64: any } | { Int64: any } | { String: any } | { Bytes: any } | { Array: any } | { List: any } | { Struct: any } | { AccountId: any } | string | Uint8Array)[], assets: Vec | (u128 | AnyNumber | Uint8Array)[], ttl: Compact | AnyNumber | Uint8Array, value: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Compact, Vec, Vec, Vec, Vec, Compact, Compact]>; + request: AugmentedSubmittable<(evmOrigin: Option | null | Uint8Array | H160 | string, blueprintId: Compact | AnyNumber | Uint8Array, permittedCallers: Vec | (AccountId32 | string | Uint8Array)[], operators: Vec | (AccountId32 | string | Uint8Array)[], requestArgs: Vec | (TanglePrimitivesServicesField | { None: any } | { Bool: any } | { Uint8: any } | { Int8: any } | { Uint16: any } | { Int16: any } | { Uint32: any } | { Int32: any } | { Uint64: any } | { Int64: any } | { String: any } | { Bytes: any } | { Array: any } | { List: any } | { Struct: any } | { AccountId: any } | string | Uint8Array)[], assets: Vec | (u128 | AnyNumber | Uint8Array)[], ttl: Compact | AnyNumber | Uint8Array, paymentAsset: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, value: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Option, Compact, Vec, Vec, Vec, Vec, Compact, TanglePrimitivesServicesAsset, Compact]>; /** - * Slash an operator (offender) for a service id with a given percent of their exposed stake for that service. + * Slash an operator (offender) for a service id with a given percent of their exposed + * stake for that service. * * The caller needs to be an authorized Slash Origin for this service. - * Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash - * by another entity. + * Note that this does not apply the slash directly, but instead schedules a deferred call + * to apply the slash by another entity. **/ slash: AugmentedSubmittable<(offender: AccountId32 | string | Uint8Array, serviceId: Compact | AnyNumber | Uint8Array, percent: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [AccountId32, Compact, Compact]>; /** @@ -3201,6 +3203,11 @@ declare module '@polkadot/api-base/types/submittable' { * and slashed. **/ unregister: AugmentedSubmittable<(blueprintId: Compact | AnyNumber | Uint8Array) => SubmittableExtrinsic, [Compact]>; + /** + * Adds a new Master Blueprint Service Manager to the list of revisions. + * + * The caller needs to be an authorized Master Blueprint Service Manager Update Origin. + **/ updateMasterBlueprintServiceManager: AugmentedSubmittable<(address: H160 | string | Uint8Array) => SubmittableExtrinsic, [H160]>; /** * Update the price targets for the caller for a specific service blueprint. diff --git a/types/src/interfaces/lookup.ts b/types/src/interfaces/lookup.ts index 8b425998..4312efab 100644 --- a/types/src/interfaces/lookup.ts +++ b/types/src/interfaces/lookup.ts @@ -1549,12 +1549,12 @@ export default { Deposited: { who: 'AccountId32', amount: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', }, Scheduledwithdraw: { who: 'AccountId32', amount: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', }, Executedwithdraw: { who: 'AccountId32', @@ -1566,13 +1566,13 @@ export default { who: 'AccountId32', operator: 'AccountId32', amount: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', }, ScheduledDelegatorBondLess: { who: 'AccountId32', operator: 'AccountId32', amount: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', }, ExecutedDelegatorBondLess: { who: 'AccountId32', @@ -1591,7 +1591,7 @@ export default { AssetUpdatedInVault: { who: 'AccountId32', vaultId: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', action: 'PalletMultiAssetDelegationRewardsAssetAction', }, OperatorSlashed: { @@ -1600,18 +1600,33 @@ export default { }, DelegatorSlashed: { who: 'AccountId32', - amount: 'u128' + amount: 'u128', + }, + EvmReverted: { + from: 'H160', + to: 'H160', + data: 'Bytes', + reason: 'Bytes' } } }, /** - * Lookup125: pallet_multi_asset_delegation::types::rewards::AssetAction + * Lookup124: tangle_primitives::services::Asset + **/ + TanglePrimitivesServicesAsset: { + _enum: { + Custom: 'u128', + Erc20: 'H160' + } + }, + /** + * Lookup126: pallet_multi_asset_delegation::types::rewards::AssetAction **/ PalletMultiAssetDelegationRewardsAssetAction: { _enum: ['Add', 'Remove'] }, /** - * Lookup126: pallet_services::module::Event + * Lookup127: pallet_services::module::Event **/ PalletServicesModuleEvent: { _enum: { @@ -1713,14 +1728,14 @@ export default { } }, /** - * Lookup127: tangle_primitives::services::OperatorPreferences + * Lookup128: tangle_primitives::services::OperatorPreferences **/ TanglePrimitivesServicesOperatorPreferences: { key: '[u8;33]', priceTargets: 'TanglePrimitivesServicesPriceTargets' }, /** - * Lookup129: tangle_primitives::services::PriceTargets + * Lookup130: tangle_primitives::services::PriceTargets **/ TanglePrimitivesServicesPriceTargets: { cpu: 'u64', @@ -1730,7 +1745,7 @@ export default { storageNvme: 'u64' }, /** - * Lookup131: tangle_primitives::services::field::Field + * Lookup132: tangle_primitives::services::field::Field **/ TanglePrimitivesServicesField: { _enum: { @@ -1838,7 +1853,7 @@ export default { } }, /** - * Lookup144: pallet_tangle_lst::pallet::Event + * Lookup145: pallet_tangle_lst::pallet::Event **/ PalletTangleLstEvent: { _enum: { @@ -1926,20 +1941,20 @@ export default { } }, /** - * Lookup145: pallet_tangle_lst::types::pools::PoolState + * Lookup146: pallet_tangle_lst::types::pools::PoolState **/ PalletTangleLstPoolsPoolState: { _enum: ['Open', 'Blocked', 'Destroying'] }, /** - * Lookup146: pallet_tangle_lst::types::commission::CommissionChangeRate + * Lookup147: pallet_tangle_lst::types::commission::CommissionChangeRate **/ PalletTangleLstCommissionCommissionChangeRate: { maxIncrease: 'Perbill', minDelay: 'u64' }, /** - * Lookup148: pallet_tangle_lst::types::commission::CommissionClaimPermission + * Lookup149: pallet_tangle_lst::types::commission::CommissionClaimPermission **/ PalletTangleLstCommissionCommissionClaimPermission: { _enum: { @@ -1948,7 +1963,7 @@ export default { } }, /** - * Lookup149: frame_system::Phase + * Lookup150: frame_system::Phase **/ FrameSystemPhase: { _enum: { @@ -1958,21 +1973,21 @@ export default { } }, /** - * Lookup151: frame_system::LastRuntimeUpgradeInfo + * Lookup152: frame_system::LastRuntimeUpgradeInfo **/ FrameSystemLastRuntimeUpgradeInfo: { specVersion: 'Compact', specName: 'Text' }, /** - * Lookup153: frame_system::CodeUpgradeAuthorization + * Lookup154: frame_system::CodeUpgradeAuthorization **/ FrameSystemCodeUpgradeAuthorization: { codeHash: 'H256', checkVersion: 'bool' }, /** - * Lookup154: frame_system::pallet::Call + * Lookup155: frame_system::pallet::Call **/ FrameSystemCall: { _enum: { @@ -2017,7 +2032,7 @@ export default { } }, /** - * Lookup158: frame_system::limits::BlockWeights + * Lookup159: frame_system::limits::BlockWeights **/ FrameSystemLimitsBlockWeights: { baseBlock: 'SpWeightsWeightV2Weight', @@ -2025,7 +2040,7 @@ export default { perClass: 'FrameSupportDispatchPerDispatchClassWeightsPerClass' }, /** - * Lookup159: frame_support::dispatch::PerDispatchClass + * Lookup160: frame_support::dispatch::PerDispatchClass **/ FrameSupportDispatchPerDispatchClassWeightsPerClass: { normal: 'FrameSystemLimitsWeightsPerClass', @@ -2033,7 +2048,7 @@ export default { mandatory: 'FrameSystemLimitsWeightsPerClass' }, /** - * Lookup160: frame_system::limits::WeightsPerClass + * Lookup161: frame_system::limits::WeightsPerClass **/ FrameSystemLimitsWeightsPerClass: { baseExtrinsic: 'SpWeightsWeightV2Weight', @@ -2042,13 +2057,13 @@ export default { reserved: 'Option' }, /** - * Lookup162: frame_system::limits::BlockLength + * Lookup163: frame_system::limits::BlockLength **/ FrameSystemLimitsBlockLength: { max: 'FrameSupportDispatchPerDispatchClassU32' }, /** - * Lookup163: frame_support::dispatch::PerDispatchClass + * Lookup164: frame_support::dispatch::PerDispatchClass **/ FrameSupportDispatchPerDispatchClassU32: { normal: 'u32', @@ -2056,14 +2071,14 @@ export default { mandatory: 'u32' }, /** - * Lookup164: sp_weights::RuntimeDbWeight + * Lookup165: sp_weights::RuntimeDbWeight **/ SpWeightsRuntimeDbWeight: { read: 'u64', write: 'u64' }, /** - * Lookup165: sp_version::RuntimeVersion + * Lookup166: sp_version::RuntimeVersion **/ SpVersionRuntimeVersion: { specName: 'Text', @@ -2076,13 +2091,13 @@ export default { stateVersion: 'u8' }, /** - * Lookup170: frame_system::pallet::Error + * Lookup171: frame_system::pallet::Error **/ FrameSystemError: { _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered', 'MultiBlockMigrationsOngoing', 'NothingAuthorized', 'Unauthorized'] }, /** - * Lookup171: pallet_timestamp::pallet::Call + * Lookup172: pallet_timestamp::pallet::Call **/ PalletTimestampCall: { _enum: { @@ -2092,7 +2107,7 @@ export default { } }, /** - * Lookup172: pallet_sudo::pallet::Call + * Lookup173: pallet_sudo::pallet::Call **/ PalletSudoCall: { _enum: { @@ -2117,7 +2132,7 @@ export default { } }, /** - * Lookup174: pallet_assets::pallet::Call + * Lookup175: pallet_assets::pallet::Call **/ PalletAssetsCall: { _enum: { @@ -2269,7 +2284,7 @@ export default { } }, /** - * Lookup176: pallet_balances::pallet::Call + * Lookup177: pallet_balances::pallet::Call **/ PalletBalancesCall: { _enum: { @@ -2314,13 +2329,13 @@ export default { } }, /** - * Lookup177: pallet_balances::types::AdjustmentDirection + * Lookup178: pallet_balances::types::AdjustmentDirection **/ PalletBalancesAdjustmentDirection: { _enum: ['Increase', 'Decrease'] }, /** - * Lookup178: pallet_babe::pallet::Call + * Lookup179: pallet_babe::pallet::Call **/ PalletBabeCall: { _enum: { @@ -2338,7 +2353,7 @@ export default { } }, /** - * Lookup179: sp_consensus_slots::EquivocationProof, sp_consensus_babe::app::Public> + * Lookup180: sp_consensus_slots::EquivocationProof, sp_consensus_babe::app::Public> **/ SpConsensusSlotsEquivocationProof: { offender: 'SpConsensusBabeAppPublic', @@ -2347,7 +2362,7 @@ export default { secondHeader: 'SpRuntimeHeader' }, /** - * Lookup180: sp_runtime::generic::header::Header + * Lookup181: sp_runtime::generic::header::Header **/ SpRuntimeHeader: { parentHash: 'H256', @@ -2357,11 +2372,11 @@ export default { digest: 'SpRuntimeDigest' }, /** - * Lookup181: sp_consensus_babe::app::Public + * Lookup182: sp_consensus_babe::app::Public **/ SpConsensusBabeAppPublic: '[u8;32]', /** - * Lookup183: sp_session::MembershipProof + * Lookup184: sp_session::MembershipProof **/ SpSessionMembershipProof: { session: 'u32', @@ -2369,7 +2384,7 @@ export default { validatorCount: 'u32' }, /** - * Lookup184: sp_consensus_babe::digests::NextConfigDescriptor + * Lookup185: sp_consensus_babe::digests::NextConfigDescriptor **/ SpConsensusBabeDigestsNextConfigDescriptor: { _enum: { @@ -2381,13 +2396,13 @@ export default { } }, /** - * Lookup186: sp_consensus_babe::AllowedSlots + * Lookup187: sp_consensus_babe::AllowedSlots **/ SpConsensusBabeAllowedSlots: { _enum: ['PrimarySlots', 'PrimaryAndSecondaryPlainSlots', 'PrimaryAndSecondaryVRFSlots'] }, /** - * Lookup187: pallet_grandpa::pallet::Call + * Lookup188: pallet_grandpa::pallet::Call **/ PalletGrandpaCall: { _enum: { @@ -2406,14 +2421,14 @@ export default { } }, /** - * Lookup188: sp_consensus_grandpa::EquivocationProof + * Lookup189: sp_consensus_grandpa::EquivocationProof **/ SpConsensusGrandpaEquivocationProof: { setId: 'u64', equivocation: 'SpConsensusGrandpaEquivocation' }, /** - * Lookup189: sp_consensus_grandpa::Equivocation + * Lookup190: sp_consensus_grandpa::Equivocation **/ SpConsensusGrandpaEquivocation: { _enum: { @@ -2422,7 +2437,7 @@ export default { } }, /** - * Lookup190: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> + * Lookup191: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> **/ FinalityGrandpaEquivocationPrevote: { roundNumber: 'u64', @@ -2431,18 +2446,18 @@ export default { second: '(FinalityGrandpaPrevote,SpConsensusGrandpaAppSignature)' }, /** - * Lookup191: finality_grandpa::Prevote + * Lookup192: finality_grandpa::Prevote **/ FinalityGrandpaPrevote: { targetHash: 'H256', targetNumber: 'u64' }, /** - * Lookup192: sp_consensus_grandpa::app::Signature + * Lookup193: sp_consensus_grandpa::app::Signature **/ SpConsensusGrandpaAppSignature: '[u8;64]', /** - * Lookup195: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> + * Lookup196: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> **/ FinalityGrandpaEquivocationPrecommit: { roundNumber: 'u64', @@ -2451,18 +2466,18 @@ export default { second: '(FinalityGrandpaPrecommit,SpConsensusGrandpaAppSignature)' }, /** - * Lookup196: finality_grandpa::Precommit + * Lookup197: finality_grandpa::Precommit **/ FinalityGrandpaPrecommit: { targetHash: 'H256', targetNumber: 'u64' }, /** - * Lookup198: sp_core::Void + * Lookup199: sp_core::Void **/ SpCoreVoid: 'Null', /** - * Lookup199: pallet_indices::pallet::Call + * Lookup200: pallet_indices::pallet::Call **/ PalletIndicesCall: { _enum: { @@ -2493,7 +2508,7 @@ export default { } }, /** - * Lookup200: pallet_democracy::pallet::Call + * Lookup201: pallet_democracy::pallet::Call **/ PalletDemocracyCall: { _enum: { @@ -2562,7 +2577,7 @@ export default { } }, /** - * Lookup201: frame_support::traits::preimages::Bounded + * Lookup202: frame_support::traits::preimages::Bounded **/ FrameSupportPreimagesBounded: { _enum: { @@ -2583,17 +2598,17 @@ export default { } }, /** - * Lookup202: sp_runtime::traits::BlakeTwo256 + * Lookup203: sp_runtime::traits::BlakeTwo256 **/ SpRuntimeBlakeTwo256: 'Null', /** - * Lookup204: pallet_democracy::conviction::Conviction + * Lookup205: pallet_democracy::conviction::Conviction **/ PalletDemocracyConviction: { _enum: ['None', 'Locked1x', 'Locked2x', 'Locked3x', 'Locked4x', 'Locked5x', 'Locked6x'] }, /** - * Lookup207: pallet_collective::pallet::Call + * Lookup208: pallet_collective::pallet::Call **/ PalletCollectiveCall: { _enum: { @@ -2629,7 +2644,7 @@ export default { } }, /** - * Lookup208: pallet_vesting::pallet::Call + * Lookup209: pallet_vesting::pallet::Call **/ PalletVestingCall: { _enum: { @@ -2657,7 +2672,7 @@ export default { } }, /** - * Lookup209: pallet_vesting::vesting_info::VestingInfo + * Lookup210: pallet_vesting::vesting_info::VestingInfo **/ PalletVestingVestingInfo: { locked: 'u128', @@ -2665,7 +2680,7 @@ export default { startingBlock: 'u64' }, /** - * Lookup210: pallet_elections_phragmen::pallet::Call + * Lookup211: pallet_elections_phragmen::pallet::Call **/ PalletElectionsPhragmenCall: { _enum: { @@ -2692,7 +2707,7 @@ export default { } }, /** - * Lookup211: pallet_elections_phragmen::Renouncing + * Lookup212: pallet_elections_phragmen::Renouncing **/ PalletElectionsPhragmenRenouncing: { _enum: { @@ -2702,7 +2717,7 @@ export default { } }, /** - * Lookup212: pallet_election_provider_multi_phase::pallet::Call + * Lookup213: pallet_election_provider_multi_phase::pallet::Call **/ PalletElectionProviderMultiPhaseCall: { _enum: { @@ -2726,7 +2741,7 @@ export default { } }, /** - * Lookup213: pallet_election_provider_multi_phase::RawSolution + * Lookup214: pallet_election_provider_multi_phase::RawSolution **/ PalletElectionProviderMultiPhaseRawSolution: { solution: 'TangleTestnetRuntimeNposSolution16', @@ -2734,7 +2749,7 @@ export default { round: 'u32' }, /** - * Lookup214: tangle_testnet_runtime::NposSolution16 + * Lookup215: tangle_testnet_runtime::NposSolution16 **/ TangleTestnetRuntimeNposSolution16: { votes1: 'Vec<(Compact,Compact)>', @@ -2755,21 +2770,21 @@ export default { votes16: 'Vec<(Compact,[(Compact,Compact);15],Compact)>' }, /** - * Lookup265: pallet_election_provider_multi_phase::SolutionOrSnapshotSize + * Lookup266: pallet_election_provider_multi_phase::SolutionOrSnapshotSize **/ PalletElectionProviderMultiPhaseSolutionOrSnapshotSize: { voters: 'Compact', targets: 'Compact' }, /** - * Lookup269: sp_npos_elections::Support + * Lookup270: sp_npos_elections::Support **/ SpNposElectionsSupport: { total: 'u128', voters: 'Vec<(AccountId32,u128)>' }, /** - * Lookup270: pallet_staking::pallet::pallet::Call + * Lookup271: pallet_staking::pallet::pallet::Call **/ PalletStakingPalletCall: { _enum: { @@ -2878,7 +2893,7 @@ export default { } }, /** - * Lookup273: pallet_staking::pallet::pallet::ConfigOp + * Lookup274: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpU128: { _enum: { @@ -2888,7 +2903,7 @@ export default { } }, /** - * Lookup274: pallet_staking::pallet::pallet::ConfigOp + * Lookup275: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpU32: { _enum: { @@ -2898,7 +2913,7 @@ export default { } }, /** - * Lookup275: pallet_staking::pallet::pallet::ConfigOp + * Lookup276: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpPercent: { _enum: { @@ -2908,7 +2923,7 @@ export default { } }, /** - * Lookup276: pallet_staking::pallet::pallet::ConfigOp + * Lookup277: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpPerbill: { _enum: { @@ -2918,14 +2933,14 @@ export default { } }, /** - * Lookup281: pallet_staking::UnlockChunk + * Lookup282: pallet_staking::UnlockChunk **/ PalletStakingUnlockChunk: { value: 'Compact', era: 'Compact' }, /** - * Lookup283: pallet_session::pallet::Call + * Lookup284: pallet_session::pallet::Call **/ PalletSessionCall: { _enum: { @@ -2940,7 +2955,7 @@ export default { } }, /** - * Lookup284: tangle_testnet_runtime::opaque::SessionKeys + * Lookup285: tangle_testnet_runtime::opaque::SessionKeys **/ TangleTestnetRuntimeOpaqueSessionKeys: { babe: 'SpConsensusBabeAppPublic', @@ -2948,7 +2963,7 @@ export default { imOnline: 'PalletImOnlineSr25519AppSr25519Public' }, /** - * Lookup285: pallet_treasury::pallet::Call + * Lookup286: pallet_treasury::pallet::Call **/ PalletTreasuryCall: { _enum: { @@ -2980,7 +2995,7 @@ export default { } }, /** - * Lookup287: pallet_bounties::pallet::Call + * Lookup288: pallet_bounties::pallet::Call **/ PalletBountiesCall: { _enum: { @@ -3019,7 +3034,7 @@ export default { } }, /** - * Lookup288: pallet_child_bounties::pallet::Call + * Lookup289: pallet_child_bounties::pallet::Call **/ PalletChildBountiesCall: { _enum: { @@ -3058,7 +3073,7 @@ export default { } }, /** - * Lookup289: pallet_bags_list::pallet::Call + * Lookup290: pallet_bags_list::pallet::Call **/ PalletBagsListCall: { _enum: { @@ -3075,7 +3090,7 @@ export default { } }, /** - * Lookup290: pallet_nomination_pools::pallet::Call + * Lookup291: pallet_nomination_pools::pallet::Call **/ PalletNominationPoolsCall: { _enum: { @@ -3185,7 +3200,7 @@ export default { } }, /** - * Lookup291: pallet_nomination_pools::BondExtra + * Lookup292: pallet_nomination_pools::BondExtra **/ PalletNominationPoolsBondExtra: { _enum: { @@ -3194,7 +3209,7 @@ export default { } }, /** - * Lookup292: pallet_nomination_pools::ConfigOp + * Lookup293: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpU128: { _enum: { @@ -3204,7 +3219,7 @@ export default { } }, /** - * Lookup293: pallet_nomination_pools::ConfigOp + * Lookup294: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpU32: { _enum: { @@ -3214,7 +3229,7 @@ export default { } }, /** - * Lookup294: pallet_nomination_pools::ConfigOp + * Lookup295: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpPerbill: { _enum: { @@ -3224,7 +3239,7 @@ export default { } }, /** - * Lookup295: pallet_nomination_pools::ConfigOp + * Lookup296: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpAccountId32: { _enum: { @@ -3234,13 +3249,13 @@ export default { } }, /** - * Lookup296: pallet_nomination_pools::ClaimPermission + * Lookup297: pallet_nomination_pools::ClaimPermission **/ PalletNominationPoolsClaimPermission: { _enum: ['Permissioned', 'PermissionlessCompound', 'PermissionlessWithdraw', 'PermissionlessAll'] }, /** - * Lookup297: pallet_scheduler::pallet::Call + * Lookup298: pallet_scheduler::pallet::Call **/ PalletSchedulerCall: { _enum: { @@ -3296,7 +3311,7 @@ export default { } }, /** - * Lookup299: pallet_preimage::pallet::Call + * Lookup300: pallet_preimage::pallet::Call **/ PalletPreimageCall: { _enum: { @@ -3327,7 +3342,7 @@ export default { } }, /** - * Lookup300: pallet_tx_pause::pallet::Call + * Lookup301: pallet_tx_pause::pallet::Call **/ PalletTxPauseCall: { _enum: { @@ -3340,7 +3355,7 @@ export default { } }, /** - * Lookup301: pallet_im_online::pallet::Call + * Lookup302: pallet_im_online::pallet::Call **/ PalletImOnlineCall: { _enum: { @@ -3351,7 +3366,7 @@ export default { } }, /** - * Lookup302: pallet_im_online::Heartbeat + * Lookup303: pallet_im_online::Heartbeat **/ PalletImOnlineHeartbeat: { blockNumber: 'u64', @@ -3360,11 +3375,11 @@ export default { validatorsLen: 'u32' }, /** - * Lookup303: pallet_im_online::sr25519::app_sr25519::Signature + * Lookup304: pallet_im_online::sr25519::app_sr25519::Signature **/ PalletImOnlineSr25519AppSr25519Signature: '[u8;64]', /** - * Lookup304: pallet_identity::pallet::Call + * Lookup305: pallet_identity::pallet::Call **/ PalletIdentityCall: { _enum: { @@ -3449,7 +3464,7 @@ export default { } }, /** - * Lookup305: pallet_identity::legacy::IdentityInfo + * Lookup306: pallet_identity::legacy::IdentityInfo **/ PalletIdentityLegacyIdentityInfo: { additional: 'Vec<(Data,Data)>', @@ -3463,7 +3478,7 @@ export default { twitter: 'Data' }, /** - * Lookup341: pallet_identity::types::Judgement + * Lookup342: pallet_identity::types::Judgement **/ PalletIdentityJudgement: { _enum: { @@ -3477,7 +3492,7 @@ export default { } }, /** - * Lookup343: sp_runtime::MultiSignature + * Lookup344: sp_runtime::MultiSignature **/ SpRuntimeMultiSignature: { _enum: { @@ -3487,7 +3502,7 @@ export default { } }, /** - * Lookup345: pallet_utility::pallet::Call + * Lookup346: pallet_utility::pallet::Call **/ PalletUtilityCall: { _enum: { @@ -3515,7 +3530,7 @@ export default { } }, /** - * Lookup347: tangle_testnet_runtime::OriginCaller + * Lookup348: tangle_testnet_runtime::OriginCaller **/ TangleTestnetRuntimeOriginCaller: { _enum: { @@ -3556,7 +3571,7 @@ export default { } }, /** - * Lookup348: frame_support::dispatch::RawOrigin + * Lookup349: frame_support::dispatch::RawOrigin **/ FrameSupportDispatchRawOrigin: { _enum: { @@ -3566,7 +3581,7 @@ export default { } }, /** - * Lookup349: pallet_collective::RawOrigin + * Lookup350: pallet_collective::RawOrigin **/ PalletCollectiveRawOrigin: { _enum: { @@ -3576,7 +3591,7 @@ export default { } }, /** - * Lookup350: pallet_ethereum::RawOrigin + * Lookup351: pallet_ethereum::RawOrigin **/ PalletEthereumRawOrigin: { _enum: { @@ -3584,7 +3599,7 @@ export default { } }, /** - * Lookup351: pallet_multisig::pallet::Call + * Lookup352: pallet_multisig::pallet::Call **/ PalletMultisigCall: { _enum: { @@ -3615,7 +3630,7 @@ export default { } }, /** - * Lookup353: pallet_ethereum::pallet::Call + * Lookup354: pallet_ethereum::pallet::Call **/ PalletEthereumCall: { _enum: { @@ -3625,7 +3640,7 @@ export default { } }, /** - * Lookup354: ethereum::transaction::TransactionV2 + * Lookup355: ethereum::transaction::TransactionV2 **/ EthereumTransactionTransactionV2: { _enum: { @@ -3635,7 +3650,7 @@ export default { } }, /** - * Lookup355: ethereum::transaction::LegacyTransaction + * Lookup356: ethereum::transaction::LegacyTransaction **/ EthereumTransactionLegacyTransaction: { nonce: 'U256', @@ -3647,7 +3662,7 @@ export default { signature: 'EthereumTransactionTransactionSignature' }, /** - * Lookup356: ethereum::transaction::TransactionAction + * Lookup357: ethereum::transaction::TransactionAction **/ EthereumTransactionTransactionAction: { _enum: { @@ -3656,7 +3671,7 @@ export default { } }, /** - * Lookup357: ethereum::transaction::TransactionSignature + * Lookup358: ethereum::transaction::TransactionSignature **/ EthereumTransactionTransactionSignature: { v: 'u64', @@ -3664,7 +3679,7 @@ export default { s: 'H256' }, /** - * Lookup359: ethereum::transaction::EIP2930Transaction + * Lookup360: ethereum::transaction::EIP2930Transaction **/ EthereumTransactionEip2930Transaction: { chainId: 'u64', @@ -3680,14 +3695,14 @@ export default { s: 'H256' }, /** - * Lookup361: ethereum::transaction::AccessListItem + * Lookup362: ethereum::transaction::AccessListItem **/ EthereumTransactionAccessListItem: { address: 'H160', storageKeys: 'Vec' }, /** - * Lookup362: ethereum::transaction::EIP1559Transaction + * Lookup363: ethereum::transaction::EIP1559Transaction **/ EthereumTransactionEip1559Transaction: { chainId: 'u64', @@ -3704,7 +3719,7 @@ export default { s: 'H256' }, /** - * Lookup363: pallet_evm::pallet::Call + * Lookup364: pallet_evm::pallet::Call **/ PalletEvmCall: { _enum: { @@ -3747,7 +3762,7 @@ export default { } }, /** - * Lookup367: pallet_dynamic_fee::pallet::Call + * Lookup368: pallet_dynamic_fee::pallet::Call **/ PalletDynamicFeeCall: { _enum: { @@ -3757,7 +3772,7 @@ export default { } }, /** - * Lookup368: pallet_base_fee::pallet::Call + * Lookup369: pallet_base_fee::pallet::Call **/ PalletBaseFeeCall: { _enum: { @@ -3770,7 +3785,7 @@ export default { } }, /** - * Lookup369: pallet_hotfix_sufficients::pallet::Call + * Lookup370: pallet_hotfix_sufficients::pallet::Call **/ PalletHotfixSufficientsCall: { _enum: { @@ -3780,7 +3795,7 @@ export default { } }, /** - * Lookup371: pallet_airdrop_claims::pallet::Call + * Lookup372: pallet_airdrop_claims::pallet::Call **/ PalletAirdropClaimsCall: { _enum: { @@ -3819,7 +3834,7 @@ export default { } }, /** - * Lookup373: pallet_airdrop_claims::utils::MultiAddressSignature + * Lookup374: pallet_airdrop_claims::utils::MultiAddressSignature **/ PalletAirdropClaimsUtilsMultiAddressSignature: { _enum: { @@ -3828,21 +3843,21 @@ export default { } }, /** - * Lookup374: pallet_airdrop_claims::utils::ethereum_address::EcdsaSignature + * Lookup375: pallet_airdrop_claims::utils::ethereum_address::EcdsaSignature **/ PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature: '[u8;65]', /** - * Lookup375: pallet_airdrop_claims::utils::Sr25519Signature + * Lookup376: pallet_airdrop_claims::utils::Sr25519Signature **/ PalletAirdropClaimsUtilsSr25519Signature: '[u8;64]', /** - * Lookup381: pallet_airdrop_claims::StatementKind + * Lookup382: pallet_airdrop_claims::StatementKind **/ PalletAirdropClaimsStatementKind: { _enum: ['Regular', 'Safe'] }, /** - * Lookup382: pallet_proxy::pallet::Call + * Lookup383: pallet_proxy::pallet::Call **/ PalletProxyCall: { _enum: { @@ -3895,7 +3910,7 @@ export default { } }, /** - * Lookup384: pallet_multi_asset_delegation::pallet::Call + * Lookup385: pallet_multi_asset_delegation::pallet::Call **/ PalletMultiAssetDelegationCall: { _enum: { @@ -3916,33 +3931,36 @@ export default { go_offline: 'Null', go_online: 'Null', deposit: { - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', + evmAddress: 'Option', }, schedule_withdraw: { - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', }, - execute_withdraw: 'Null', + execute_withdraw: { + evmAddress: 'Option', + }, cancel_withdraw: { - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', }, delegate: { operator: 'AccountId32', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', blueprintSelection: 'PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection', }, schedule_delegator_unstake: { operator: 'AccountId32', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', }, execute_delegator_unstake: 'Null', cancel_delegator_unstake: { operator: 'AccountId32', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', }, set_incentive_apy_and_cap: { @@ -3955,7 +3973,7 @@ export default { }, manage_asset_in_vault: { vaultId: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', action: 'PalletMultiAssetDelegationRewardsAssetAction', }, __Unused21: 'Null', @@ -3968,7 +3986,7 @@ export default { } }, /** - * Lookup385: pallet_multi_asset_delegation::types::delegator::DelegatorBlueprintSelection + * Lookup387: pallet_multi_asset_delegation::types::delegator::DelegatorBlueprintSelection **/ PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection: { _enum: { @@ -3977,11 +3995,11 @@ export default { } }, /** - * Lookup386: tangle_testnet_runtime::MaxDelegatorBlueprints + * Lookup388: tangle_testnet_runtime::MaxDelegatorBlueprints **/ TangleTestnetRuntimeMaxDelegatorBlueprints: 'Null', /** - * Lookup389: pallet_services::module::Call + * Lookup391: pallet_services::module::Call **/ PalletServicesModuleCall: { _enum: { @@ -4005,12 +4023,14 @@ export default { priceTargets: 'TanglePrimitivesServicesPriceTargets', }, request: { + evmOrigin: 'Option', blueprintId: 'Compact', permittedCallers: 'Vec', operators: 'Vec', requestArgs: 'Vec', assets: 'Vec', ttl: 'Compact', + paymentAsset: 'TanglePrimitivesServicesAsset', value: 'Compact', }, approve: { @@ -4048,7 +4068,7 @@ export default { } }, /** - * Lookup390: tangle_primitives::services::ServiceBlueprint + * Lookup392: tangle_primitives::services::ServiceBlueprint **/ TanglePrimitivesServicesServiceBlueprint: { metadata: 'TanglePrimitivesServicesServiceMetadata', @@ -4060,7 +4080,7 @@ export default { gadget: 'TanglePrimitivesServicesGadget' }, /** - * Lookup391: tangle_primitives::services::ServiceMetadata + * Lookup393: tangle_primitives::services::ServiceMetadata **/ TanglePrimitivesServicesServiceMetadata: { name: 'Bytes', @@ -4073,7 +4093,7 @@ export default { license: 'Option' }, /** - * Lookup396: tangle_primitives::services::JobDefinition + * Lookup398: tangle_primitives::services::JobDefinition **/ TanglePrimitivesServicesJobDefinition: { metadata: 'TanglePrimitivesServicesJobMetadata', @@ -4081,14 +4101,14 @@ export default { result: 'Vec' }, /** - * Lookup397: tangle_primitives::services::JobMetadata + * Lookup399: tangle_primitives::services::JobMetadata **/ TanglePrimitivesServicesJobMetadata: { name: 'Bytes', description: 'Option' }, /** - * Lookup399: tangle_primitives::services::field::FieldType + * Lookup401: tangle_primitives::services::field::FieldType **/ TanglePrimitivesServicesFieldFieldType: { _enum: { @@ -4196,7 +4216,7 @@ export default { } }, /** - * Lookup405: tangle_primitives::services::BlueprintServiceManager + * Lookup407: tangle_primitives::services::BlueprintServiceManager **/ TanglePrimitivesServicesBlueprintServiceManager: { _enum: { @@ -4204,7 +4224,7 @@ export default { } }, /** - * Lookup406: tangle_primitives::services::MasterBlueprintServiceManagerRevision + * Lookup408: tangle_primitives::services::MasterBlueprintServiceManagerRevision **/ TanglePrimitivesServicesMasterBlueprintServiceManagerRevision: { _enum: { @@ -4213,7 +4233,7 @@ export default { } }, /** - * Lookup407: tangle_primitives::services::Gadget + * Lookup409: tangle_primitives::services::Gadget **/ TanglePrimitivesServicesGadget: { _enum: { @@ -4223,26 +4243,26 @@ export default { } }, /** - * Lookup408: tangle_primitives::services::WasmGadget + * Lookup410: tangle_primitives::services::WasmGadget **/ TanglePrimitivesServicesWasmGadget: { runtime: 'TanglePrimitivesServicesWasmRuntime', sources: 'Vec' }, /** - * Lookup409: tangle_primitives::services::WasmRuntime + * Lookup411: tangle_primitives::services::WasmRuntime **/ TanglePrimitivesServicesWasmRuntime: { _enum: ['Wasmtime', 'Wasmer'] }, /** - * Lookup411: tangle_primitives::services::GadgetSource + * Lookup413: tangle_primitives::services::GadgetSource **/ TanglePrimitivesServicesGadgetSource: { fetcher: 'TanglePrimitivesServicesGadgetSourceFetcher' }, /** - * Lookup412: tangle_primitives::services::GadgetSourceFetcher + * Lookup414: tangle_primitives::services::GadgetSourceFetcher **/ TanglePrimitivesServicesGadgetSourceFetcher: { _enum: { @@ -4253,7 +4273,7 @@ export default { } }, /** - * Lookup414: tangle_primitives::services::GithubFetcher + * Lookup416: tangle_primitives::services::GithubFetcher **/ TanglePrimitivesServicesGithubFetcher: { owner: 'Bytes', @@ -4262,7 +4282,7 @@ export default { binaries: 'Vec' }, /** - * Lookup422: tangle_primitives::services::GadgetBinary + * Lookup424: tangle_primitives::services::GadgetBinary **/ TanglePrimitivesServicesGadgetBinary: { arch: 'TanglePrimitivesServicesArchitecture', @@ -4271,19 +4291,19 @@ export default { sha256: '[u8;32]' }, /** - * Lookup423: tangle_primitives::services::Architecture + * Lookup425: tangle_primitives::services::Architecture **/ TanglePrimitivesServicesArchitecture: { _enum: ['Wasm', 'Wasm64', 'Wasi', 'Wasi64', 'Amd', 'Amd64', 'Arm', 'Arm64', 'RiscV', 'RiscV64'] }, /** - * Lookup424: tangle_primitives::services::OperatingSystem + * Lookup426: tangle_primitives::services::OperatingSystem **/ TanglePrimitivesServicesOperatingSystem: { _enum: ['Unknown', 'Linux', 'Windows', 'MacOS', 'BSD'] }, /** - * Lookup428: tangle_primitives::services::ImageRegistryFetcher + * Lookup430: tangle_primitives::services::ImageRegistryFetcher **/ TanglePrimitivesServicesImageRegistryFetcher: { _alias: { @@ -4294,7 +4314,7 @@ export default { tag: 'Bytes' }, /** - * Lookup435: tangle_primitives::services::TestFetcher + * Lookup437: tangle_primitives::services::TestFetcher **/ TanglePrimitivesServicesTestFetcher: { cargoPackage: 'Bytes', @@ -4302,19 +4322,19 @@ export default { basePath: 'Bytes' }, /** - * Lookup437: tangle_primitives::services::NativeGadget + * Lookup439: tangle_primitives::services::NativeGadget **/ TanglePrimitivesServicesNativeGadget: { sources: 'Vec' }, /** - * Lookup438: tangle_primitives::services::ContainerGadget + * Lookup440: tangle_primitives::services::ContainerGadget **/ TanglePrimitivesServicesContainerGadget: { sources: 'Vec' }, /** - * Lookup441: pallet_tangle_lst::pallet::Call + * Lookup443: pallet_tangle_lst::pallet::Call **/ PalletTangleLstCall: { _enum: { @@ -4417,7 +4437,7 @@ export default { } }, /** - * Lookup442: pallet_tangle_lst::types::BondExtra + * Lookup444: pallet_tangle_lst::types::BondExtra **/ PalletTangleLstBondExtra: { _enum: { @@ -4425,7 +4445,7 @@ export default { } }, /** - * Lookup447: pallet_tangle_lst::types::ConfigOp + * Lookup449: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpU128: { _enum: { @@ -4435,7 +4455,7 @@ export default { } }, /** - * Lookup448: pallet_tangle_lst::types::ConfigOp + * Lookup450: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpU32: { _enum: { @@ -4445,7 +4465,7 @@ export default { } }, /** - * Lookup449: pallet_tangle_lst::types::ConfigOp + * Lookup451: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpPerbill: { _enum: { @@ -4455,7 +4475,7 @@ export default { } }, /** - * Lookup450: pallet_tangle_lst::types::ConfigOp + * Lookup452: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpAccountId32: { _enum: { @@ -4465,13 +4485,13 @@ export default { } }, /** - * Lookup451: pallet_sudo::pallet::Error + * Lookup453: pallet_sudo::pallet::Error **/ PalletSudoError: { _enum: ['RequireSudo'] }, /** - * Lookup453: pallet_assets::types::AssetDetails + * Lookup455: pallet_assets::types::AssetDetails **/ PalletAssetsAssetDetails: { owner: 'AccountId32', @@ -4488,13 +4508,13 @@ export default { status: 'PalletAssetsAssetStatus' }, /** - * Lookup454: pallet_assets::types::AssetStatus + * Lookup456: pallet_assets::types::AssetStatus **/ PalletAssetsAssetStatus: { _enum: ['Live', 'Frozen', 'Destroying'] }, /** - * Lookup456: pallet_assets::types::AssetAccount + * Lookup458: pallet_assets::types::AssetAccount **/ PalletAssetsAssetAccount: { balance: 'u128', @@ -4503,13 +4523,13 @@ export default { extra: 'Null' }, /** - * Lookup457: pallet_assets::types::AccountStatus + * Lookup459: pallet_assets::types::AccountStatus **/ PalletAssetsAccountStatus: { _enum: ['Liquid', 'Frozen', 'Blocked'] }, /** - * Lookup458: pallet_assets::types::ExistenceReason + * Lookup460: pallet_assets::types::ExistenceReason **/ PalletAssetsExistenceReason: { _enum: { @@ -4521,14 +4541,14 @@ export default { } }, /** - * Lookup460: pallet_assets::types::Approval + * Lookup462: pallet_assets::types::Approval **/ PalletAssetsApproval: { amount: 'u128', deposit: 'u128' }, /** - * Lookup461: pallet_assets::types::AssetMetadata> + * Lookup463: pallet_assets::types::AssetMetadata> **/ PalletAssetsAssetMetadata: { deposit: 'u128', @@ -4538,13 +4558,13 @@ export default { isFrozen: 'bool' }, /** - * Lookup463: pallet_assets::pallet::Error + * Lookup465: pallet_assets::pallet::Error **/ PalletAssetsError: { _enum: ['BalanceLow', 'NoAccount', 'NoPermission', 'Unknown', 'Frozen', 'InUse', 'BadWitness', 'MinBalanceZero', 'UnavailableConsumer', 'BadMetadata', 'Unapproved', 'WouldDie', 'AlreadyExists', 'NoDeposit', 'WouldBurn', 'LiveAsset', 'AssetNotLive', 'IncorrectStatus', 'NotFrozen', 'CallbackFailed', 'BadAssetId'] }, /** - * Lookup465: pallet_balances::types::BalanceLock + * Lookup467: pallet_balances::types::BalanceLock **/ PalletBalancesBalanceLock: { id: '[u8;8]', @@ -4552,27 +4572,27 @@ export default { reasons: 'PalletBalancesReasons' }, /** - * Lookup466: pallet_balances::types::Reasons + * Lookup468: pallet_balances::types::Reasons **/ PalletBalancesReasons: { _enum: ['Fee', 'Misc', 'All'] }, /** - * Lookup469: pallet_balances::types::ReserveData + * Lookup471: pallet_balances::types::ReserveData **/ PalletBalancesReserveData: { id: '[u8;8]', amount: 'u128' }, /** - * Lookup472: frame_support::traits::tokens::misc::IdAmount + * Lookup474: frame_support::traits::tokens::misc::IdAmount **/ FrameSupportTokensMiscIdAmountRuntimeHoldReason: { id: 'TangleTestnetRuntimeRuntimeHoldReason', amount: 'u128' }, /** - * Lookup473: tangle_testnet_runtime::RuntimeHoldReason + * Lookup475: tangle_testnet_runtime::RuntimeHoldReason **/ TangleTestnetRuntimeRuntimeHoldReason: { _enum: { @@ -4606,20 +4626,20 @@ export default { } }, /** - * Lookup474: pallet_preimage::pallet::HoldReason + * Lookup476: pallet_preimage::pallet::HoldReason **/ PalletPreimageHoldReason: { _enum: ['Preimage'] }, /** - * Lookup477: frame_support::traits::tokens::misc::IdAmount + * Lookup479: frame_support::traits::tokens::misc::IdAmount **/ FrameSupportTokensMiscIdAmountRuntimeFreezeReason: { id: 'TangleTestnetRuntimeRuntimeFreezeReason', amount: 'u128' }, /** - * Lookup478: tangle_testnet_runtime::RuntimeFreezeReason + * Lookup480: tangle_testnet_runtime::RuntimeFreezeReason **/ TangleTestnetRuntimeRuntimeFreezeReason: { _enum: { @@ -4679,31 +4699,31 @@ export default { } }, /** - * Lookup479: pallet_nomination_pools::pallet::FreezeReason + * Lookup481: pallet_nomination_pools::pallet::FreezeReason **/ PalletNominationPoolsFreezeReason: { _enum: ['PoolMinBalance'] }, /** - * Lookup480: pallet_tangle_lst::pallet::FreezeReason + * Lookup482: pallet_tangle_lst::pallet::FreezeReason **/ PalletTangleLstFreezeReason: { _enum: ['PoolMinBalance'] }, /** - * Lookup482: pallet_balances::pallet::Error + * Lookup484: pallet_balances::pallet::Error **/ PalletBalancesError: { _enum: ['VestingBalance', 'LiquidityRestrictions', 'InsufficientBalance', 'ExistentialDeposit', 'Expendability', 'ExistingVestingSchedule', 'DeadAccount', 'TooManyReserves', 'TooManyHolds', 'TooManyFreezes', 'IssuanceDeactivated', 'DeltaZero'] }, /** - * Lookup484: pallet_transaction_payment::Releases + * Lookup486: pallet_transaction_payment::Releases **/ PalletTransactionPaymentReleases: { _enum: ['V1Ancient', 'V2'] }, /** - * Lookup491: sp_consensus_babe::digests::PreDigest + * Lookup493: sp_consensus_babe::digests::PreDigest **/ SpConsensusBabeDigestsPreDigest: { _enum: { @@ -4714,7 +4734,7 @@ export default { } }, /** - * Lookup492: sp_consensus_babe::digests::PrimaryPreDigest + * Lookup494: sp_consensus_babe::digests::PrimaryPreDigest **/ SpConsensusBabeDigestsPrimaryPreDigest: { authorityIndex: 'u32', @@ -4722,21 +4742,21 @@ export default { vrfSignature: 'SpCoreSr25519VrfVrfSignature' }, /** - * Lookup493: sp_core::sr25519::vrf::VrfSignature + * Lookup495: sp_core::sr25519::vrf::VrfSignature **/ SpCoreSr25519VrfVrfSignature: { preOutput: '[u8;32]', proof: '[u8;64]' }, /** - * Lookup494: sp_consensus_babe::digests::SecondaryPlainPreDigest + * Lookup496: sp_consensus_babe::digests::SecondaryPlainPreDigest **/ SpConsensusBabeDigestsSecondaryPlainPreDigest: { authorityIndex: 'u32', slot: 'u64' }, /** - * Lookup495: sp_consensus_babe::digests::SecondaryVRFPreDigest + * Lookup497: sp_consensus_babe::digests::SecondaryVRFPreDigest **/ SpConsensusBabeDigestsSecondaryVRFPreDigest: { authorityIndex: 'u32', @@ -4744,20 +4764,20 @@ export default { vrfSignature: 'SpCoreSr25519VrfVrfSignature' }, /** - * Lookup496: sp_consensus_babe::BabeEpochConfiguration + * Lookup498: sp_consensus_babe::BabeEpochConfiguration **/ SpConsensusBabeBabeEpochConfiguration: { c: '(u64,u64)', allowedSlots: 'SpConsensusBabeAllowedSlots' }, /** - * Lookup498: pallet_babe::pallet::Error + * Lookup500: pallet_babe::pallet::Error **/ PalletBabeError: { _enum: ['InvalidEquivocationProof', 'InvalidKeyOwnershipProof', 'DuplicateOffenceReport', 'InvalidConfiguration'] }, /** - * Lookup499: pallet_grandpa::StoredState + * Lookup501: pallet_grandpa::StoredState **/ PalletGrandpaStoredState: { _enum: { @@ -4774,7 +4794,7 @@ export default { } }, /** - * Lookup500: pallet_grandpa::StoredPendingChange + * Lookup502: pallet_grandpa::StoredPendingChange **/ PalletGrandpaStoredPendingChange: { scheduledAt: 'u64', @@ -4783,19 +4803,19 @@ export default { forced: 'Option' }, /** - * Lookup502: pallet_grandpa::pallet::Error + * Lookup504: pallet_grandpa::pallet::Error **/ PalletGrandpaError: { _enum: ['PauseFailed', 'ResumeFailed', 'ChangePending', 'TooSoon', 'InvalidKeyOwnershipProof', 'InvalidEquivocationProof', 'DuplicateOffenceReport'] }, /** - * Lookup504: pallet_indices::pallet::Error + * Lookup506: pallet_indices::pallet::Error **/ PalletIndicesError: { _enum: ['NotAssigned', 'NotOwner', 'InUse', 'NotTransfer', 'Permanent'] }, /** - * Lookup509: pallet_democracy::types::ReferendumInfo, Balance> + * Lookup511: pallet_democracy::types::ReferendumInfo, Balance> **/ PalletDemocracyReferendumInfo: { _enum: { @@ -4807,7 +4827,7 @@ export default { } }, /** - * Lookup510: pallet_democracy::types::ReferendumStatus, Balance> + * Lookup512: pallet_democracy::types::ReferendumStatus, Balance> **/ PalletDemocracyReferendumStatus: { end: 'u64', @@ -4817,7 +4837,7 @@ export default { tally: 'PalletDemocracyTally' }, /** - * Lookup511: pallet_democracy::types::Tally + * Lookup513: pallet_democracy::types::Tally **/ PalletDemocracyTally: { ayes: 'u128', @@ -4825,7 +4845,7 @@ export default { turnout: 'u128' }, /** - * Lookup512: pallet_democracy::vote::Voting + * Lookup514: pallet_democracy::vote::Voting **/ PalletDemocracyVoteVoting: { _enum: { @@ -4844,24 +4864,24 @@ export default { } }, /** - * Lookup516: pallet_democracy::types::Delegations + * Lookup518: pallet_democracy::types::Delegations **/ PalletDemocracyDelegations: { votes: 'u128', capital: 'u128' }, /** - * Lookup517: pallet_democracy::vote::PriorLock + * Lookup519: pallet_democracy::vote::PriorLock **/ PalletDemocracyVotePriorLock: '(u64,u128)', /** - * Lookup520: pallet_democracy::pallet::Error + * Lookup522: pallet_democracy::pallet::Error **/ PalletDemocracyError: { _enum: ['ValueLow', 'ProposalMissing', 'AlreadyCanceled', 'DuplicateProposal', 'ProposalBlacklisted', 'NotSimpleMajority', 'InvalidHash', 'NoProposal', 'AlreadyVetoed', 'ReferendumInvalid', 'NoneWaiting', 'NotVoter', 'NoPermission', 'AlreadyDelegating', 'InsufficientFunds', 'NotDelegating', 'VotesExist', 'InstantNotAllowed', 'Nonsense', 'WrongUpperBound', 'MaxVotesReached', 'TooMany', 'VotingPeriodLow', 'PreimageNotExist'] }, /** - * Lookup522: pallet_collective::Votes + * Lookup524: pallet_collective::Votes **/ PalletCollectiveVotes: { index: 'u32', @@ -4871,25 +4891,25 @@ export default { end: 'u64' }, /** - * Lookup523: pallet_collective::pallet::Error + * Lookup525: pallet_collective::pallet::Error **/ PalletCollectiveError: { _enum: ['NotMember', 'DuplicateProposal', 'ProposalMissing', 'WrongIndex', 'DuplicateVote', 'AlreadyInitialized', 'TooEarly', 'TooManyProposals', 'WrongProposalWeight', 'WrongProposalLength', 'PrimeAccountNotMember'] }, /** - * Lookup526: pallet_vesting::Releases + * Lookup528: pallet_vesting::Releases **/ PalletVestingReleases: { _enum: ['V0', 'V1'] }, /** - * Lookup527: pallet_vesting::pallet::Error + * Lookup529: pallet_vesting::pallet::Error **/ PalletVestingError: { _enum: ['NotVesting', 'AtMaxVestingSchedules', 'AmountLow', 'ScheduleIndexOutOfBounds', 'InvalidScheduleParams'] }, /** - * Lookup529: pallet_elections_phragmen::SeatHolder + * Lookup531: pallet_elections_phragmen::SeatHolder **/ PalletElectionsPhragmenSeatHolder: { who: 'AccountId32', @@ -4897,7 +4917,7 @@ export default { deposit: 'u128' }, /** - * Lookup530: pallet_elections_phragmen::Voter + * Lookup532: pallet_elections_phragmen::Voter **/ PalletElectionsPhragmenVoter: { votes: 'Vec', @@ -4905,13 +4925,13 @@ export default { deposit: 'u128' }, /** - * Lookup531: pallet_elections_phragmen::pallet::Error + * Lookup533: pallet_elections_phragmen::pallet::Error **/ PalletElectionsPhragmenError: { _enum: ['UnableToVote', 'NoVotes', 'TooManyVotes', 'MaximumVotesExceeded', 'LowBalance', 'UnableToPayBond', 'MustBeVoter', 'DuplicatedCandidate', 'TooManyCandidates', 'MemberSubmit', 'RunnerUpSubmit', 'InsufficientCandidateFunds', 'NotMember', 'InvalidWitnessData', 'InvalidVoteCount', 'InvalidRenouncing', 'InvalidReplacement'] }, /** - * Lookup532: pallet_election_provider_multi_phase::ReadySolution + * Lookup534: pallet_election_provider_multi_phase::ReadySolution **/ PalletElectionProviderMultiPhaseReadySolution: { supports: 'Vec<(AccountId32,SpNposElectionsSupport)>', @@ -4919,14 +4939,14 @@ export default { compute: 'PalletElectionProviderMultiPhaseElectionCompute' }, /** - * Lookup534: pallet_election_provider_multi_phase::RoundSnapshot + * Lookup536: pallet_election_provider_multi_phase::RoundSnapshot **/ PalletElectionProviderMultiPhaseRoundSnapshot: { voters: 'Vec<(AccountId32,u64,Vec)>', targets: 'Vec' }, /** - * Lookup541: pallet_election_provider_multi_phase::signed::SignedSubmission + * Lookup543: pallet_election_provider_multi_phase::signed::SignedSubmission **/ PalletElectionProviderMultiPhaseSignedSignedSubmission: { who: 'AccountId32', @@ -4935,13 +4955,13 @@ export default { callFee: 'u128' }, /** - * Lookup542: pallet_election_provider_multi_phase::pallet::Error + * Lookup544: pallet_election_provider_multi_phase::pallet::Error **/ PalletElectionProviderMultiPhaseError: { _enum: ['PreDispatchEarlySubmission', 'PreDispatchWrongWinnerCount', 'PreDispatchWeakSubmission', 'SignedQueueFull', 'SignedCannotPayDeposit', 'SignedInvalidWitness', 'SignedTooMuchWeight', 'OcwCallWrongEra', 'MissingSnapshotMetadata', 'InvalidSubmissionIndex', 'CallNotAllowed', 'FallbackFailed', 'BoundNotMet', 'TooManyWinners', 'PreDispatchDifferentRound'] }, /** - * Lookup543: pallet_staking::StakingLedger + * Lookup545: pallet_staking::StakingLedger **/ PalletStakingStakingLedger: { stash: 'AccountId32', @@ -4951,7 +4971,7 @@ export default { legacyClaimedRewards: 'Vec' }, /** - * Lookup545: pallet_staking::Nominations + * Lookup547: pallet_staking::Nominations **/ PalletStakingNominations: { targets: 'Vec', @@ -4959,14 +4979,14 @@ export default { suppressed: 'bool' }, /** - * Lookup546: pallet_staking::ActiveEraInfo + * Lookup548: pallet_staking::ActiveEraInfo **/ PalletStakingActiveEraInfo: { index: 'u32', start: 'Option' }, /** - * Lookup548: sp_staking::PagedExposureMetadata + * Lookup550: sp_staking::PagedExposureMetadata **/ SpStakingPagedExposureMetadata: { total: 'Compact', @@ -4975,21 +4995,21 @@ export default { pageCount: 'u32' }, /** - * Lookup550: sp_staking::ExposurePage + * Lookup552: sp_staking::ExposurePage **/ SpStakingExposurePage: { pageTotal: 'Compact', others: 'Vec' }, /** - * Lookup551: pallet_staking::EraRewardPoints + * Lookup553: pallet_staking::EraRewardPoints **/ PalletStakingEraRewardPoints: { total: 'u32', individual: 'BTreeMap' }, /** - * Lookup556: pallet_staking::UnappliedSlash + * Lookup558: pallet_staking::UnappliedSlash **/ PalletStakingUnappliedSlash: { validator: 'AccountId32', @@ -4999,7 +5019,7 @@ export default { payout: 'u128' }, /** - * Lookup560: pallet_staking::slashing::SlashingSpans + * Lookup562: pallet_staking::slashing::SlashingSpans **/ PalletStakingSlashingSlashingSpans: { spanIndex: 'u32', @@ -5008,30 +5028,30 @@ export default { prior: 'Vec' }, /** - * Lookup561: pallet_staking::slashing::SpanRecord + * Lookup563: pallet_staking::slashing::SpanRecord **/ PalletStakingSlashingSpanRecord: { slashed: 'u128', paidOut: 'u128' }, /** - * Lookup562: pallet_staking::pallet::pallet::Error + * Lookup564: pallet_staking::pallet::pallet::Error **/ PalletStakingPalletError: { _enum: ['NotController', 'NotStash', 'AlreadyBonded', 'AlreadyPaired', 'EmptyTargets', 'DuplicateIndex', 'InvalidSlashIndex', 'InsufficientBond', 'NoMoreChunks', 'NoUnlockChunk', 'FundedTarget', 'InvalidEraToReward', 'InvalidNumberOfNominations', 'NotSortedAndUnique', 'AlreadyClaimed', 'InvalidPage', 'IncorrectHistoryDepth', 'IncorrectSlashingSpans', 'BadState', 'TooManyTargets', 'BadTarget', 'CannotChillOther', 'TooManyNominators', 'TooManyValidators', 'CommissionTooLow', 'BoundNotMet', 'ControllerDeprecated', 'CannotRestoreLedger', 'RewardDestinationRestricted', 'NotEnoughFunds', 'VirtualStakerNotAllowed'] }, /** - * Lookup566: sp_core::crypto::KeyTypeId + * Lookup568: sp_core::crypto::KeyTypeId **/ SpCoreCryptoKeyTypeId: '[u8;4]', /** - * Lookup567: pallet_session::pallet::Error + * Lookup569: pallet_session::pallet::Error **/ PalletSessionError: { _enum: ['InvalidProof', 'NoAssociatedValidatorId', 'DuplicatedKey', 'NoKeys', 'NoAccount'] }, /** - * Lookup569: pallet_treasury::Proposal + * Lookup571: pallet_treasury::Proposal **/ PalletTreasuryProposal: { proposer: 'AccountId32', @@ -5040,7 +5060,7 @@ export default { bond: 'u128' }, /** - * Lookup571: pallet_treasury::SpendStatus + * Lookup573: pallet_treasury::SpendStatus **/ PalletTreasurySpendStatus: { assetKind: 'Null', @@ -5051,7 +5071,7 @@ export default { status: 'PalletTreasuryPaymentState' }, /** - * Lookup572: pallet_treasury::PaymentState + * Lookup574: pallet_treasury::PaymentState **/ PalletTreasuryPaymentState: { _enum: { @@ -5063,17 +5083,17 @@ export default { } }, /** - * Lookup573: frame_support::PalletId + * Lookup575: frame_support::PalletId **/ FrameSupportPalletId: '[u8;8]', /** - * Lookup574: pallet_treasury::pallet::Error + * Lookup576: pallet_treasury::pallet::Error **/ PalletTreasuryError: { _enum: ['InvalidIndex', 'TooManyApprovals', 'InsufficientPermission', 'ProposalNotApproved', 'FailedToConvertBalance', 'SpendExpired', 'EarlyPayout', 'AlreadyAttempted', 'PayoutError', 'NotAttempted', 'Inconclusive'] }, /** - * Lookup575: pallet_bounties::Bounty + * Lookup577: pallet_bounties::Bounty **/ PalletBountiesBounty: { proposer: 'AccountId32', @@ -5084,7 +5104,7 @@ export default { status: 'PalletBountiesBountyStatus' }, /** - * Lookup576: pallet_bounties::BountyStatus + * Lookup578: pallet_bounties::BountyStatus **/ PalletBountiesBountyStatus: { _enum: { @@ -5106,13 +5126,13 @@ export default { } }, /** - * Lookup578: pallet_bounties::pallet::Error + * Lookup580: pallet_bounties::pallet::Error **/ PalletBountiesError: { _enum: ['InsufficientProposersBalance', 'InvalidIndex', 'ReasonTooBig', 'UnexpectedStatus', 'RequireCurator', 'InvalidValue', 'InvalidFee', 'PendingPayout', 'Premature', 'HasActiveChildBounty', 'TooManyQueued'] }, /** - * Lookup579: pallet_child_bounties::ChildBounty + * Lookup581: pallet_child_bounties::ChildBounty **/ PalletChildBountiesChildBounty: { parentBounty: 'u32', @@ -5122,7 +5142,7 @@ export default { status: 'PalletChildBountiesChildBountyStatus' }, /** - * Lookup580: pallet_child_bounties::ChildBountyStatus + * Lookup582: pallet_child_bounties::ChildBountyStatus **/ PalletChildBountiesChildBountyStatus: { _enum: { @@ -5141,13 +5161,13 @@ export default { } }, /** - * Lookup581: pallet_child_bounties::pallet::Error + * Lookup583: pallet_child_bounties::pallet::Error **/ PalletChildBountiesError: { _enum: ['ParentBountyNotActive', 'InsufficientBountyBalance', 'TooManyChildBounties'] }, /** - * Lookup582: pallet_bags_list::list::Node + * Lookup584: pallet_bags_list::list::Node **/ PalletBagsListListNode: { id: 'AccountId32', @@ -5157,14 +5177,14 @@ export default { score: 'u64' }, /** - * Lookup583: pallet_bags_list::list::Bag + * Lookup585: pallet_bags_list::list::Bag **/ PalletBagsListListBag: { head: 'Option', tail: 'Option' }, /** - * Lookup584: pallet_bags_list::pallet::Error + * Lookup586: pallet_bags_list::pallet::Error **/ PalletBagsListError: { _enum: { @@ -5172,13 +5192,13 @@ export default { } }, /** - * Lookup585: pallet_bags_list::list::ListError + * Lookup587: pallet_bags_list::list::ListError **/ PalletBagsListListListError: { _enum: ['Duplicate', 'NotHeavier', 'NotInSameBag', 'NodeNotFound'] }, /** - * Lookup586: pallet_nomination_pools::PoolMember + * Lookup588: pallet_nomination_pools::PoolMember **/ PalletNominationPoolsPoolMember: { poolId: 'u32', @@ -5187,7 +5207,7 @@ export default { unbondingEras: 'BTreeMap' }, /** - * Lookup591: pallet_nomination_pools::BondedPoolInner + * Lookup593: pallet_nomination_pools::BondedPoolInner **/ PalletNominationPoolsBondedPoolInner: { commission: 'PalletNominationPoolsCommission', @@ -5197,7 +5217,7 @@ export default { state: 'PalletNominationPoolsPoolState' }, /** - * Lookup592: pallet_nomination_pools::Commission + * Lookup594: pallet_nomination_pools::Commission **/ PalletNominationPoolsCommission: { current: 'Option<(Perbill,AccountId32)>', @@ -5207,7 +5227,7 @@ export default { claimPermission: 'Option' }, /** - * Lookup595: pallet_nomination_pools::PoolRoles + * Lookup597: pallet_nomination_pools::PoolRoles **/ PalletNominationPoolsPoolRoles: { depositor: 'AccountId32', @@ -5216,7 +5236,7 @@ export default { bouncer: 'Option' }, /** - * Lookup596: pallet_nomination_pools::RewardPool + * Lookup598: pallet_nomination_pools::RewardPool **/ PalletNominationPoolsRewardPool: { lastRecordedRewardCounter: 'u128', @@ -5226,21 +5246,21 @@ export default { totalCommissionClaimed: 'u128' }, /** - * Lookup597: pallet_nomination_pools::SubPools + * Lookup599: pallet_nomination_pools::SubPools **/ PalletNominationPoolsSubPools: { noEra: 'PalletNominationPoolsUnbondPool', withEra: 'BTreeMap' }, /** - * Lookup598: pallet_nomination_pools::UnbondPool + * Lookup600: pallet_nomination_pools::UnbondPool **/ PalletNominationPoolsUnbondPool: { points: 'u128', balance: 'u128' }, /** - * Lookup603: pallet_nomination_pools::pallet::Error + * Lookup605: pallet_nomination_pools::pallet::Error **/ PalletNominationPoolsError: { _enum: { @@ -5283,13 +5303,13 @@ export default { } }, /** - * Lookup604: pallet_nomination_pools::pallet::DefensiveError + * Lookup606: pallet_nomination_pools::pallet::DefensiveError **/ PalletNominationPoolsDefensiveError: { _enum: ['NotEnoughSpaceInUnbondPool', 'PoolNotFound', 'RewardPoolNotFound', 'SubPoolsNotFound', 'BondedStashKilledPrematurely', 'DelegationUnsupported', 'SlashNotApplied'] }, /** - * Lookup607: pallet_scheduler::Scheduled, BlockNumber, tangle_testnet_runtime::OriginCaller, sp_core::crypto::AccountId32> + * Lookup609: pallet_scheduler::Scheduled, BlockNumber, tangle_testnet_runtime::OriginCaller, sp_core::crypto::AccountId32> **/ PalletSchedulerScheduled: { maybeId: 'Option<[u8;32]>', @@ -5299,7 +5319,7 @@ export default { origin: 'TangleTestnetRuntimeOriginCaller' }, /** - * Lookup609: pallet_scheduler::RetryConfig + * Lookup611: pallet_scheduler::RetryConfig **/ PalletSchedulerRetryConfig: { totalRetries: 'u8', @@ -5307,13 +5327,13 @@ export default { period: 'u64' }, /** - * Lookup610: pallet_scheduler::pallet::Error + * Lookup612: pallet_scheduler::pallet::Error **/ PalletSchedulerError: { _enum: ['FailedToSchedule', 'NotFound', 'TargetBlockNumberInPast', 'RescheduleNoChange', 'Named'] }, /** - * Lookup611: pallet_preimage::OldRequestStatus + * Lookup613: pallet_preimage::OldRequestStatus **/ PalletPreimageOldRequestStatus: { _enum: { @@ -5329,7 +5349,7 @@ export default { } }, /** - * Lookup613: pallet_preimage::RequestStatus + * Lookup615: pallet_preimage::RequestStatus **/ PalletPreimageRequestStatus: { _enum: { @@ -5345,32 +5365,32 @@ export default { } }, /** - * Lookup617: pallet_preimage::pallet::Error + * Lookup619: pallet_preimage::pallet::Error **/ PalletPreimageError: { _enum: ['TooBig', 'AlreadyNoted', 'NotAuthorized', 'NotNoted', 'Requested', 'NotRequested', 'TooMany', 'TooFew', 'NoCost'] }, /** - * Lookup618: sp_staking::offence::OffenceDetails + * Lookup620: sp_staking::offence::OffenceDetails **/ SpStakingOffenceOffenceDetails: { offender: '(AccountId32,SpStakingExposure)', reporters: 'Vec' }, /** - * Lookup620: pallet_tx_pause::pallet::Error + * Lookup622: pallet_tx_pause::pallet::Error **/ PalletTxPauseError: { _enum: ['IsPaused', 'IsUnpaused', 'Unpausable', 'NotFound'] }, /** - * Lookup623: pallet_im_online::pallet::Error + * Lookup625: pallet_im_online::pallet::Error **/ PalletImOnlineError: { _enum: ['InvalidKey', 'DuplicatedHeartbeat'] }, /** - * Lookup625: pallet_identity::types::Registration> + * Lookup627: pallet_identity::types::Registration> **/ PalletIdentityRegistration: { judgements: 'Vec<(u32,PalletIdentityJudgement)>', @@ -5378,7 +5398,7 @@ export default { info: 'PalletIdentityLegacyIdentityInfo' }, /** - * Lookup634: pallet_identity::types::RegistrarInfo + * Lookup636: pallet_identity::types::RegistrarInfo **/ PalletIdentityRegistrarInfo: { account: 'AccountId32', @@ -5386,26 +5406,26 @@ export default { fields: 'u64' }, /** - * Lookup636: pallet_identity::types::AuthorityProperties> + * Lookup638: pallet_identity::types::AuthorityProperties> **/ PalletIdentityAuthorityProperties: { suffix: 'Bytes', allocation: 'u32' }, /** - * Lookup639: pallet_identity::pallet::Error + * Lookup641: pallet_identity::pallet::Error **/ PalletIdentityError: { _enum: ['TooManySubAccounts', 'NotFound', 'NotNamed', 'EmptyIndex', 'FeeChanged', 'NoIdentity', 'StickyJudgement', 'JudgementGiven', 'InvalidJudgement', 'InvalidIndex', 'InvalidTarget', 'TooManyRegistrars', 'AlreadyClaimed', 'NotSub', 'NotOwned', 'JudgementForDifferentIdentity', 'JudgementPaymentFailed', 'InvalidSuffix', 'NotUsernameAuthority', 'NoAllocation', 'InvalidSignature', 'RequiresSignature', 'InvalidUsername', 'UsernameTaken', 'NoUsername', 'NotExpired'] }, /** - * Lookup640: pallet_utility::pallet::Error + * Lookup642: pallet_utility::pallet::Error **/ PalletUtilityError: { _enum: ['TooManyCalls'] }, /** - * Lookup642: pallet_multisig::Multisig + * Lookup644: pallet_multisig::Multisig **/ PalletMultisigMultisig: { when: 'PalletMultisigTimepoint', @@ -5414,13 +5434,13 @@ export default { approvals: 'Vec' }, /** - * Lookup643: pallet_multisig::pallet::Error + * Lookup645: pallet_multisig::pallet::Error **/ PalletMultisigError: { _enum: ['MinimumThreshold', 'AlreadyApproved', 'NoApprovalsNeeded', 'TooFewSignatories', 'TooManySignatories', 'SignatoriesOutOfOrder', 'SenderInSignatories', 'NotFound', 'NotOwner', 'NoTimepoint', 'WrongTimepoint', 'UnexpectedTimepoint', 'MaxWeightTooLow', 'AlreadyStored'] }, /** - * Lookup646: fp_rpc::TransactionStatus + * Lookup648: fp_rpc::TransactionStatus **/ FpRpcTransactionStatus: { transactionHash: 'H256', @@ -5432,11 +5452,11 @@ export default { logsBloom: 'EthbloomBloom' }, /** - * Lookup649: ethbloom::Bloom + * Lookup650: ethbloom::Bloom **/ EthbloomBloom: '[u8;256]', /** - * Lookup651: ethereum::receipt::ReceiptV3 + * Lookup652: ethereum::receipt::ReceiptV3 **/ EthereumReceiptReceiptV3: { _enum: { @@ -5446,7 +5466,7 @@ export default { } }, /** - * Lookup652: ethereum::receipt::EIP658ReceiptData + * Lookup653: ethereum::receipt::EIP658ReceiptData **/ EthereumReceiptEip658ReceiptData: { statusCode: 'u8', @@ -5455,7 +5475,7 @@ export default { logs: 'Vec' }, /** - * Lookup653: ethereum::block::Block + * Lookup654: ethereum::block::Block **/ EthereumBlock: { header: 'EthereumHeader', @@ -5463,7 +5483,7 @@ export default { ommers: 'Vec' }, /** - * Lookup654: ethereum::header::Header + * Lookup655: ethereum::header::Header **/ EthereumHeader: { parentHash: 'H256', @@ -5483,17 +5503,17 @@ export default { nonce: 'EthereumTypesHashH64' }, /** - * Lookup655: ethereum_types::hash::H64 + * Lookup656: ethereum_types::hash::H64 **/ EthereumTypesHashH64: '[u8;8]', /** - * Lookup660: pallet_ethereum::pallet::Error + * Lookup661: pallet_ethereum::pallet::Error **/ PalletEthereumError: { _enum: ['InvalidSignature', 'PreLogExists'] }, /** - * Lookup661: pallet_evm::CodeMetadata + * Lookup662: pallet_evm::CodeMetadata **/ PalletEvmCodeMetadata: { _alias: { @@ -5504,25 +5524,25 @@ export default { hash_: 'H256' }, /** - * Lookup663: pallet_evm::pallet::Error + * Lookup664: pallet_evm::pallet::Error **/ PalletEvmError: { _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce', 'GasLimitTooLow', 'GasLimitTooHigh', 'InvalidChainId', 'InvalidSignature', 'Reentrancy', 'TransactionMustComeFromEOA', 'Undefined'] }, /** - * Lookup664: pallet_hotfix_sufficients::pallet::Error + * Lookup665: pallet_hotfix_sufficients::pallet::Error **/ PalletHotfixSufficientsError: { _enum: ['MaxAddressCountExceeded'] }, /** - * Lookup666: pallet_airdrop_claims::pallet::Error + * Lookup667: pallet_airdrop_claims::pallet::Error **/ PalletAirdropClaimsError: { _enum: ['InvalidEthereumSignature', 'InvalidNativeSignature', 'InvalidNativeAccount', 'SignerHasNoClaim', 'SenderHasNoClaim', 'PotUnderflow', 'InvalidStatement', 'VestedBalanceExists'] }, /** - * Lookup669: pallet_proxy::ProxyDefinition + * Lookup670: pallet_proxy::ProxyDefinition **/ PalletProxyProxyDefinition: { delegate: 'AccountId32', @@ -5530,7 +5550,7 @@ export default { delay: 'u64' }, /** - * Lookup673: pallet_proxy::Announcement + * Lookup674: pallet_proxy::Announcement **/ PalletProxyAnnouncement: { real: 'AccountId32', @@ -5538,13 +5558,13 @@ export default { height: 'u64' }, /** - * Lookup675: pallet_proxy::pallet::Error + * Lookup676: pallet_proxy::pallet::Error **/ PalletProxyError: { _enum: ['TooMany', 'NotFound', 'NotProxy', 'Unproxyable', 'Duplicate', 'NoPermission', 'Unannounced', 'NoSelfProxy'] }, /** - * Lookup676: pallet_multi_asset_delegation::types::operator::OperatorMetadata + * Lookup677: pallet_multi_asset_delegation::types::operator::OperatorMetadata **/ PalletMultiAssetDelegationOperatorOperatorMetadata: { stake: 'u128', @@ -5555,30 +5575,30 @@ export default { blueprintIds: 'Vec' }, /** - * Lookup677: tangle_testnet_runtime::MaxDelegations + * Lookup678: tangle_testnet_runtime::MaxDelegations **/ TangleTestnetRuntimeMaxDelegations: 'Null', /** - * Lookup678: tangle_testnet_runtime::MaxOperatorBlueprints + * Lookup679: tangle_testnet_runtime::MaxOperatorBlueprints **/ TangleTestnetRuntimeMaxOperatorBlueprints: 'Null', /** - * Lookup680: pallet_multi_asset_delegation::types::operator::OperatorBondLessRequest + * Lookup681: pallet_multi_asset_delegation::types::operator::OperatorBondLessRequest **/ PalletMultiAssetDelegationOperatorOperatorBondLessRequest: { amount: 'u128', requestTime: 'u32' }, /** - * Lookup682: pallet_multi_asset_delegation::types::operator::DelegatorBond + * Lookup683: pallet_multi_asset_delegation::types::operator::DelegatorBond **/ PalletMultiAssetDelegationOperatorDelegatorBond: { delegator: 'AccountId32', amount: 'u128', - assetId: 'u128' + assetId: 'TanglePrimitivesServicesAsset' }, /** - * Lookup684: pallet_multi_asset_delegation::types::operator::OperatorStatus + * Lookup685: pallet_multi_asset_delegation::types::operator::OperatorStatus **/ PalletMultiAssetDelegationOperatorOperatorStatus: { _enum: { @@ -5588,59 +5608,59 @@ export default { } }, /** - * Lookup686: pallet_multi_asset_delegation::types::operator::OperatorSnapshot + * Lookup687: pallet_multi_asset_delegation::types::operator::OperatorSnapshot **/ PalletMultiAssetDelegationOperatorOperatorSnapshot: { stake: 'u128', delegations: 'Vec' }, /** - * Lookup687: pallet_multi_asset_delegation::types::delegator::DelegatorMetadata + * Lookup688: pallet_multi_asset_delegation::types::delegator::DelegatorMetadata **/ PalletMultiAssetDelegationDelegatorDelegatorMetadata: { - deposits: 'BTreeMap', + deposits: 'BTreeMap', withdrawRequests: 'Vec', delegations: 'Vec', delegatorUnstakeRequests: 'Vec', status: 'PalletMultiAssetDelegationDelegatorDelegatorStatus' }, /** - * Lookup688: tangle_testnet_runtime::MaxWithdrawRequests + * Lookup689: tangle_testnet_runtime::MaxWithdrawRequests **/ TangleTestnetRuntimeMaxWithdrawRequests: 'Null', /** - * Lookup689: tangle_testnet_runtime::MaxUnstakeRequests + * Lookup690: tangle_testnet_runtime::MaxUnstakeRequests **/ TangleTestnetRuntimeMaxUnstakeRequests: 'Null', /** - * Lookup694: pallet_multi_asset_delegation::types::delegator::WithdrawRequest + * Lookup695: pallet_multi_asset_delegation::types::delegator::WithdrawRequest **/ PalletMultiAssetDelegationDelegatorWithdrawRequest: { - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', requestedRound: 'u32' }, /** - * Lookup697: pallet_multi_asset_delegation::types::delegator::BondInfoDelegator + * Lookup698: pallet_multi_asset_delegation::types::delegator::BondInfoDelegator **/ PalletMultiAssetDelegationDelegatorBondInfoDelegator: { operator: 'AccountId32', amount: 'u128', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', blueprintSelection: 'PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection' }, /** - * Lookup700: pallet_multi_asset_delegation::types::delegator::BondLessRequest + * Lookup701: pallet_multi_asset_delegation::types::delegator::BondLessRequest **/ PalletMultiAssetDelegationDelegatorBondLessRequest: { operator: 'AccountId32', - assetId: 'u128', + assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', requestedRound: 'u32', blueprintSelection: 'PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection' }, /** - * Lookup702: pallet_multi_asset_delegation::types::delegator::DelegatorStatus + * Lookup703: pallet_multi_asset_delegation::types::delegator::DelegatorStatus **/ PalletMultiAssetDelegationDelegatorDelegatorStatus: { _enum: { @@ -5649,27 +5669,27 @@ export default { } }, /** - * Lookup703: pallet_multi_asset_delegation::types::rewards::RewardConfig + * Lookup705: pallet_multi_asset_delegation::types::rewards::RewardConfig **/ PalletMultiAssetDelegationRewardsRewardConfig: { configs: 'BTreeMap', whitelistedBlueprintIds: 'Vec' }, /** - * Lookup705: pallet_multi_asset_delegation::types::rewards::RewardConfigForAssetVault + * Lookup707: pallet_multi_asset_delegation::types::rewards::RewardConfigForAssetVault **/ PalletMultiAssetDelegationRewardsRewardConfigForAssetVault: { apy: 'Percent', cap: 'u128' }, /** - * Lookup708: pallet_multi_asset_delegation::pallet::Error + * Lookup710: pallet_multi_asset_delegation::pallet::Error **/ PalletMultiAssetDelegationError: { - _enum: ['AlreadyOperator', 'BondTooLow', 'NotAnOperator', 'CannotExit', 'AlreadyLeaving', 'NotLeavingOperator', 'NotLeavingRound', 'LeavingRoundNotReached', 'NoScheduledBondLess', 'BondLessRequestNotSatisfied', 'NotActiveOperator', 'NotOfflineOperator', 'AlreadyDelegator', 'NotDelegator', 'WithdrawRequestAlreadyExists', 'InsufficientBalance', 'NoWithdrawRequest', 'NoBondLessRequest', 'BondLessNotReady', 'BondLessRequestAlreadyExists', 'ActiveServicesUsingAsset', 'NoActiveDelegation', 'AssetNotWhitelisted', 'NotAuthorized', 'MaxBlueprintsExceeded', 'AssetNotFound', 'BlueprintAlreadyWhitelisted', 'NowithdrawRequests', 'NoMatchingwithdrawRequest', 'AssetAlreadyInVault', 'AssetNotInVault', 'VaultNotFound', 'DuplicateBlueprintId', 'BlueprintIdNotFound', 'NotInFixedMode', 'MaxDelegationsExceeded', 'MaxUnstakeRequestsExceeded', 'MaxWithdrawRequestsExceeded', 'DepositOverflow', 'UnstakeAmountTooLarge', 'StakeOverflow', 'InsufficientStakeRemaining', 'APYExceedsMaximum', 'CapCannotBeZero', 'CapExceedsTotalSupply', 'PendingUnstakeRequestExists', 'BlueprintNotSelected'] + _enum: ['AlreadyOperator', 'BondTooLow', 'NotAnOperator', 'CannotExit', 'AlreadyLeaving', 'NotLeavingOperator', 'NotLeavingRound', 'LeavingRoundNotReached', 'NoScheduledBondLess', 'BondLessRequestNotSatisfied', 'NotActiveOperator', 'NotOfflineOperator', 'AlreadyDelegator', 'NotDelegator', 'WithdrawRequestAlreadyExists', 'InsufficientBalance', 'NoWithdrawRequest', 'NoBondLessRequest', 'BondLessNotReady', 'BondLessRequestAlreadyExists', 'ActiveServicesUsingAsset', 'NoActiveDelegation', 'AssetNotWhitelisted', 'NotAuthorized', 'MaxBlueprintsExceeded', 'AssetNotFound', 'BlueprintAlreadyWhitelisted', 'NowithdrawRequests', 'NoMatchingwithdrawRequest', 'AssetAlreadyInVault', 'AssetNotInVault', 'VaultNotFound', 'DuplicateBlueprintId', 'BlueprintIdNotFound', 'NotInFixedMode', 'MaxDelegationsExceeded', 'MaxUnstakeRequestsExceeded', 'MaxWithdrawRequestsExceeded', 'DepositOverflow', 'UnstakeAmountTooLarge', 'StakeOverflow', 'InsufficientStakeRemaining', 'APYExceedsMaximum', 'CapCannotBeZero', 'CapExceedsTotalSupply', 'PendingUnstakeRequestExists', 'BlueprintNotSelected', 'ERC20TransferFailed', 'EVMAbiEncode', 'EVMAbiDecode'] }, /** - * Lookup711: tangle_primitives::services::ServiceRequest + * Lookup713: tangle_primitives::services::ServiceRequest **/ TanglePrimitivesServicesServiceRequest: { blueprint: 'u64', @@ -5681,7 +5701,7 @@ export default { operatorsWithApprovalState: 'Vec<(AccountId32,TanglePrimitivesServicesApprovalState)>' }, /** - * Lookup717: tangle_primitives::services::ApprovalState + * Lookup719: tangle_primitives::services::ApprovalState **/ TanglePrimitivesServicesApprovalState: { _enum: { @@ -5693,7 +5713,7 @@ export default { } }, /** - * Lookup719: tangle_primitives::services::Service + * Lookup721: tangle_primitives::services::Service **/ TanglePrimitivesServicesService: { id: 'u64', @@ -5705,7 +5725,7 @@ export default { ttl: 'u64' }, /** - * Lookup725: tangle_primitives::services::JobCall + * Lookup727: tangle_primitives::services::JobCall **/ TanglePrimitivesServicesJobCall: { serviceId: 'u64', @@ -5713,7 +5733,7 @@ export default { args: 'Vec' }, /** - * Lookup726: tangle_primitives::services::JobCallResult + * Lookup728: tangle_primitives::services::JobCallResult **/ TanglePrimitivesServicesJobCallResult: { serviceId: 'u64', @@ -5721,7 +5741,7 @@ export default { result: 'Vec' }, /** - * Lookup727: pallet_services::types::UnappliedSlash + * Lookup729: pallet_services::types::UnappliedSlash **/ PalletServicesUnappliedSlash: { serviceId: 'u64', @@ -5732,14 +5752,32 @@ export default { payout: 'u128' }, /** - * Lookup729: tangle_primitives::services::OperatorProfile + * Lookup731: tangle_primitives::services::OperatorProfile **/ TanglePrimitivesServicesOperatorProfile: { services: 'BTreeSet', blueprints: 'BTreeSet' }, /** - * Lookup732: pallet_services::module::Error + * Lookup734: tangle_primitives::services::StagingServicePayment + **/ + TanglePrimitivesServicesStagingServicePayment: { + requestId: 'u64', + refundTo: 'TanglePrimitivesAccount', + asset: 'TanglePrimitivesServicesAsset', + amount: 'u128' + }, + /** + * Lookup735: tangle_primitives::types::Account + **/ + TanglePrimitivesAccount: { + _enum: { + Id: 'AccountId32', + Address: 'H160' + } + }, + /** + * Lookup736: pallet_services::module::Error **/ PalletServicesModuleError: { _enum: { @@ -5781,11 +5819,15 @@ export default { NoDisputeOrigin: 'Null', UnappliedSlashNotFound: 'Null', MasterBlueprintServiceManagerRevisionNotFound: 'Null', - MaxMasterBlueprintServiceManagerVersionsExceeded: 'Null' + MaxMasterBlueprintServiceManagerVersionsExceeded: 'Null', + ERC20TransferFailed: 'Null', + MissingEVMOrigin: 'Null', + ExpectedEVMAddress: 'Null', + ExpectedAccountId: 'Null' } }, /** - * Lookup733: tangle_primitives::services::TypeCheckError + * Lookup737: tangle_primitives::services::TypeCheckError **/ TanglePrimitivesServicesTypeCheckError: { _enum: { @@ -5806,7 +5848,7 @@ export default { } }, /** - * Lookup734: pallet_tangle_lst::types::bonded_pool::BondedPoolInner + * Lookup738: pallet_tangle_lst::types::bonded_pool::BondedPoolInner **/ PalletTangleLstBondedPoolBondedPoolInner: { commission: 'PalletTangleLstCommission', @@ -5815,7 +5857,7 @@ export default { metadata: 'PalletTangleLstBondedPoolPoolMetadata' }, /** - * Lookup735: pallet_tangle_lst::types::commission::Commission + * Lookup739: pallet_tangle_lst::types::commission::Commission **/ PalletTangleLstCommission: { current: 'Option<(Perbill,AccountId32)>', @@ -5825,7 +5867,7 @@ export default { claimPermission: 'Option' }, /** - * Lookup737: pallet_tangle_lst::types::pools::PoolRoles + * Lookup741: pallet_tangle_lst::types::pools::PoolRoles **/ PalletTangleLstPoolsPoolRoles: { depositor: 'AccountId32', @@ -5834,14 +5876,14 @@ export default { bouncer: 'Option' }, /** - * Lookup738: pallet_tangle_lst::types::bonded_pool::PoolMetadata + * Lookup742: pallet_tangle_lst::types::bonded_pool::PoolMetadata **/ PalletTangleLstBondedPoolPoolMetadata: { name: 'Option', icon: 'Option' }, /** - * Lookup739: pallet_tangle_lst::types::sub_pools::RewardPool + * Lookup743: pallet_tangle_lst::types::sub_pools::RewardPool **/ PalletTangleLstSubPoolsRewardPool: { lastRecordedRewardCounter: 'u128', @@ -5851,33 +5893,33 @@ export default { totalCommissionClaimed: 'u128' }, /** - * Lookup740: pallet_tangle_lst::types::sub_pools::SubPools + * Lookup744: pallet_tangle_lst::types::sub_pools::SubPools **/ PalletTangleLstSubPools: { noEra: 'PalletTangleLstSubPoolsUnbondPool', withEra: 'BTreeMap' }, /** - * Lookup741: pallet_tangle_lst::types::sub_pools::UnbondPool + * Lookup745: pallet_tangle_lst::types::sub_pools::UnbondPool **/ PalletTangleLstSubPoolsUnbondPool: { points: 'u128', balance: 'u128' }, /** - * Lookup747: pallet_tangle_lst::types::pools::PoolMember + * Lookup751: pallet_tangle_lst::types::pools::PoolMember **/ PalletTangleLstPoolsPoolMember: { unbondingEras: 'BTreeMap' }, /** - * Lookup752: pallet_tangle_lst::types::ClaimPermission + * Lookup756: pallet_tangle_lst::types::ClaimPermission **/ PalletTangleLstClaimPermission: { _enum: ['Permissioned', 'PermissionlessCompound', 'PermissionlessWithdraw', 'PermissionlessAll'] }, /** - * Lookup753: pallet_tangle_lst::pallet::Error + * Lookup757: pallet_tangle_lst::pallet::Error **/ PalletTangleLstError: { _enum: { @@ -5917,53 +5959,53 @@ export default { } }, /** - * Lookup754: pallet_tangle_lst::pallet::DefensiveError + * Lookup758: pallet_tangle_lst::pallet::DefensiveError **/ PalletTangleLstDefensiveError: { _enum: ['NotEnoughSpaceInUnbondPool', 'PoolNotFound', 'RewardPoolNotFound', 'SubPoolsNotFound', 'BondedStashKilledPrematurely'] }, /** - * Lookup757: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender + * Lookup761: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender **/ FrameSystemExtensionsCheckNonZeroSender: 'Null', /** - * Lookup758: frame_system::extensions::check_spec_version::CheckSpecVersion + * Lookup762: frame_system::extensions::check_spec_version::CheckSpecVersion **/ FrameSystemExtensionsCheckSpecVersion: 'Null', /** - * Lookup759: frame_system::extensions::check_tx_version::CheckTxVersion + * Lookup763: frame_system::extensions::check_tx_version::CheckTxVersion **/ FrameSystemExtensionsCheckTxVersion: 'Null', /** - * Lookup760: frame_system::extensions::check_genesis::CheckGenesis + * Lookup764: frame_system::extensions::check_genesis::CheckGenesis **/ FrameSystemExtensionsCheckGenesis: 'Null', /** - * Lookup763: frame_system::extensions::check_nonce::CheckNonce + * Lookup767: frame_system::extensions::check_nonce::CheckNonce **/ FrameSystemExtensionsCheckNonce: 'Compact', /** - * Lookup764: frame_system::extensions::check_weight::CheckWeight + * Lookup768: frame_system::extensions::check_weight::CheckWeight **/ FrameSystemExtensionsCheckWeight: 'Null', /** - * Lookup765: pallet_transaction_payment::ChargeTransactionPayment + * Lookup769: pallet_transaction_payment::ChargeTransactionPayment **/ PalletTransactionPaymentChargeTransactionPayment: 'Compact', /** - * Lookup766: frame_metadata_hash_extension::CheckMetadataHash + * Lookup770: frame_metadata_hash_extension::CheckMetadataHash **/ FrameMetadataHashExtensionCheckMetadataHash: { mode: 'FrameMetadataHashExtensionMode' }, /** - * Lookup767: frame_metadata_hash_extension::Mode + * Lookup771: frame_metadata_hash_extension::Mode **/ FrameMetadataHashExtensionMode: { _enum: ['Disabled', 'Enabled'] }, /** - * Lookup769: tangle_testnet_runtime::Runtime + * Lookup773: tangle_testnet_runtime::Runtime **/ TangleTestnetRuntimeRuntime: 'Null' }; diff --git a/types/src/interfaces/registry.ts b/types/src/interfaces/registry.ts index 60cd613d..b821e16c 100644 --- a/types/src/interfaces/registry.ts +++ b/types/src/interfaces/registry.ts @@ -5,7 +5,7 @@ // this is required to allow for ambient/previous definitions import '@polkadot/types/types/registry'; -import type { EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FinalityGrandpaEquivocationPrecommit, FinalityGrandpaEquivocationPrevote, FinalityGrandpaPrecommit, FinalityGrandpaPrevote, FpRpcTransactionStatus, FrameMetadataHashExtensionCheckMetadataHash, FrameMetadataHashExtensionMode, FrameSupportDispatchDispatchClass, FrameSupportDispatchDispatchInfo, FrameSupportDispatchPays, FrameSupportDispatchPerDispatchClassU32, FrameSupportDispatchPerDispatchClassWeight, FrameSupportDispatchPerDispatchClassWeightsPerClass, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportPreimagesBounded, FrameSupportTokensMiscBalanceStatus, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCall, FrameSystemCodeUpgradeAuthorization, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonZeroSender, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckTxVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, PalletAirdropClaimsCall, PalletAirdropClaimsError, PalletAirdropClaimsEvent, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsEthereumAddress, PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletAirdropClaimsUtilsSr25519Signature, PalletAssetsAccountStatus, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAssetsAssetStatus, PalletAssetsCall, PalletAssetsError, PalletAssetsEvent, PalletAssetsExistenceReason, PalletBabeCall, PalletBabeError, PalletBagsListCall, PalletBagsListError, PalletBagsListEvent, PalletBagsListListBag, PalletBagsListListListError, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesAdjustmentDirection, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReserveData, PalletBaseFeeCall, PalletBaseFeeEvent, PalletBountiesBounty, PalletBountiesBountyStatus, PalletBountiesCall, PalletBountiesError, PalletBountiesEvent, PalletChildBountiesCall, PalletChildBountiesChildBounty, PalletChildBountiesChildBountyStatus, PalletChildBountiesError, PalletChildBountiesEvent, PalletCollectiveCall, PalletCollectiveError, PalletCollectiveEvent, PalletCollectiveRawOrigin, PalletCollectiveVotes, PalletDemocracyCall, PalletDemocracyConviction, PalletDemocracyDelegations, PalletDemocracyError, PalletDemocracyEvent, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyTally, PalletDemocracyVoteAccountVote, PalletDemocracyVotePriorLock, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletDynamicFeeCall, PalletElectionProviderMultiPhaseCall, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhaseError, PalletElectionProviderMultiPhaseEvent, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenCall, PalletElectionsPhragmenError, PalletElectionsPhragmenEvent, PalletElectionsPhragmenRenouncing, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumRawOrigin, PalletEvmCall, PalletEvmCodeMetadata, PalletEvmError, PalletEvmEvent, PalletGrandpaCall, PalletGrandpaError, PalletGrandpaEvent, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletHotfixSufficientsCall, PalletHotfixSufficientsError, PalletIdentityAuthorityProperties, PalletIdentityCall, PalletIdentityError, PalletIdentityEvent, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineCall, PalletImOnlineError, PalletImOnlineEvent, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Public, PalletImOnlineSr25519AppSr25519Signature, PalletIndicesCall, PalletIndicesError, PalletIndicesEvent, PalletMultiAssetDelegationCall, PalletMultiAssetDelegationDelegatorBondInfoDelegator, PalletMultiAssetDelegationDelegatorBondLessRequest, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationDelegatorDelegatorStatus, PalletMultiAssetDelegationDelegatorWithdrawRequest, PalletMultiAssetDelegationError, PalletMultiAssetDelegationEvent, PalletMultiAssetDelegationOperatorDelegatorBond, PalletMultiAssetDelegationOperatorOperatorBondLessRequest, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationOperatorOperatorStatus, PalletMultiAssetDelegationRewardsAssetAction, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultiAssetDelegationRewardsRewardConfigForAssetVault, PalletMultisigCall, PalletMultisigError, PalletMultisigEvent, PalletMultisigMultisig, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsCall, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsDefensiveError, PalletNominationPoolsError, PalletNominationPoolsEvent, PalletNominationPoolsFreezeReason, PalletNominationPoolsPoolMember, PalletNominationPoolsPoolRoles, PalletNominationPoolsPoolState, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletNominationPoolsUnbondPool, PalletOffencesEvent, PalletPreimageCall, PalletPreimageError, PalletPreimageEvent, PalletPreimageHoldReason, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyCall, PalletProxyError, PalletProxyEvent, PalletProxyProxyDefinition, PalletSchedulerCall, PalletSchedulerError, PalletSchedulerEvent, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesModuleCall, PalletServicesModuleError, PalletServicesModuleEvent, PalletServicesUnappliedSlash, PalletSessionCall, PalletSessionError, PalletSessionEvent, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingPalletCall, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingPalletError, PalletStakingPalletEvent, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTangleLstBondExtra, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstBondedPoolPoolMetadata, PalletTangleLstCall, PalletTangleLstClaimPermission, PalletTangleLstCommission, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstDefensiveError, PalletTangleLstError, PalletTangleLstEvent, PalletTangleLstFreezeReason, PalletTangleLstPoolsPoolMember, PalletTangleLstPoolsPoolRoles, PalletTangleLstPoolsPoolState, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTangleLstSubPoolsUnbondPool, PalletTimestampCall, PalletTransactionPaymentChargeTransactionPayment, PalletTransactionPaymentEvent, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryPaymentState, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletTxPauseCall, PalletTxPauseError, PalletTxPauseEvent, PalletUtilityCall, PalletUtilityError, PalletUtilityEvent, PalletVestingCall, PalletVestingError, PalletVestingEvent, PalletVestingReleases, PalletVestingVestingInfo, SpArithmeticArithmeticError, SpConsensusBabeAllowedSlots, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusBabeDigestsPrimaryPreDigest, SpConsensusBabeDigestsSecondaryPlainPreDigest, SpConsensusBabeDigestsSecondaryVRFPreDigest, SpConsensusGrandpaAppPublic, SpConsensusGrandpaAppSignature, SpConsensusGrandpaEquivocation, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreCryptoKeyTypeId, SpCoreSr25519VrfVrfSignature, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeBlakeTwo256, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeHeader, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpSessionMembershipProof, SpStakingExposure, SpStakingExposurePage, SpStakingIndividualExposure, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, SpVersionRuntimeVersion, SpWeightsRuntimeDbWeight, SpWeightsWeightV2Weight, TanglePrimitivesServicesApprovalState, TanglePrimitivesServicesArchitecture, TanglePrimitivesServicesBlueprintServiceManager, TanglePrimitivesServicesContainerGadget, TanglePrimitivesServicesField, TanglePrimitivesServicesFieldFieldType, TanglePrimitivesServicesGadget, TanglePrimitivesServicesGadgetBinary, TanglePrimitivesServicesGadgetSource, TanglePrimitivesServicesGadgetSourceFetcher, TanglePrimitivesServicesGithubFetcher, TanglePrimitivesServicesImageRegistryFetcher, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesJobDefinition, TanglePrimitivesServicesJobMetadata, TanglePrimitivesServicesMasterBlueprintServiceManagerRevision, TanglePrimitivesServicesNativeGadget, TanglePrimitivesServicesOperatingSystem, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceMetadata, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesTestFetcher, TanglePrimitivesServicesTypeCheckError, TanglePrimitivesServicesWasmGadget, TanglePrimitivesServicesWasmRuntime, TangleTestnetRuntimeMaxDelegations, TangleTestnetRuntimeMaxDelegatorBlueprints, TangleTestnetRuntimeMaxOperatorBlueprints, TangleTestnetRuntimeMaxUnstakeRequests, TangleTestnetRuntimeMaxWithdrawRequests, TangleTestnetRuntimeNposSolution16, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType, TangleTestnetRuntimeRuntime, TangleTestnetRuntimeRuntimeFreezeReason, TangleTestnetRuntimeRuntimeHoldReason } from '@polkadot/types/lookup'; +import type { EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FinalityGrandpaEquivocationPrecommit, FinalityGrandpaEquivocationPrevote, FinalityGrandpaPrecommit, FinalityGrandpaPrevote, FpRpcTransactionStatus, FrameMetadataHashExtensionCheckMetadataHash, FrameMetadataHashExtensionMode, FrameSupportDispatchDispatchClass, FrameSupportDispatchDispatchInfo, FrameSupportDispatchPays, FrameSupportDispatchPerDispatchClassU32, FrameSupportDispatchPerDispatchClassWeight, FrameSupportDispatchPerDispatchClassWeightsPerClass, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportPreimagesBounded, FrameSupportTokensMiscBalanceStatus, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCall, FrameSystemCodeUpgradeAuthorization, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonZeroSender, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckTxVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, PalletAirdropClaimsCall, PalletAirdropClaimsError, PalletAirdropClaimsEvent, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsEthereumAddress, PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletAirdropClaimsUtilsSr25519Signature, PalletAssetsAccountStatus, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAssetsAssetStatus, PalletAssetsCall, PalletAssetsError, PalletAssetsEvent, PalletAssetsExistenceReason, PalletBabeCall, PalletBabeError, PalletBagsListCall, PalletBagsListError, PalletBagsListEvent, PalletBagsListListBag, PalletBagsListListListError, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesAdjustmentDirection, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReserveData, PalletBaseFeeCall, PalletBaseFeeEvent, PalletBountiesBounty, PalletBountiesBountyStatus, PalletBountiesCall, PalletBountiesError, PalletBountiesEvent, PalletChildBountiesCall, PalletChildBountiesChildBounty, PalletChildBountiesChildBountyStatus, PalletChildBountiesError, PalletChildBountiesEvent, PalletCollectiveCall, PalletCollectiveError, PalletCollectiveEvent, PalletCollectiveRawOrigin, PalletCollectiveVotes, PalletDemocracyCall, PalletDemocracyConviction, PalletDemocracyDelegations, PalletDemocracyError, PalletDemocracyEvent, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyTally, PalletDemocracyVoteAccountVote, PalletDemocracyVotePriorLock, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletDynamicFeeCall, PalletElectionProviderMultiPhaseCall, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhaseError, PalletElectionProviderMultiPhaseEvent, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenCall, PalletElectionsPhragmenError, PalletElectionsPhragmenEvent, PalletElectionsPhragmenRenouncing, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumRawOrigin, PalletEvmCall, PalletEvmCodeMetadata, PalletEvmError, PalletEvmEvent, PalletGrandpaCall, PalletGrandpaError, PalletGrandpaEvent, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletHotfixSufficientsCall, PalletHotfixSufficientsError, PalletIdentityAuthorityProperties, PalletIdentityCall, PalletIdentityError, PalletIdentityEvent, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineCall, PalletImOnlineError, PalletImOnlineEvent, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Public, PalletImOnlineSr25519AppSr25519Signature, PalletIndicesCall, PalletIndicesError, PalletIndicesEvent, PalletMultiAssetDelegationCall, PalletMultiAssetDelegationDelegatorBondInfoDelegator, PalletMultiAssetDelegationDelegatorBondLessRequest, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationDelegatorDelegatorStatus, PalletMultiAssetDelegationDelegatorWithdrawRequest, PalletMultiAssetDelegationError, PalletMultiAssetDelegationEvent, PalletMultiAssetDelegationOperatorDelegatorBond, PalletMultiAssetDelegationOperatorOperatorBondLessRequest, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationOperatorOperatorStatus, PalletMultiAssetDelegationRewardsAssetAction, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultiAssetDelegationRewardsRewardConfigForAssetVault, PalletMultisigCall, PalletMultisigError, PalletMultisigEvent, PalletMultisigMultisig, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsCall, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsDefensiveError, PalletNominationPoolsError, PalletNominationPoolsEvent, PalletNominationPoolsFreezeReason, PalletNominationPoolsPoolMember, PalletNominationPoolsPoolRoles, PalletNominationPoolsPoolState, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletNominationPoolsUnbondPool, PalletOffencesEvent, PalletPreimageCall, PalletPreimageError, PalletPreimageEvent, PalletPreimageHoldReason, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyCall, PalletProxyError, PalletProxyEvent, PalletProxyProxyDefinition, PalletSchedulerCall, PalletSchedulerError, PalletSchedulerEvent, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesModuleCall, PalletServicesModuleError, PalletServicesModuleEvent, PalletServicesUnappliedSlash, PalletSessionCall, PalletSessionError, PalletSessionEvent, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingPalletCall, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingPalletError, PalletStakingPalletEvent, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTangleLstBondExtra, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstBondedPoolPoolMetadata, PalletTangleLstCall, PalletTangleLstClaimPermission, PalletTangleLstCommission, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstDefensiveError, PalletTangleLstError, PalletTangleLstEvent, PalletTangleLstFreezeReason, PalletTangleLstPoolsPoolMember, PalletTangleLstPoolsPoolRoles, PalletTangleLstPoolsPoolState, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTangleLstSubPoolsUnbondPool, PalletTimestampCall, PalletTransactionPaymentChargeTransactionPayment, PalletTransactionPaymentEvent, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryPaymentState, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletTxPauseCall, PalletTxPauseError, PalletTxPauseEvent, PalletUtilityCall, PalletUtilityError, PalletUtilityEvent, PalletVestingCall, PalletVestingError, PalletVestingEvent, PalletVestingReleases, PalletVestingVestingInfo, SpArithmeticArithmeticError, SpConsensusBabeAllowedSlots, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusBabeDigestsPrimaryPreDigest, SpConsensusBabeDigestsSecondaryPlainPreDigest, SpConsensusBabeDigestsSecondaryVRFPreDigest, SpConsensusGrandpaAppPublic, SpConsensusGrandpaAppSignature, SpConsensusGrandpaEquivocation, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreCryptoKeyTypeId, SpCoreSr25519VrfVrfSignature, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeBlakeTwo256, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeHeader, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpSessionMembershipProof, SpStakingExposure, SpStakingExposurePage, SpStakingIndividualExposure, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, SpVersionRuntimeVersion, SpWeightsRuntimeDbWeight, SpWeightsWeightV2Weight, TanglePrimitivesAccount, TanglePrimitivesServicesApprovalState, TanglePrimitivesServicesArchitecture, TanglePrimitivesServicesAsset, TanglePrimitivesServicesBlueprintServiceManager, TanglePrimitivesServicesContainerGadget, TanglePrimitivesServicesField, TanglePrimitivesServicesFieldFieldType, TanglePrimitivesServicesGadget, TanglePrimitivesServicesGadgetBinary, TanglePrimitivesServicesGadgetSource, TanglePrimitivesServicesGadgetSourceFetcher, TanglePrimitivesServicesGithubFetcher, TanglePrimitivesServicesImageRegistryFetcher, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesJobDefinition, TanglePrimitivesServicesJobMetadata, TanglePrimitivesServicesMasterBlueprintServiceManagerRevision, TanglePrimitivesServicesNativeGadget, TanglePrimitivesServicesOperatingSystem, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceMetadata, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TanglePrimitivesServicesTestFetcher, TanglePrimitivesServicesTypeCheckError, TanglePrimitivesServicesWasmGadget, TanglePrimitivesServicesWasmRuntime, TangleTestnetRuntimeMaxDelegations, TangleTestnetRuntimeMaxDelegatorBlueprints, TangleTestnetRuntimeMaxOperatorBlueprints, TangleTestnetRuntimeMaxUnstakeRequests, TangleTestnetRuntimeMaxWithdrawRequests, TangleTestnetRuntimeNposSolution16, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType, TangleTestnetRuntimeRuntime, TangleTestnetRuntimeRuntimeFreezeReason, TangleTestnetRuntimeRuntimeHoldReason } from '@polkadot/types/lookup'; declare module '@polkadot/types/types/registry' { interface InterfaceTypes { @@ -346,8 +346,10 @@ declare module '@polkadot/types/types/registry' { SpVersionRuntimeVersion: SpVersionRuntimeVersion; SpWeightsRuntimeDbWeight: SpWeightsRuntimeDbWeight; SpWeightsWeightV2Weight: SpWeightsWeightV2Weight; + TanglePrimitivesAccount: TanglePrimitivesAccount; TanglePrimitivesServicesApprovalState: TanglePrimitivesServicesApprovalState; TanglePrimitivesServicesArchitecture: TanglePrimitivesServicesArchitecture; + TanglePrimitivesServicesAsset: TanglePrimitivesServicesAsset; TanglePrimitivesServicesBlueprintServiceManager: TanglePrimitivesServicesBlueprintServiceManager; TanglePrimitivesServicesContainerGadget: TanglePrimitivesServicesContainerGadget; TanglePrimitivesServicesField: TanglePrimitivesServicesField; @@ -372,6 +374,7 @@ declare module '@polkadot/types/types/registry' { TanglePrimitivesServicesServiceBlueprint: TanglePrimitivesServicesServiceBlueprint; TanglePrimitivesServicesServiceMetadata: TanglePrimitivesServicesServiceMetadata; TanglePrimitivesServicesServiceRequest: TanglePrimitivesServicesServiceRequest; + TanglePrimitivesServicesStagingServicePayment: TanglePrimitivesServicesStagingServicePayment; TanglePrimitivesServicesTestFetcher: TanglePrimitivesServicesTestFetcher; TanglePrimitivesServicesTypeCheckError: TanglePrimitivesServicesTypeCheckError; TanglePrimitivesServicesWasmGadget: TanglePrimitivesServicesWasmGadget; diff --git a/types/src/interfaces/types-lookup.ts b/types/src/interfaces/types-lookup.ts index 69ca0206..78f6e934 100644 --- a/types/src/interfaces/types-lookup.ts +++ b/types/src/interfaces/types-lookup.ts @@ -1698,13 +1698,13 @@ declare module '@polkadot/types/lookup' { readonly asDeposited: { readonly who: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; } & Struct; readonly isScheduledwithdraw: boolean; readonly asScheduledwithdraw: { readonly who: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; } & Struct; readonly isExecutedwithdraw: boolean; readonly asExecutedwithdraw: { @@ -1719,14 +1719,14 @@ declare module '@polkadot/types/lookup' { readonly who: AccountId32; readonly operator: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; } & Struct; readonly isScheduledDelegatorBondLess: boolean; readonly asScheduledDelegatorBondLess: { readonly who: AccountId32; readonly operator: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; } & Struct; readonly isExecutedDelegatorBondLess: boolean; readonly asExecutedDelegatorBondLess: { @@ -1750,7 +1750,7 @@ declare module '@polkadot/types/lookup' { readonly asAssetUpdatedInVault: { readonly who: AccountId32; readonly vaultId: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly action: PalletMultiAssetDelegationRewardsAssetAction; } & Struct; readonly isOperatorSlashed: boolean; @@ -1763,17 +1763,33 @@ declare module '@polkadot/types/lookup' { readonly who: AccountId32; readonly amount: u128; } & Struct; - readonly type: 'OperatorJoined' | 'OperatorLeavingScheduled' | 'OperatorLeaveCancelled' | 'OperatorLeaveExecuted' | 'OperatorBondMore' | 'OperatorBondLessScheduled' | 'OperatorBondLessExecuted' | 'OperatorBondLessCancelled' | 'OperatorWentOffline' | 'OperatorWentOnline' | 'Deposited' | 'Scheduledwithdraw' | 'Executedwithdraw' | 'Cancelledwithdraw' | 'Delegated' | 'ScheduledDelegatorBondLess' | 'ExecutedDelegatorBondLess' | 'CancelledDelegatorBondLess' | 'IncentiveAPYAndCapSet' | 'BlueprintWhitelisted' | 'AssetUpdatedInVault' | 'OperatorSlashed' | 'DelegatorSlashed'; + readonly isEvmReverted: boolean; + readonly asEvmReverted: { + readonly from: H160; + readonly to: H160; + readonly data: Bytes; + readonly reason: Bytes; + } & Struct; + readonly type: 'OperatorJoined' | 'OperatorLeavingScheduled' | 'OperatorLeaveCancelled' | 'OperatorLeaveExecuted' | 'OperatorBondMore' | 'OperatorBondLessScheduled' | 'OperatorBondLessExecuted' | 'OperatorBondLessCancelled' | 'OperatorWentOffline' | 'OperatorWentOnline' | 'Deposited' | 'Scheduledwithdraw' | 'Executedwithdraw' | 'Cancelledwithdraw' | 'Delegated' | 'ScheduledDelegatorBondLess' | 'ExecutedDelegatorBondLess' | 'CancelledDelegatorBondLess' | 'IncentiveAPYAndCapSet' | 'BlueprintWhitelisted' | 'AssetUpdatedInVault' | 'OperatorSlashed' | 'DelegatorSlashed' | 'EvmReverted'; } - /** @name PalletMultiAssetDelegationRewardsAssetAction (125) */ + /** @name TanglePrimitivesServicesAsset (124) */ + interface TanglePrimitivesServicesAsset extends Enum { + readonly isCustom: boolean; + readonly asCustom: u128; + readonly isErc20: boolean; + readonly asErc20: H160; + readonly type: 'Custom' | 'Erc20'; + } + + /** @name PalletMultiAssetDelegationRewardsAssetAction (126) */ interface PalletMultiAssetDelegationRewardsAssetAction extends Enum { readonly isAdd: boolean; readonly isRemove: boolean; readonly type: 'Add' | 'Remove'; } - /** @name PalletServicesModuleEvent (126) */ + /** @name PalletServicesModuleEvent (127) */ interface PalletServicesModuleEvent extends Enum { readonly isBlueprintCreated: boolean; readonly asBlueprintCreated: { @@ -1889,13 +1905,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'BlueprintCreated' | 'PreRegistration' | 'Registered' | 'Unregistered' | 'PriceTargetsUpdated' | 'ServiceRequested' | 'ServiceRequestApproved' | 'ServiceRequestRejected' | 'ServiceInitiated' | 'ServiceTerminated' | 'JobCalled' | 'JobResultSubmitted' | 'EvmReverted' | 'UnappliedSlash' | 'SlashDiscarded' | 'MasterBlueprintServiceManagerRevised'; } - /** @name TanglePrimitivesServicesOperatorPreferences (127) */ + /** @name TanglePrimitivesServicesOperatorPreferences (128) */ interface TanglePrimitivesServicesOperatorPreferences extends Struct { readonly key: U8aFixed; readonly priceTargets: TanglePrimitivesServicesPriceTargets; } - /** @name TanglePrimitivesServicesPriceTargets (129) */ + /** @name TanglePrimitivesServicesPriceTargets (130) */ interface TanglePrimitivesServicesPriceTargets extends Struct { readonly cpu: u64; readonly mem: u64; @@ -1904,7 +1920,7 @@ declare module '@polkadot/types/lookup' { readonly storageNvme: u64; } - /** @name TanglePrimitivesServicesField (131) */ + /** @name TanglePrimitivesServicesField (132) */ interface TanglePrimitivesServicesField extends Enum { readonly isNone: boolean; readonly isBool: boolean; @@ -1940,7 +1956,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'None' | 'Bool' | 'Uint8' | 'Int8' | 'Uint16' | 'Int16' | 'Uint32' | 'Int32' | 'Uint64' | 'Int64' | 'String' | 'Bytes' | 'Array' | 'List' | 'Struct' | 'AccountId'; } - /** @name PalletTangleLstEvent (144) */ + /** @name PalletTangleLstEvent (145) */ interface PalletTangleLstEvent extends Enum { readonly isCreated: boolean; readonly asCreated: { @@ -2044,7 +2060,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Created' | 'Bonded' | 'PaidOut' | 'Unbonded' | 'Withdrawn' | 'Destroyed' | 'StateChanged' | 'MemberRemoved' | 'RolesUpdated' | 'PoolSlashed' | 'UnbondingPoolSlashed' | 'PoolCommissionUpdated' | 'PoolMaxCommissionUpdated' | 'PoolCommissionChangeRateUpdated' | 'PoolCommissionClaimPermissionUpdated' | 'PoolCommissionClaimed' | 'MinBalanceDeficitAdjusted' | 'MinBalanceExcessAdjusted'; } - /** @name PalletTangleLstPoolsPoolState (145) */ + /** @name PalletTangleLstPoolsPoolState (146) */ interface PalletTangleLstPoolsPoolState extends Enum { readonly isOpen: boolean; readonly isBlocked: boolean; @@ -2052,13 +2068,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Open' | 'Blocked' | 'Destroying'; } - /** @name PalletTangleLstCommissionCommissionChangeRate (146) */ + /** @name PalletTangleLstCommissionCommissionChangeRate (147) */ interface PalletTangleLstCommissionCommissionChangeRate extends Struct { readonly maxIncrease: Perbill; readonly minDelay: u64; } - /** @name PalletTangleLstCommissionCommissionClaimPermission (148) */ + /** @name PalletTangleLstCommissionCommissionClaimPermission (149) */ interface PalletTangleLstCommissionCommissionClaimPermission extends Enum { readonly isPermissionless: boolean; readonly isAccount: boolean; @@ -2066,7 +2082,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissionless' | 'Account'; } - /** @name FrameSystemPhase (149) */ + /** @name FrameSystemPhase (150) */ interface FrameSystemPhase extends Enum { readonly isApplyExtrinsic: boolean; readonly asApplyExtrinsic: u32; @@ -2075,19 +2091,19 @@ declare module '@polkadot/types/lookup' { readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization'; } - /** @name FrameSystemLastRuntimeUpgradeInfo (151) */ + /** @name FrameSystemLastRuntimeUpgradeInfo (152) */ interface FrameSystemLastRuntimeUpgradeInfo extends Struct { readonly specVersion: Compact; readonly specName: Text; } - /** @name FrameSystemCodeUpgradeAuthorization (153) */ + /** @name FrameSystemCodeUpgradeAuthorization (154) */ interface FrameSystemCodeUpgradeAuthorization extends Struct { readonly codeHash: H256; readonly checkVersion: bool; } - /** @name FrameSystemCall (154) */ + /** @name FrameSystemCall (155) */ interface FrameSystemCall extends Enum { readonly isRemark: boolean; readonly asRemark: { @@ -2137,21 +2153,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent' | 'AuthorizeUpgrade' | 'AuthorizeUpgradeWithoutChecks' | 'ApplyAuthorizedUpgrade'; } - /** @name FrameSystemLimitsBlockWeights (158) */ + /** @name FrameSystemLimitsBlockWeights (159) */ interface FrameSystemLimitsBlockWeights extends Struct { readonly baseBlock: SpWeightsWeightV2Weight; readonly maxBlock: SpWeightsWeightV2Weight; readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass; } - /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (159) */ + /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (160) */ interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct { readonly normal: FrameSystemLimitsWeightsPerClass; readonly operational: FrameSystemLimitsWeightsPerClass; readonly mandatory: FrameSystemLimitsWeightsPerClass; } - /** @name FrameSystemLimitsWeightsPerClass (160) */ + /** @name FrameSystemLimitsWeightsPerClass (161) */ interface FrameSystemLimitsWeightsPerClass extends Struct { readonly baseExtrinsic: SpWeightsWeightV2Weight; readonly maxExtrinsic: Option; @@ -2159,25 +2175,25 @@ declare module '@polkadot/types/lookup' { readonly reserved: Option; } - /** @name FrameSystemLimitsBlockLength (162) */ + /** @name FrameSystemLimitsBlockLength (163) */ interface FrameSystemLimitsBlockLength extends Struct { readonly max: FrameSupportDispatchPerDispatchClassU32; } - /** @name FrameSupportDispatchPerDispatchClassU32 (163) */ + /** @name FrameSupportDispatchPerDispatchClassU32 (164) */ interface FrameSupportDispatchPerDispatchClassU32 extends Struct { readonly normal: u32; readonly operational: u32; readonly mandatory: u32; } - /** @name SpWeightsRuntimeDbWeight (164) */ + /** @name SpWeightsRuntimeDbWeight (165) */ interface SpWeightsRuntimeDbWeight extends Struct { readonly read: u64; readonly write: u64; } - /** @name SpVersionRuntimeVersion (165) */ + /** @name SpVersionRuntimeVersion (166) */ interface SpVersionRuntimeVersion extends Struct { readonly specName: Text; readonly implName: Text; @@ -2189,7 +2205,7 @@ declare module '@polkadot/types/lookup' { readonly stateVersion: u8; } - /** @name FrameSystemError (170) */ + /** @name FrameSystemError (171) */ interface FrameSystemError extends Enum { readonly isInvalidSpecName: boolean; readonly isSpecVersionNeedsToIncrease: boolean; @@ -2203,7 +2219,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered' | 'MultiBlockMigrationsOngoing' | 'NothingAuthorized' | 'Unauthorized'; } - /** @name PalletTimestampCall (171) */ + /** @name PalletTimestampCall (172) */ interface PalletTimestampCall extends Enum { readonly isSet: boolean; readonly asSet: { @@ -2212,7 +2228,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Set'; } - /** @name PalletSudoCall (172) */ + /** @name PalletSudoCall (173) */ interface PalletSudoCall extends Enum { readonly isSudo: boolean; readonly asSudo: { @@ -2236,7 +2252,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs' | 'RemoveKey'; } - /** @name PalletAssetsCall (174) */ + /** @name PalletAssetsCall (175) */ interface PalletAssetsCall extends Enum { readonly isCreate: boolean; readonly asCreate: { @@ -2418,7 +2434,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Create' | 'ForceCreate' | 'StartDestroy' | 'DestroyAccounts' | 'DestroyApprovals' | 'FinishDestroy' | 'Mint' | 'Burn' | 'Transfer' | 'TransferKeepAlive' | 'ForceTransfer' | 'Freeze' | 'Thaw' | 'FreezeAsset' | 'ThawAsset' | 'TransferOwnership' | 'SetTeam' | 'SetMetadata' | 'ClearMetadata' | 'ForceSetMetadata' | 'ForceClearMetadata' | 'ForceAssetStatus' | 'ApproveTransfer' | 'CancelApproval' | 'ForceCancelApproval' | 'TransferApproved' | 'Touch' | 'Refund' | 'SetMinBalance' | 'TouchOther' | 'RefundOther' | 'Block'; } - /** @name PalletBalancesCall (176) */ + /** @name PalletBalancesCall (177) */ interface PalletBalancesCall extends Enum { readonly isTransferAllowDeath: boolean; readonly asTransferAllowDeath: { @@ -2468,14 +2484,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'TransferAllowDeath' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve' | 'UpgradeAccounts' | 'ForceSetBalance' | 'ForceAdjustTotalIssuance' | 'Burn'; } - /** @name PalletBalancesAdjustmentDirection (177) */ + /** @name PalletBalancesAdjustmentDirection (178) */ interface PalletBalancesAdjustmentDirection extends Enum { readonly isIncrease: boolean; readonly isDecrease: boolean; readonly type: 'Increase' | 'Decrease'; } - /** @name PalletBabeCall (178) */ + /** @name PalletBabeCall (179) */ interface PalletBabeCall extends Enum { readonly isReportEquivocation: boolean; readonly asReportEquivocation: { @@ -2494,7 +2510,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ReportEquivocation' | 'ReportEquivocationUnsigned' | 'PlanConfigChange'; } - /** @name SpConsensusSlotsEquivocationProof (179) */ + /** @name SpConsensusSlotsEquivocationProof (180) */ interface SpConsensusSlotsEquivocationProof extends Struct { readonly offender: SpConsensusBabeAppPublic; readonly slot: u64; @@ -2502,7 +2518,7 @@ declare module '@polkadot/types/lookup' { readonly secondHeader: SpRuntimeHeader; } - /** @name SpRuntimeHeader (180) */ + /** @name SpRuntimeHeader (181) */ interface SpRuntimeHeader extends Struct { readonly parentHash: H256; readonly number: Compact; @@ -2511,17 +2527,17 @@ declare module '@polkadot/types/lookup' { readonly digest: SpRuntimeDigest; } - /** @name SpConsensusBabeAppPublic (181) */ + /** @name SpConsensusBabeAppPublic (182) */ interface SpConsensusBabeAppPublic extends U8aFixed {} - /** @name SpSessionMembershipProof (183) */ + /** @name SpSessionMembershipProof (184) */ interface SpSessionMembershipProof extends Struct { readonly session: u32; readonly trieNodes: Vec; readonly validatorCount: u32; } - /** @name SpConsensusBabeDigestsNextConfigDescriptor (184) */ + /** @name SpConsensusBabeDigestsNextConfigDescriptor (185) */ interface SpConsensusBabeDigestsNextConfigDescriptor extends Enum { readonly isV1: boolean; readonly asV1: { @@ -2531,7 +2547,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'V1'; } - /** @name SpConsensusBabeAllowedSlots (186) */ + /** @name SpConsensusBabeAllowedSlots (187) */ interface SpConsensusBabeAllowedSlots extends Enum { readonly isPrimarySlots: boolean; readonly isPrimaryAndSecondaryPlainSlots: boolean; @@ -2539,7 +2555,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PrimarySlots' | 'PrimaryAndSecondaryPlainSlots' | 'PrimaryAndSecondaryVRFSlots'; } - /** @name PalletGrandpaCall (187) */ + /** @name PalletGrandpaCall (188) */ interface PalletGrandpaCall extends Enum { readonly isReportEquivocation: boolean; readonly asReportEquivocation: { @@ -2559,13 +2575,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'ReportEquivocation' | 'ReportEquivocationUnsigned' | 'NoteStalled'; } - /** @name SpConsensusGrandpaEquivocationProof (188) */ + /** @name SpConsensusGrandpaEquivocationProof (189) */ interface SpConsensusGrandpaEquivocationProof extends Struct { readonly setId: u64; readonly equivocation: SpConsensusGrandpaEquivocation; } - /** @name SpConsensusGrandpaEquivocation (189) */ + /** @name SpConsensusGrandpaEquivocation (190) */ interface SpConsensusGrandpaEquivocation extends Enum { readonly isPrevote: boolean; readonly asPrevote: FinalityGrandpaEquivocationPrevote; @@ -2574,7 +2590,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Prevote' | 'Precommit'; } - /** @name FinalityGrandpaEquivocationPrevote (190) */ + /** @name FinalityGrandpaEquivocationPrevote (191) */ interface FinalityGrandpaEquivocationPrevote extends Struct { readonly roundNumber: u64; readonly identity: SpConsensusGrandpaAppPublic; @@ -2582,16 +2598,16 @@ declare module '@polkadot/types/lookup' { readonly second: ITuple<[FinalityGrandpaPrevote, SpConsensusGrandpaAppSignature]>; } - /** @name FinalityGrandpaPrevote (191) */ + /** @name FinalityGrandpaPrevote (192) */ interface FinalityGrandpaPrevote extends Struct { readonly targetHash: H256; readonly targetNumber: u64; } - /** @name SpConsensusGrandpaAppSignature (192) */ + /** @name SpConsensusGrandpaAppSignature (193) */ interface SpConsensusGrandpaAppSignature extends U8aFixed {} - /** @name FinalityGrandpaEquivocationPrecommit (195) */ + /** @name FinalityGrandpaEquivocationPrecommit (196) */ interface FinalityGrandpaEquivocationPrecommit extends Struct { readonly roundNumber: u64; readonly identity: SpConsensusGrandpaAppPublic; @@ -2599,16 +2615,16 @@ declare module '@polkadot/types/lookup' { readonly second: ITuple<[FinalityGrandpaPrecommit, SpConsensusGrandpaAppSignature]>; } - /** @name FinalityGrandpaPrecommit (196) */ + /** @name FinalityGrandpaPrecommit (197) */ interface FinalityGrandpaPrecommit extends Struct { readonly targetHash: H256; readonly targetNumber: u64; } - /** @name SpCoreVoid (198) */ + /** @name SpCoreVoid (199) */ type SpCoreVoid = Null; - /** @name PalletIndicesCall (199) */ + /** @name PalletIndicesCall (200) */ interface PalletIndicesCall extends Enum { readonly isClaim: boolean; readonly asClaim: { @@ -2636,7 +2652,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Claim' | 'Transfer' | 'Free' | 'ForceTransfer' | 'Freeze'; } - /** @name PalletDemocracyCall (200) */ + /** @name PalletDemocracyCall (201) */ interface PalletDemocracyCall extends Enum { readonly isPropose: boolean; readonly asPropose: { @@ -2720,7 +2736,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Propose' | 'Second' | 'Vote' | 'EmergencyCancel' | 'ExternalPropose' | 'ExternalProposeMajority' | 'ExternalProposeDefault' | 'FastTrack' | 'VetoExternal' | 'CancelReferendum' | 'Delegate' | 'Undelegate' | 'ClearPublicProposals' | 'Unlock' | 'RemoveVote' | 'RemoveOtherVote' | 'Blacklist' | 'CancelProposal' | 'SetMetadata'; } - /** @name FrameSupportPreimagesBounded (201) */ + /** @name FrameSupportPreimagesBounded (202) */ interface FrameSupportPreimagesBounded extends Enum { readonly isLegacy: boolean; readonly asLegacy: { @@ -2736,10 +2752,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Inline' | 'Lookup'; } - /** @name SpRuntimeBlakeTwo256 (202) */ + /** @name SpRuntimeBlakeTwo256 (203) */ type SpRuntimeBlakeTwo256 = Null; - /** @name PalletDemocracyConviction (204) */ + /** @name PalletDemocracyConviction (205) */ interface PalletDemocracyConviction extends Enum { readonly isNone: boolean; readonly isLocked1x: boolean; @@ -2751,7 +2767,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'None' | 'Locked1x' | 'Locked2x' | 'Locked3x' | 'Locked4x' | 'Locked5x' | 'Locked6x'; } - /** @name PalletCollectiveCall (207) */ + /** @name PalletCollectiveCall (208) */ interface PalletCollectiveCall extends Enum { readonly isSetMembers: boolean; readonly asSetMembers: { @@ -2790,7 +2806,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetMembers' | 'Execute' | 'Propose' | 'Vote' | 'DisapproveProposal' | 'Close'; } - /** @name PalletVestingCall (208) */ + /** @name PalletVestingCall (209) */ interface PalletVestingCall extends Enum { readonly isVest: boolean; readonly isVestOther: boolean; @@ -2821,14 +2837,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Vest' | 'VestOther' | 'VestedTransfer' | 'ForceVestedTransfer' | 'MergeSchedules' | 'ForceRemoveVestingSchedule'; } - /** @name PalletVestingVestingInfo (209) */ + /** @name PalletVestingVestingInfo (210) */ interface PalletVestingVestingInfo extends Struct { readonly locked: u128; readonly perBlock: u128; readonly startingBlock: u64; } - /** @name PalletElectionsPhragmenCall (210) */ + /** @name PalletElectionsPhragmenCall (211) */ interface PalletElectionsPhragmenCall extends Enum { readonly isVote: boolean; readonly asVote: { @@ -2858,7 +2874,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Vote' | 'RemoveVoter' | 'SubmitCandidacy' | 'RenounceCandidacy' | 'RemoveMember' | 'CleanDefunctVoters'; } - /** @name PalletElectionsPhragmenRenouncing (211) */ + /** @name PalletElectionsPhragmenRenouncing (212) */ interface PalletElectionsPhragmenRenouncing extends Enum { readonly isMember: boolean; readonly isRunnerUp: boolean; @@ -2867,7 +2883,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Member' | 'RunnerUp' | 'Candidate'; } - /** @name PalletElectionProviderMultiPhaseCall (212) */ + /** @name PalletElectionProviderMultiPhaseCall (213) */ interface PalletElectionProviderMultiPhaseCall extends Enum { readonly isSubmitUnsigned: boolean; readonly asSubmitUnsigned: { @@ -2894,14 +2910,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'SubmitUnsigned' | 'SetMinimumUntrustedScore' | 'SetEmergencyElectionResult' | 'Submit' | 'GovernanceFallback'; } - /** @name PalletElectionProviderMultiPhaseRawSolution (213) */ + /** @name PalletElectionProviderMultiPhaseRawSolution (214) */ interface PalletElectionProviderMultiPhaseRawSolution extends Struct { readonly solution: TangleTestnetRuntimeNposSolution16; readonly score: SpNposElectionsElectionScore; readonly round: u32; } - /** @name TangleTestnetRuntimeNposSolution16 (214) */ + /** @name TangleTestnetRuntimeNposSolution16 (215) */ interface TangleTestnetRuntimeNposSolution16 extends Struct { readonly votes1: Vec, Compact]>>; readonly votes2: Vec, ITuple<[Compact, Compact]>, Compact]>>; @@ -2921,19 +2937,19 @@ declare module '@polkadot/types/lookup' { readonly votes16: Vec, Vec, Compact]>>, Compact]>>; } - /** @name PalletElectionProviderMultiPhaseSolutionOrSnapshotSize (265) */ + /** @name PalletElectionProviderMultiPhaseSolutionOrSnapshotSize (266) */ interface PalletElectionProviderMultiPhaseSolutionOrSnapshotSize extends Struct { readonly voters: Compact; readonly targets: Compact; } - /** @name SpNposElectionsSupport (269) */ + /** @name SpNposElectionsSupport (270) */ interface SpNposElectionsSupport extends Struct { readonly total: u128; readonly voters: Vec>; } - /** @name PalletStakingPalletCall (270) */ + /** @name PalletStakingPalletCall (271) */ interface PalletStakingPalletCall extends Enum { readonly isBond: boolean; readonly asBond: { @@ -3059,7 +3075,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Bond' | 'BondExtra' | 'Unbond' | 'WithdrawUnbonded' | 'Validate' | 'Nominate' | 'Chill' | 'SetPayee' | 'SetController' | 'SetValidatorCount' | 'IncreaseValidatorCount' | 'ScaleValidatorCount' | 'ForceNoEras' | 'ForceNewEra' | 'SetInvulnerables' | 'ForceUnstake' | 'ForceNewEraAlways' | 'CancelDeferredSlash' | 'PayoutStakers' | 'Rebond' | 'ReapStash' | 'Kick' | 'SetStakingConfigs' | 'ChillOther' | 'ForceApplyMinCommission' | 'SetMinCommission' | 'PayoutStakersByPage' | 'UpdatePayee' | 'DeprecateControllerBatch' | 'RestoreLedger'; } - /** @name PalletStakingPalletConfigOpU128 (273) */ + /** @name PalletStakingPalletConfigOpU128 (274) */ interface PalletStakingPalletConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3068,7 +3084,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpU32 (274) */ + /** @name PalletStakingPalletConfigOpU32 (275) */ interface PalletStakingPalletConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3077,7 +3093,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpPercent (275) */ + /** @name PalletStakingPalletConfigOpPercent (276) */ interface PalletStakingPalletConfigOpPercent extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3086,7 +3102,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpPerbill (276) */ + /** @name PalletStakingPalletConfigOpPerbill (277) */ interface PalletStakingPalletConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3095,13 +3111,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingUnlockChunk (281) */ + /** @name PalletStakingUnlockChunk (282) */ interface PalletStakingUnlockChunk extends Struct { readonly value: Compact; readonly era: Compact; } - /** @name PalletSessionCall (283) */ + /** @name PalletSessionCall (284) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -3112,14 +3128,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetKeys' | 'PurgeKeys'; } - /** @name TangleTestnetRuntimeOpaqueSessionKeys (284) */ + /** @name TangleTestnetRuntimeOpaqueSessionKeys (285) */ interface TangleTestnetRuntimeOpaqueSessionKeys extends Struct { readonly babe: SpConsensusBabeAppPublic; readonly grandpa: SpConsensusGrandpaAppPublic; readonly imOnline: PalletImOnlineSr25519AppSr25519Public; } - /** @name PalletTreasuryCall (285) */ + /** @name PalletTreasuryCall (286) */ interface PalletTreasuryCall extends Enum { readonly isSpendLocal: boolean; readonly asSpendLocal: { @@ -3152,7 +3168,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SpendLocal' | 'RemoveApproval' | 'Spend' | 'Payout' | 'CheckStatus' | 'VoidSpend'; } - /** @name PalletBountiesCall (287) */ + /** @name PalletBountiesCall (288) */ interface PalletBountiesCall extends Enum { readonly isProposeBounty: boolean; readonly asProposeBounty: { @@ -3198,7 +3214,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ProposeBounty' | 'ApproveBounty' | 'ProposeCurator' | 'UnassignCurator' | 'AcceptCurator' | 'AwardBounty' | 'ClaimBounty' | 'CloseBounty' | 'ExtendBountyExpiry'; } - /** @name PalletChildBountiesCall (288) */ + /** @name PalletChildBountiesCall (289) */ interface PalletChildBountiesCall extends Enum { readonly isAddChildBounty: boolean; readonly asAddChildBounty: { @@ -3242,7 +3258,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AddChildBounty' | 'ProposeCurator' | 'AcceptCurator' | 'UnassignCurator' | 'AwardChildBounty' | 'ClaimChildBounty' | 'CloseChildBounty'; } - /** @name PalletBagsListCall (289) */ + /** @name PalletBagsListCall (290) */ interface PalletBagsListCall extends Enum { readonly isRebag: boolean; readonly asRebag: { @@ -3260,7 +3276,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Rebag' | 'PutInFrontOf' | 'PutInFrontOfOther'; } - /** @name PalletNominationPoolsCall (290) */ + /** @name PalletNominationPoolsCall (291) */ interface PalletNominationPoolsCall extends Enum { readonly isJoin: boolean; readonly asJoin: { @@ -3393,7 +3409,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Join' | 'BondExtra' | 'ClaimPayout' | 'Unbond' | 'PoolWithdrawUnbonded' | 'WithdrawUnbonded' | 'Create' | 'CreateWithPoolId' | 'Nominate' | 'SetState' | 'SetMetadata' | 'SetConfigs' | 'UpdateRoles' | 'Chill' | 'BondExtraOther' | 'SetClaimPermission' | 'ClaimPayoutOther' | 'SetCommission' | 'SetCommissionMax' | 'SetCommissionChangeRate' | 'ClaimCommission' | 'AdjustPoolDeposit' | 'SetCommissionClaimPermission' | 'ApplySlash' | 'MigrateDelegation' | 'MigratePoolToDelegateStake'; } - /** @name PalletNominationPoolsBondExtra (291) */ + /** @name PalletNominationPoolsBondExtra (292) */ interface PalletNominationPoolsBondExtra extends Enum { readonly isFreeBalance: boolean; readonly asFreeBalance: u128; @@ -3401,7 +3417,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'FreeBalance' | 'Rewards'; } - /** @name PalletNominationPoolsConfigOpU128 (292) */ + /** @name PalletNominationPoolsConfigOpU128 (293) */ interface PalletNominationPoolsConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3410,7 +3426,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpU32 (293) */ + /** @name PalletNominationPoolsConfigOpU32 (294) */ interface PalletNominationPoolsConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3419,7 +3435,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpPerbill (294) */ + /** @name PalletNominationPoolsConfigOpPerbill (295) */ interface PalletNominationPoolsConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3428,7 +3444,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpAccountId32 (295) */ + /** @name PalletNominationPoolsConfigOpAccountId32 (296) */ interface PalletNominationPoolsConfigOpAccountId32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3437,7 +3453,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsClaimPermission (296) */ + /** @name PalletNominationPoolsClaimPermission (297) */ interface PalletNominationPoolsClaimPermission extends Enum { readonly isPermissioned: boolean; readonly isPermissionlessCompound: boolean; @@ -3446,7 +3462,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissioned' | 'PermissionlessCompound' | 'PermissionlessWithdraw' | 'PermissionlessAll'; } - /** @name PalletSchedulerCall (297) */ + /** @name PalletSchedulerCall (298) */ interface PalletSchedulerCall extends Enum { readonly isSchedule: boolean; readonly asSchedule: { @@ -3510,7 +3526,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Schedule' | 'Cancel' | 'ScheduleNamed' | 'CancelNamed' | 'ScheduleAfter' | 'ScheduleNamedAfter' | 'SetRetry' | 'SetRetryNamed' | 'CancelRetry' | 'CancelRetryNamed'; } - /** @name PalletPreimageCall (299) */ + /** @name PalletPreimageCall (300) */ interface PalletPreimageCall extends Enum { readonly isNotePreimage: boolean; readonly asNotePreimage: { @@ -3535,7 +3551,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotePreimage' | 'UnnotePreimage' | 'RequestPreimage' | 'UnrequestPreimage' | 'EnsureUpdated'; } - /** @name PalletTxPauseCall (300) */ + /** @name PalletTxPauseCall (301) */ interface PalletTxPauseCall extends Enum { readonly isPause: boolean; readonly asPause: { @@ -3548,7 +3564,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pause' | 'Unpause'; } - /** @name PalletImOnlineCall (301) */ + /** @name PalletImOnlineCall (302) */ interface PalletImOnlineCall extends Enum { readonly isHeartbeat: boolean; readonly asHeartbeat: { @@ -3558,7 +3574,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Heartbeat'; } - /** @name PalletImOnlineHeartbeat (302) */ + /** @name PalletImOnlineHeartbeat (303) */ interface PalletImOnlineHeartbeat extends Struct { readonly blockNumber: u64; readonly sessionIndex: u32; @@ -3566,10 +3582,10 @@ declare module '@polkadot/types/lookup' { readonly validatorsLen: u32; } - /** @name PalletImOnlineSr25519AppSr25519Signature (303) */ + /** @name PalletImOnlineSr25519AppSr25519Signature (304) */ interface PalletImOnlineSr25519AppSr25519Signature extends U8aFixed {} - /** @name PalletIdentityCall (304) */ + /** @name PalletIdentityCall (305) */ interface PalletIdentityCall extends Enum { readonly isAddRegistrar: boolean; readonly asAddRegistrar: { @@ -3669,7 +3685,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AddRegistrar' | 'SetIdentity' | 'SetSubs' | 'ClearIdentity' | 'RequestJudgement' | 'CancelRequest' | 'SetFee' | 'SetAccountId' | 'SetFields' | 'ProvideJudgement' | 'KillIdentity' | 'AddSub' | 'RenameSub' | 'RemoveSub' | 'QuitSub' | 'AddUsernameAuthority' | 'RemoveUsernameAuthority' | 'SetUsernameFor' | 'AcceptUsername' | 'RemoveExpiredApproval' | 'SetPrimaryUsername' | 'RemoveDanglingUsername'; } - /** @name PalletIdentityLegacyIdentityInfo (305) */ + /** @name PalletIdentityLegacyIdentityInfo (306) */ interface PalletIdentityLegacyIdentityInfo extends Struct { readonly additional: Vec>; readonly display: Data; @@ -3682,7 +3698,7 @@ declare module '@polkadot/types/lookup' { readonly twitter: Data; } - /** @name PalletIdentityJudgement (341) */ + /** @name PalletIdentityJudgement (342) */ interface PalletIdentityJudgement extends Enum { readonly isUnknown: boolean; readonly isFeePaid: boolean; @@ -3695,7 +3711,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unknown' | 'FeePaid' | 'Reasonable' | 'KnownGood' | 'OutOfDate' | 'LowQuality' | 'Erroneous'; } - /** @name SpRuntimeMultiSignature (343) */ + /** @name SpRuntimeMultiSignature (344) */ interface SpRuntimeMultiSignature extends Enum { readonly isEd25519: boolean; readonly asEd25519: U8aFixed; @@ -3706,7 +3722,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa'; } - /** @name PalletUtilityCall (345) */ + /** @name PalletUtilityCall (346) */ interface PalletUtilityCall extends Enum { readonly isBatch: boolean; readonly asBatch: { @@ -3738,7 +3754,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Batch' | 'AsDerivative' | 'BatchAll' | 'DispatchAs' | 'ForceBatch' | 'WithWeight'; } - /** @name TangleTestnetRuntimeOriginCaller (347) */ + /** @name TangleTestnetRuntimeOriginCaller (348) */ interface TangleTestnetRuntimeOriginCaller extends Enum { readonly isSystem: boolean; readonly asSystem: FrameSupportDispatchRawOrigin; @@ -3750,7 +3766,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'System' | 'Void' | 'Council' | 'Ethereum'; } - /** @name FrameSupportDispatchRawOrigin (348) */ + /** @name FrameSupportDispatchRawOrigin (349) */ interface FrameSupportDispatchRawOrigin extends Enum { readonly isRoot: boolean; readonly isSigned: boolean; @@ -3759,7 +3775,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Root' | 'Signed' | 'None'; } - /** @name PalletCollectiveRawOrigin (349) */ + /** @name PalletCollectiveRawOrigin (350) */ interface PalletCollectiveRawOrigin extends Enum { readonly isMembers: boolean; readonly asMembers: ITuple<[u32, u32]>; @@ -3769,14 +3785,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Members' | 'Member' | 'Phantom'; } - /** @name PalletEthereumRawOrigin (350) */ + /** @name PalletEthereumRawOrigin (351) */ interface PalletEthereumRawOrigin extends Enum { readonly isEthereumTransaction: boolean; readonly asEthereumTransaction: H160; readonly type: 'EthereumTransaction'; } - /** @name PalletMultisigCall (351) */ + /** @name PalletMultisigCall (352) */ interface PalletMultisigCall extends Enum { readonly isAsMultiThreshold1: boolean; readonly asAsMultiThreshold1: { @@ -3809,7 +3825,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AsMultiThreshold1' | 'AsMulti' | 'ApproveAsMulti' | 'CancelAsMulti'; } - /** @name PalletEthereumCall (353) */ + /** @name PalletEthereumCall (354) */ interface PalletEthereumCall extends Enum { readonly isTransact: boolean; readonly asTransact: { @@ -3818,7 +3834,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Transact'; } - /** @name EthereumTransactionTransactionV2 (354) */ + /** @name EthereumTransactionTransactionV2 (355) */ interface EthereumTransactionTransactionV2 extends Enum { readonly isLegacy: boolean; readonly asLegacy: EthereumTransactionLegacyTransaction; @@ -3829,7 +3845,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Eip2930' | 'Eip1559'; } - /** @name EthereumTransactionLegacyTransaction (355) */ + /** @name EthereumTransactionLegacyTransaction (356) */ interface EthereumTransactionLegacyTransaction extends Struct { readonly nonce: U256; readonly gasPrice: U256; @@ -3840,7 +3856,7 @@ declare module '@polkadot/types/lookup' { readonly signature: EthereumTransactionTransactionSignature; } - /** @name EthereumTransactionTransactionAction (356) */ + /** @name EthereumTransactionTransactionAction (357) */ interface EthereumTransactionTransactionAction extends Enum { readonly isCall: boolean; readonly asCall: H160; @@ -3848,14 +3864,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Call' | 'Create'; } - /** @name EthereumTransactionTransactionSignature (357) */ + /** @name EthereumTransactionTransactionSignature (358) */ interface EthereumTransactionTransactionSignature extends Struct { readonly v: u64; readonly r: H256; readonly s: H256; } - /** @name EthereumTransactionEip2930Transaction (359) */ + /** @name EthereumTransactionEip2930Transaction (360) */ interface EthereumTransactionEip2930Transaction extends Struct { readonly chainId: u64; readonly nonce: U256; @@ -3870,13 +3886,13 @@ declare module '@polkadot/types/lookup' { readonly s: H256; } - /** @name EthereumTransactionAccessListItem (361) */ + /** @name EthereumTransactionAccessListItem (362) */ interface EthereumTransactionAccessListItem extends Struct { readonly address: H160; readonly storageKeys: Vec; } - /** @name EthereumTransactionEip1559Transaction (362) */ + /** @name EthereumTransactionEip1559Transaction (363) */ interface EthereumTransactionEip1559Transaction extends Struct { readonly chainId: u64; readonly nonce: U256; @@ -3892,7 +3908,7 @@ declare module '@polkadot/types/lookup' { readonly s: H256; } - /** @name PalletEvmCall (363) */ + /** @name PalletEvmCall (364) */ interface PalletEvmCall extends Enum { readonly isWithdraw: boolean; readonly asWithdraw: { @@ -3937,7 +3953,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2'; } - /** @name PalletDynamicFeeCall (367) */ + /** @name PalletDynamicFeeCall (368) */ interface PalletDynamicFeeCall extends Enum { readonly isNoteMinGasPriceTarget: boolean; readonly asNoteMinGasPriceTarget: { @@ -3946,7 +3962,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NoteMinGasPriceTarget'; } - /** @name PalletBaseFeeCall (368) */ + /** @name PalletBaseFeeCall (369) */ interface PalletBaseFeeCall extends Enum { readonly isSetBaseFeePerGas: boolean; readonly asSetBaseFeePerGas: { @@ -3959,7 +3975,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetBaseFeePerGas' | 'SetElasticity'; } - /** @name PalletHotfixSufficientsCall (369) */ + /** @name PalletHotfixSufficientsCall (370) */ interface PalletHotfixSufficientsCall extends Enum { readonly isHotfixIncAccountSufficients: boolean; readonly asHotfixIncAccountSufficients: { @@ -3968,7 +3984,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'HotfixIncAccountSufficients'; } - /** @name PalletAirdropClaimsCall (371) */ + /** @name PalletAirdropClaimsCall (372) */ interface PalletAirdropClaimsCall extends Enum { readonly isClaim: boolean; readonly asClaim: { @@ -4007,7 +4023,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Claim' | 'MintClaim' | 'ClaimAttest' | 'MoveClaim' | 'ForceSetExpiryConfig' | 'ClaimSigned'; } - /** @name PalletAirdropClaimsUtilsMultiAddressSignature (373) */ + /** @name PalletAirdropClaimsUtilsMultiAddressSignature (374) */ interface PalletAirdropClaimsUtilsMultiAddressSignature extends Enum { readonly isEvm: boolean; readonly asEvm: PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature; @@ -4016,20 +4032,20 @@ declare module '@polkadot/types/lookup' { readonly type: 'Evm' | 'Native'; } - /** @name PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature (374) */ + /** @name PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature (375) */ interface PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature extends U8aFixed {} - /** @name PalletAirdropClaimsUtilsSr25519Signature (375) */ + /** @name PalletAirdropClaimsUtilsSr25519Signature (376) */ interface PalletAirdropClaimsUtilsSr25519Signature extends U8aFixed {} - /** @name PalletAirdropClaimsStatementKind (381) */ + /** @name PalletAirdropClaimsStatementKind (382) */ interface PalletAirdropClaimsStatementKind extends Enum { readonly isRegular: boolean; readonly isSafe: boolean; readonly type: 'Regular' | 'Safe'; } - /** @name PalletProxyCall (382) */ + /** @name PalletProxyCall (383) */ interface PalletProxyCall extends Enum { readonly isProxy: boolean; readonly asProxy: { @@ -4089,7 +4105,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Proxy' | 'AddProxy' | 'RemoveProxy' | 'RemoveProxies' | 'CreatePure' | 'KillPure' | 'Announce' | 'RemoveAnnouncement' | 'RejectAnnouncement' | 'ProxyAnnounced'; } - /** @name PalletMultiAssetDelegationCall (384) */ + /** @name PalletMultiAssetDelegationCall (385) */ interface PalletMultiAssetDelegationCall extends Enum { readonly isJoinOperators: boolean; readonly asJoinOperators: { @@ -4112,38 +4128,42 @@ declare module '@polkadot/types/lookup' { readonly isGoOnline: boolean; readonly isDeposit: boolean; readonly asDeposit: { - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; + readonly evmAddress: Option; } & Struct; readonly isScheduleWithdraw: boolean; readonly asScheduleWithdraw: { - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; } & Struct; readonly isExecuteWithdraw: boolean; + readonly asExecuteWithdraw: { + readonly evmAddress: Option; + } & Struct; readonly isCancelWithdraw: boolean; readonly asCancelWithdraw: { - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; } & Struct; readonly isDelegate: boolean; readonly asDelegate: { readonly operator: AccountId32; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; readonly blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; } & Struct; readonly isScheduleDelegatorUnstake: boolean; readonly asScheduleDelegatorUnstake: { readonly operator: AccountId32; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; } & Struct; readonly isExecuteDelegatorUnstake: boolean; readonly isCancelDelegatorUnstake: boolean; readonly asCancelDelegatorUnstake: { readonly operator: AccountId32; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; } & Struct; readonly isSetIncentiveApyAndCap: boolean; @@ -4159,7 +4179,7 @@ declare module '@polkadot/types/lookup' { readonly isManageAssetInVault: boolean; readonly asManageAssetInVault: { readonly vaultId: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly action: PalletMultiAssetDelegationRewardsAssetAction; } & Struct; readonly isAddBlueprintId: boolean; @@ -4173,7 +4193,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'JoinOperators' | 'ScheduleLeaveOperators' | 'CancelLeaveOperators' | 'ExecuteLeaveOperators' | 'OperatorBondMore' | 'ScheduleOperatorUnstake' | 'ExecuteOperatorUnstake' | 'CancelOperatorUnstake' | 'GoOffline' | 'GoOnline' | 'Deposit' | 'ScheduleWithdraw' | 'ExecuteWithdraw' | 'CancelWithdraw' | 'Delegate' | 'ScheduleDelegatorUnstake' | 'ExecuteDelegatorUnstake' | 'CancelDelegatorUnstake' | 'SetIncentiveApyAndCap' | 'WhitelistBlueprintForRewards' | 'ManageAssetInVault' | 'AddBlueprintId' | 'RemoveBlueprintId'; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection (385) */ + /** @name PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection (387) */ interface PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection extends Enum { readonly isFixed: boolean; readonly asFixed: Vec; @@ -4181,10 +4201,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Fixed' | 'All'; } - /** @name TangleTestnetRuntimeMaxDelegatorBlueprints (386) */ + /** @name TangleTestnetRuntimeMaxDelegatorBlueprints (388) */ type TangleTestnetRuntimeMaxDelegatorBlueprints = Null; - /** @name PalletServicesModuleCall (389) */ + /** @name PalletServicesModuleCall (391) */ interface PalletServicesModuleCall extends Enum { readonly isCreateBlueprint: boolean; readonly asCreateBlueprint: { @@ -4212,12 +4232,14 @@ declare module '@polkadot/types/lookup' { } & Struct; readonly isRequest: boolean; readonly asRequest: { + readonly evmOrigin: Option; readonly blueprintId: Compact; readonly permittedCallers: Vec; readonly operators: Vec; readonly requestArgs: Vec; readonly assets: Vec; readonly ttl: Compact; + readonly paymentAsset: TanglePrimitivesServicesAsset; readonly value: Compact; } & Struct; readonly isApprove: boolean; @@ -4263,7 +4285,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'CreateBlueprint' | 'PreRegister' | 'Register' | 'Unregister' | 'UpdatePriceTargets' | 'Request' | 'Approve' | 'Reject' | 'Terminate' | 'Call' | 'SubmitResult' | 'Slash' | 'Dispute' | 'UpdateMasterBlueprintServiceManager'; } - /** @name TanglePrimitivesServicesServiceBlueprint (390) */ + /** @name TanglePrimitivesServicesServiceBlueprint (392) */ interface TanglePrimitivesServicesServiceBlueprint extends Struct { readonly metadata: TanglePrimitivesServicesServiceMetadata; readonly jobs: Vec; @@ -4274,7 +4296,7 @@ declare module '@polkadot/types/lookup' { readonly gadget: TanglePrimitivesServicesGadget; } - /** @name TanglePrimitivesServicesServiceMetadata (391) */ + /** @name TanglePrimitivesServicesServiceMetadata (393) */ interface TanglePrimitivesServicesServiceMetadata extends Struct { readonly name: Bytes; readonly description: Option; @@ -4286,20 +4308,20 @@ declare module '@polkadot/types/lookup' { readonly license: Option; } - /** @name TanglePrimitivesServicesJobDefinition (396) */ + /** @name TanglePrimitivesServicesJobDefinition (398) */ interface TanglePrimitivesServicesJobDefinition extends Struct { readonly metadata: TanglePrimitivesServicesJobMetadata; readonly params: Vec; readonly result: Vec; } - /** @name TanglePrimitivesServicesJobMetadata (397) */ + /** @name TanglePrimitivesServicesJobMetadata (399) */ interface TanglePrimitivesServicesJobMetadata extends Struct { readonly name: Bytes; readonly description: Option; } - /** @name TanglePrimitivesServicesFieldFieldType (399) */ + /** @name TanglePrimitivesServicesFieldFieldType (401) */ interface TanglePrimitivesServicesFieldFieldType extends Enum { readonly isVoid: boolean; readonly isBool: boolean; @@ -4325,14 +4347,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Void' | 'Bool' | 'Uint8' | 'Int8' | 'Uint16' | 'Int16' | 'Uint32' | 'Int32' | 'Uint64' | 'Int64' | 'String' | 'Bytes' | 'Optional' | 'Array' | 'List' | 'Struct' | 'AccountId'; } - /** @name TanglePrimitivesServicesBlueprintServiceManager (405) */ + /** @name TanglePrimitivesServicesBlueprintServiceManager (407) */ interface TanglePrimitivesServicesBlueprintServiceManager extends Enum { readonly isEvm: boolean; readonly asEvm: H160; readonly type: 'Evm'; } - /** @name TanglePrimitivesServicesMasterBlueprintServiceManagerRevision (406) */ + /** @name TanglePrimitivesServicesMasterBlueprintServiceManagerRevision (408) */ interface TanglePrimitivesServicesMasterBlueprintServiceManagerRevision extends Enum { readonly isLatest: boolean; readonly isSpecific: boolean; @@ -4340,7 +4362,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Latest' | 'Specific'; } - /** @name TanglePrimitivesServicesGadget (407) */ + /** @name TanglePrimitivesServicesGadget (409) */ interface TanglePrimitivesServicesGadget extends Enum { readonly isWasm: boolean; readonly asWasm: TanglePrimitivesServicesWasmGadget; @@ -4351,25 +4373,25 @@ declare module '@polkadot/types/lookup' { readonly type: 'Wasm' | 'Native' | 'Container'; } - /** @name TanglePrimitivesServicesWasmGadget (408) */ + /** @name TanglePrimitivesServicesWasmGadget (410) */ interface TanglePrimitivesServicesWasmGadget extends Struct { readonly runtime: TanglePrimitivesServicesWasmRuntime; readonly sources: Vec; } - /** @name TanglePrimitivesServicesWasmRuntime (409) */ + /** @name TanglePrimitivesServicesWasmRuntime (411) */ interface TanglePrimitivesServicesWasmRuntime extends Enum { readonly isWasmtime: boolean; readonly isWasmer: boolean; readonly type: 'Wasmtime' | 'Wasmer'; } - /** @name TanglePrimitivesServicesGadgetSource (411) */ + /** @name TanglePrimitivesServicesGadgetSource (413) */ interface TanglePrimitivesServicesGadgetSource extends Struct { readonly fetcher: TanglePrimitivesServicesGadgetSourceFetcher; } - /** @name TanglePrimitivesServicesGadgetSourceFetcher (412) */ + /** @name TanglePrimitivesServicesGadgetSourceFetcher (414) */ interface TanglePrimitivesServicesGadgetSourceFetcher extends Enum { readonly isIpfs: boolean; readonly asIpfs: Bytes; @@ -4382,7 +4404,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ipfs' | 'Github' | 'ContainerImage' | 'Testing'; } - /** @name TanglePrimitivesServicesGithubFetcher (414) */ + /** @name TanglePrimitivesServicesGithubFetcher (416) */ interface TanglePrimitivesServicesGithubFetcher extends Struct { readonly owner: Bytes; readonly repo: Bytes; @@ -4390,7 +4412,7 @@ declare module '@polkadot/types/lookup' { readonly binaries: Vec; } - /** @name TanglePrimitivesServicesGadgetBinary (422) */ + /** @name TanglePrimitivesServicesGadgetBinary (424) */ interface TanglePrimitivesServicesGadgetBinary extends Struct { readonly arch: TanglePrimitivesServicesArchitecture; readonly os: TanglePrimitivesServicesOperatingSystem; @@ -4398,7 +4420,7 @@ declare module '@polkadot/types/lookup' { readonly sha256: U8aFixed; } - /** @name TanglePrimitivesServicesArchitecture (423) */ + /** @name TanglePrimitivesServicesArchitecture (425) */ interface TanglePrimitivesServicesArchitecture extends Enum { readonly isWasm: boolean; readonly isWasm64: boolean; @@ -4413,7 +4435,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Wasm' | 'Wasm64' | 'Wasi' | 'Wasi64' | 'Amd' | 'Amd64' | 'Arm' | 'Arm64' | 'RiscV' | 'RiscV64'; } - /** @name TanglePrimitivesServicesOperatingSystem (424) */ + /** @name TanglePrimitivesServicesOperatingSystem (426) */ interface TanglePrimitivesServicesOperatingSystem extends Enum { readonly isUnknown: boolean; readonly isLinux: boolean; @@ -4423,31 +4445,31 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unknown' | 'Linux' | 'Windows' | 'MacOS' | 'Bsd'; } - /** @name TanglePrimitivesServicesImageRegistryFetcher (428) */ + /** @name TanglePrimitivesServicesImageRegistryFetcher (430) */ interface TanglePrimitivesServicesImageRegistryFetcher extends Struct { readonly registry_: Bytes; readonly image: Bytes; readonly tag: Bytes; } - /** @name TanglePrimitivesServicesTestFetcher (435) */ + /** @name TanglePrimitivesServicesTestFetcher (437) */ interface TanglePrimitivesServicesTestFetcher extends Struct { readonly cargoPackage: Bytes; readonly cargoBin: Bytes; readonly basePath: Bytes; } - /** @name TanglePrimitivesServicesNativeGadget (437) */ + /** @name TanglePrimitivesServicesNativeGadget (439) */ interface TanglePrimitivesServicesNativeGadget extends Struct { readonly sources: Vec; } - /** @name TanglePrimitivesServicesContainerGadget (438) */ + /** @name TanglePrimitivesServicesContainerGadget (440) */ interface TanglePrimitivesServicesContainerGadget extends Struct { readonly sources: Vec; } - /** @name PalletTangleLstCall (441) */ + /** @name PalletTangleLstCall (443) */ interface PalletTangleLstCall extends Enum { readonly isJoin: boolean; readonly asJoin: { @@ -4565,14 +4587,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Join' | 'BondExtra' | 'Unbond' | 'PoolWithdrawUnbonded' | 'WithdrawUnbonded' | 'Create' | 'CreateWithPoolId' | 'Nominate' | 'SetState' | 'SetMetadata' | 'SetConfigs' | 'UpdateRoles' | 'Chill' | 'BondExtraOther' | 'SetCommission' | 'SetCommissionMax' | 'SetCommissionChangeRate' | 'ClaimCommission' | 'AdjustPoolDeposit' | 'SetCommissionClaimPermission'; } - /** @name PalletTangleLstBondExtra (442) */ + /** @name PalletTangleLstBondExtra (444) */ interface PalletTangleLstBondExtra extends Enum { readonly isFreeBalance: boolean; readonly asFreeBalance: u128; readonly type: 'FreeBalance'; } - /** @name PalletTangleLstConfigOpU128 (447) */ + /** @name PalletTangleLstConfigOpU128 (449) */ interface PalletTangleLstConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4581,7 +4603,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpU32 (448) */ + /** @name PalletTangleLstConfigOpU32 (450) */ interface PalletTangleLstConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4590,7 +4612,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpPerbill (449) */ + /** @name PalletTangleLstConfigOpPerbill (451) */ interface PalletTangleLstConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4599,7 +4621,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpAccountId32 (450) */ + /** @name PalletTangleLstConfigOpAccountId32 (452) */ interface PalletTangleLstConfigOpAccountId32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4608,13 +4630,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletSudoError (451) */ + /** @name PalletSudoError (453) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: 'RequireSudo'; } - /** @name PalletAssetsAssetDetails (453) */ + /** @name PalletAssetsAssetDetails (455) */ interface PalletAssetsAssetDetails extends Struct { readonly owner: AccountId32; readonly issuer: AccountId32; @@ -4630,7 +4652,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletAssetsAssetStatus; } - /** @name PalletAssetsAssetStatus (454) */ + /** @name PalletAssetsAssetStatus (456) */ interface PalletAssetsAssetStatus extends Enum { readonly isLive: boolean; readonly isFrozen: boolean; @@ -4638,7 +4660,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Live' | 'Frozen' | 'Destroying'; } - /** @name PalletAssetsAssetAccount (456) */ + /** @name PalletAssetsAssetAccount (458) */ interface PalletAssetsAssetAccount extends Struct { readonly balance: u128; readonly status: PalletAssetsAccountStatus; @@ -4646,7 +4668,7 @@ declare module '@polkadot/types/lookup' { readonly extra: Null; } - /** @name PalletAssetsAccountStatus (457) */ + /** @name PalletAssetsAccountStatus (459) */ interface PalletAssetsAccountStatus extends Enum { readonly isLiquid: boolean; readonly isFrozen: boolean; @@ -4654,7 +4676,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Liquid' | 'Frozen' | 'Blocked'; } - /** @name PalletAssetsExistenceReason (458) */ + /** @name PalletAssetsExistenceReason (460) */ interface PalletAssetsExistenceReason extends Enum { readonly isConsumer: boolean; readonly isSufficient: boolean; @@ -4666,13 +4688,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Consumer' | 'Sufficient' | 'DepositHeld' | 'DepositRefunded' | 'DepositFrom'; } - /** @name PalletAssetsApproval (460) */ + /** @name PalletAssetsApproval (462) */ interface PalletAssetsApproval extends Struct { readonly amount: u128; readonly deposit: u128; } - /** @name PalletAssetsAssetMetadata (461) */ + /** @name PalletAssetsAssetMetadata (463) */ interface PalletAssetsAssetMetadata extends Struct { readonly deposit: u128; readonly name: Bytes; @@ -4681,7 +4703,7 @@ declare module '@polkadot/types/lookup' { readonly isFrozen: bool; } - /** @name PalletAssetsError (463) */ + /** @name PalletAssetsError (465) */ interface PalletAssetsError extends Enum { readonly isBalanceLow: boolean; readonly isNoAccount: boolean; @@ -4707,14 +4729,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'BalanceLow' | 'NoAccount' | 'NoPermission' | 'Unknown' | 'Frozen' | 'InUse' | 'BadWitness' | 'MinBalanceZero' | 'UnavailableConsumer' | 'BadMetadata' | 'Unapproved' | 'WouldDie' | 'AlreadyExists' | 'NoDeposit' | 'WouldBurn' | 'LiveAsset' | 'AssetNotLive' | 'IncorrectStatus' | 'NotFrozen' | 'CallbackFailed' | 'BadAssetId'; } - /** @name PalletBalancesBalanceLock (465) */ + /** @name PalletBalancesBalanceLock (467) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (466) */ + /** @name PalletBalancesReasons (468) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -4722,38 +4744,38 @@ declare module '@polkadot/types/lookup' { readonly type: 'Fee' | 'Misc' | 'All'; } - /** @name PalletBalancesReserveData (469) */ + /** @name PalletBalancesReserveData (471) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name FrameSupportTokensMiscIdAmountRuntimeHoldReason (472) */ + /** @name FrameSupportTokensMiscIdAmountRuntimeHoldReason (474) */ interface FrameSupportTokensMiscIdAmountRuntimeHoldReason extends Struct { readonly id: TangleTestnetRuntimeRuntimeHoldReason; readonly amount: u128; } - /** @name TangleTestnetRuntimeRuntimeHoldReason (473) */ + /** @name TangleTestnetRuntimeRuntimeHoldReason (475) */ interface TangleTestnetRuntimeRuntimeHoldReason extends Enum { readonly isPreimage: boolean; readonly asPreimage: PalletPreimageHoldReason; readonly type: 'Preimage'; } - /** @name PalletPreimageHoldReason (474) */ + /** @name PalletPreimageHoldReason (476) */ interface PalletPreimageHoldReason extends Enum { readonly isPreimage: boolean; readonly type: 'Preimage'; } - /** @name FrameSupportTokensMiscIdAmountRuntimeFreezeReason (477) */ + /** @name FrameSupportTokensMiscIdAmountRuntimeFreezeReason (479) */ interface FrameSupportTokensMiscIdAmountRuntimeFreezeReason extends Struct { readonly id: TangleTestnetRuntimeRuntimeFreezeReason; readonly amount: u128; } - /** @name TangleTestnetRuntimeRuntimeFreezeReason (478) */ + /** @name TangleTestnetRuntimeRuntimeFreezeReason (480) */ interface TangleTestnetRuntimeRuntimeFreezeReason extends Enum { readonly isNominationPools: boolean; readonly asNominationPools: PalletNominationPoolsFreezeReason; @@ -4762,19 +4784,19 @@ declare module '@polkadot/types/lookup' { readonly type: 'NominationPools' | 'Lst'; } - /** @name PalletNominationPoolsFreezeReason (479) */ + /** @name PalletNominationPoolsFreezeReason (481) */ interface PalletNominationPoolsFreezeReason extends Enum { readonly isPoolMinBalance: boolean; readonly type: 'PoolMinBalance'; } - /** @name PalletTangleLstFreezeReason (480) */ + /** @name PalletTangleLstFreezeReason (482) */ interface PalletTangleLstFreezeReason extends Enum { readonly isPoolMinBalance: boolean; readonly type: 'PoolMinBalance'; } - /** @name PalletBalancesError (482) */ + /** @name PalletBalancesError (484) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -4791,14 +4813,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'Expendability' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves' | 'TooManyHolds' | 'TooManyFreezes' | 'IssuanceDeactivated' | 'DeltaZero'; } - /** @name PalletTransactionPaymentReleases (484) */ + /** @name PalletTransactionPaymentReleases (486) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: 'V1Ancient' | 'V2'; } - /** @name SpConsensusBabeDigestsPreDigest (491) */ + /** @name SpConsensusBabeDigestsPreDigest (493) */ interface SpConsensusBabeDigestsPreDigest extends Enum { readonly isPrimary: boolean; readonly asPrimary: SpConsensusBabeDigestsPrimaryPreDigest; @@ -4809,39 +4831,39 @@ declare module '@polkadot/types/lookup' { readonly type: 'Primary' | 'SecondaryPlain' | 'SecondaryVRF'; } - /** @name SpConsensusBabeDigestsPrimaryPreDigest (492) */ + /** @name SpConsensusBabeDigestsPrimaryPreDigest (494) */ interface SpConsensusBabeDigestsPrimaryPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; readonly vrfSignature: SpCoreSr25519VrfVrfSignature; } - /** @name SpCoreSr25519VrfVrfSignature (493) */ + /** @name SpCoreSr25519VrfVrfSignature (495) */ interface SpCoreSr25519VrfVrfSignature extends Struct { readonly preOutput: U8aFixed; readonly proof: U8aFixed; } - /** @name SpConsensusBabeDigestsSecondaryPlainPreDigest (494) */ + /** @name SpConsensusBabeDigestsSecondaryPlainPreDigest (496) */ interface SpConsensusBabeDigestsSecondaryPlainPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; } - /** @name SpConsensusBabeDigestsSecondaryVRFPreDigest (495) */ + /** @name SpConsensusBabeDigestsSecondaryVRFPreDigest (497) */ interface SpConsensusBabeDigestsSecondaryVRFPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; readonly vrfSignature: SpCoreSr25519VrfVrfSignature; } - /** @name SpConsensusBabeBabeEpochConfiguration (496) */ + /** @name SpConsensusBabeBabeEpochConfiguration (498) */ interface SpConsensusBabeBabeEpochConfiguration extends Struct { readonly c: ITuple<[u64, u64]>; readonly allowedSlots: SpConsensusBabeAllowedSlots; } - /** @name PalletBabeError (498) */ + /** @name PalletBabeError (500) */ interface PalletBabeError extends Enum { readonly isInvalidEquivocationProof: boolean; readonly isInvalidKeyOwnershipProof: boolean; @@ -4850,7 +4872,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidEquivocationProof' | 'InvalidKeyOwnershipProof' | 'DuplicateOffenceReport' | 'InvalidConfiguration'; } - /** @name PalletGrandpaStoredState (499) */ + /** @name PalletGrandpaStoredState (501) */ interface PalletGrandpaStoredState extends Enum { readonly isLive: boolean; readonly isPendingPause: boolean; @@ -4867,7 +4889,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Live' | 'PendingPause' | 'Paused' | 'PendingResume'; } - /** @name PalletGrandpaStoredPendingChange (500) */ + /** @name PalletGrandpaStoredPendingChange (502) */ interface PalletGrandpaStoredPendingChange extends Struct { readonly scheduledAt: u64; readonly delay: u64; @@ -4875,7 +4897,7 @@ declare module '@polkadot/types/lookup' { readonly forced: Option; } - /** @name PalletGrandpaError (502) */ + /** @name PalletGrandpaError (504) */ interface PalletGrandpaError extends Enum { readonly isPauseFailed: boolean; readonly isResumeFailed: boolean; @@ -4887,7 +4909,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PauseFailed' | 'ResumeFailed' | 'ChangePending' | 'TooSoon' | 'InvalidKeyOwnershipProof' | 'InvalidEquivocationProof' | 'DuplicateOffenceReport'; } - /** @name PalletIndicesError (504) */ + /** @name PalletIndicesError (506) */ interface PalletIndicesError extends Enum { readonly isNotAssigned: boolean; readonly isNotOwner: boolean; @@ -4897,7 +4919,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotAssigned' | 'NotOwner' | 'InUse' | 'NotTransfer' | 'Permanent'; } - /** @name PalletDemocracyReferendumInfo (509) */ + /** @name PalletDemocracyReferendumInfo (511) */ interface PalletDemocracyReferendumInfo extends Enum { readonly isOngoing: boolean; readonly asOngoing: PalletDemocracyReferendumStatus; @@ -4909,7 +4931,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ongoing' | 'Finished'; } - /** @name PalletDemocracyReferendumStatus (510) */ + /** @name PalletDemocracyReferendumStatus (512) */ interface PalletDemocracyReferendumStatus extends Struct { readonly end: u64; readonly proposal: FrameSupportPreimagesBounded; @@ -4918,14 +4940,14 @@ declare module '@polkadot/types/lookup' { readonly tally: PalletDemocracyTally; } - /** @name PalletDemocracyTally (511) */ + /** @name PalletDemocracyTally (513) */ interface PalletDemocracyTally extends Struct { readonly ayes: u128; readonly nays: u128; readonly turnout: u128; } - /** @name PalletDemocracyVoteVoting (512) */ + /** @name PalletDemocracyVoteVoting (514) */ interface PalletDemocracyVoteVoting extends Enum { readonly isDirect: boolean; readonly asDirect: { @@ -4944,16 +4966,16 @@ declare module '@polkadot/types/lookup' { readonly type: 'Direct' | 'Delegating'; } - /** @name PalletDemocracyDelegations (516) */ + /** @name PalletDemocracyDelegations (518) */ interface PalletDemocracyDelegations extends Struct { readonly votes: u128; readonly capital: u128; } - /** @name PalletDemocracyVotePriorLock (517) */ + /** @name PalletDemocracyVotePriorLock (519) */ interface PalletDemocracyVotePriorLock extends ITuple<[u64, u128]> {} - /** @name PalletDemocracyError (520) */ + /** @name PalletDemocracyError (522) */ interface PalletDemocracyError extends Enum { readonly isValueLow: boolean; readonly isProposalMissing: boolean; @@ -4982,7 +5004,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ValueLow' | 'ProposalMissing' | 'AlreadyCanceled' | 'DuplicateProposal' | 'ProposalBlacklisted' | 'NotSimpleMajority' | 'InvalidHash' | 'NoProposal' | 'AlreadyVetoed' | 'ReferendumInvalid' | 'NoneWaiting' | 'NotVoter' | 'NoPermission' | 'AlreadyDelegating' | 'InsufficientFunds' | 'NotDelegating' | 'VotesExist' | 'InstantNotAllowed' | 'Nonsense' | 'WrongUpperBound' | 'MaxVotesReached' | 'TooMany' | 'VotingPeriodLow' | 'PreimageNotExist'; } - /** @name PalletCollectiveVotes (522) */ + /** @name PalletCollectiveVotes (524) */ interface PalletCollectiveVotes extends Struct { readonly index: u32; readonly threshold: u32; @@ -4991,7 +5013,7 @@ declare module '@polkadot/types/lookup' { readonly end: u64; } - /** @name PalletCollectiveError (523) */ + /** @name PalletCollectiveError (525) */ interface PalletCollectiveError extends Enum { readonly isNotMember: boolean; readonly isDuplicateProposal: boolean; @@ -5007,14 +5029,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotMember' | 'DuplicateProposal' | 'ProposalMissing' | 'WrongIndex' | 'DuplicateVote' | 'AlreadyInitialized' | 'TooEarly' | 'TooManyProposals' | 'WrongProposalWeight' | 'WrongProposalLength' | 'PrimeAccountNotMember'; } - /** @name PalletVestingReleases (526) */ + /** @name PalletVestingReleases (528) */ interface PalletVestingReleases extends Enum { readonly isV0: boolean; readonly isV1: boolean; readonly type: 'V0' | 'V1'; } - /** @name PalletVestingError (527) */ + /** @name PalletVestingError (529) */ interface PalletVestingError extends Enum { readonly isNotVesting: boolean; readonly isAtMaxVestingSchedules: boolean; @@ -5024,21 +5046,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotVesting' | 'AtMaxVestingSchedules' | 'AmountLow' | 'ScheduleIndexOutOfBounds' | 'InvalidScheduleParams'; } - /** @name PalletElectionsPhragmenSeatHolder (529) */ + /** @name PalletElectionsPhragmenSeatHolder (531) */ interface PalletElectionsPhragmenSeatHolder extends Struct { readonly who: AccountId32; readonly stake: u128; readonly deposit: u128; } - /** @name PalletElectionsPhragmenVoter (530) */ + /** @name PalletElectionsPhragmenVoter (532) */ interface PalletElectionsPhragmenVoter extends Struct { readonly votes: Vec; readonly stake: u128; readonly deposit: u128; } - /** @name PalletElectionsPhragmenError (531) */ + /** @name PalletElectionsPhragmenError (533) */ interface PalletElectionsPhragmenError extends Enum { readonly isUnableToVote: boolean; readonly isNoVotes: boolean; @@ -5060,20 +5082,20 @@ declare module '@polkadot/types/lookup' { readonly type: 'UnableToVote' | 'NoVotes' | 'TooManyVotes' | 'MaximumVotesExceeded' | 'LowBalance' | 'UnableToPayBond' | 'MustBeVoter' | 'DuplicatedCandidate' | 'TooManyCandidates' | 'MemberSubmit' | 'RunnerUpSubmit' | 'InsufficientCandidateFunds' | 'NotMember' | 'InvalidWitnessData' | 'InvalidVoteCount' | 'InvalidRenouncing' | 'InvalidReplacement'; } - /** @name PalletElectionProviderMultiPhaseReadySolution (532) */ + /** @name PalletElectionProviderMultiPhaseReadySolution (534) */ interface PalletElectionProviderMultiPhaseReadySolution extends Struct { readonly supports: Vec>; readonly score: SpNposElectionsElectionScore; readonly compute: PalletElectionProviderMultiPhaseElectionCompute; } - /** @name PalletElectionProviderMultiPhaseRoundSnapshot (534) */ + /** @name PalletElectionProviderMultiPhaseRoundSnapshot (536) */ interface PalletElectionProviderMultiPhaseRoundSnapshot extends Struct { readonly voters: Vec]>>; readonly targets: Vec; } - /** @name PalletElectionProviderMultiPhaseSignedSignedSubmission (541) */ + /** @name PalletElectionProviderMultiPhaseSignedSignedSubmission (543) */ interface PalletElectionProviderMultiPhaseSignedSignedSubmission extends Struct { readonly who: AccountId32; readonly deposit: u128; @@ -5081,7 +5103,7 @@ declare module '@polkadot/types/lookup' { readonly callFee: u128; } - /** @name PalletElectionProviderMultiPhaseError (542) */ + /** @name PalletElectionProviderMultiPhaseError (544) */ interface PalletElectionProviderMultiPhaseError extends Enum { readonly isPreDispatchEarlySubmission: boolean; readonly isPreDispatchWrongWinnerCount: boolean; @@ -5101,7 +5123,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PreDispatchEarlySubmission' | 'PreDispatchWrongWinnerCount' | 'PreDispatchWeakSubmission' | 'SignedQueueFull' | 'SignedCannotPayDeposit' | 'SignedInvalidWitness' | 'SignedTooMuchWeight' | 'OcwCallWrongEra' | 'MissingSnapshotMetadata' | 'InvalidSubmissionIndex' | 'CallNotAllowed' | 'FallbackFailed' | 'BoundNotMet' | 'TooManyWinners' | 'PreDispatchDifferentRound'; } - /** @name PalletStakingStakingLedger (543) */ + /** @name PalletStakingStakingLedger (545) */ interface PalletStakingStakingLedger extends Struct { readonly stash: AccountId32; readonly total: Compact; @@ -5110,20 +5132,20 @@ declare module '@polkadot/types/lookup' { readonly legacyClaimedRewards: Vec; } - /** @name PalletStakingNominations (545) */ + /** @name PalletStakingNominations (547) */ interface PalletStakingNominations extends Struct { readonly targets: Vec; readonly submittedIn: u32; readonly suppressed: bool; } - /** @name PalletStakingActiveEraInfo (546) */ + /** @name PalletStakingActiveEraInfo (548) */ interface PalletStakingActiveEraInfo extends Struct { readonly index: u32; readonly start: Option; } - /** @name SpStakingPagedExposureMetadata (548) */ + /** @name SpStakingPagedExposureMetadata (550) */ interface SpStakingPagedExposureMetadata extends Struct { readonly total: Compact; readonly own: Compact; @@ -5131,19 +5153,19 @@ declare module '@polkadot/types/lookup' { readonly pageCount: u32; } - /** @name SpStakingExposurePage (550) */ + /** @name SpStakingExposurePage (552) */ interface SpStakingExposurePage extends Struct { readonly pageTotal: Compact; readonly others: Vec; } - /** @name PalletStakingEraRewardPoints (551) */ + /** @name PalletStakingEraRewardPoints (553) */ interface PalletStakingEraRewardPoints extends Struct { readonly total: u32; readonly individual: BTreeMap; } - /** @name PalletStakingUnappliedSlash (556) */ + /** @name PalletStakingUnappliedSlash (558) */ interface PalletStakingUnappliedSlash extends Struct { readonly validator: AccountId32; readonly own: u128; @@ -5152,7 +5174,7 @@ declare module '@polkadot/types/lookup' { readonly payout: u128; } - /** @name PalletStakingSlashingSlashingSpans (560) */ + /** @name PalletStakingSlashingSlashingSpans (562) */ interface PalletStakingSlashingSlashingSpans extends Struct { readonly spanIndex: u32; readonly lastStart: u32; @@ -5160,13 +5182,13 @@ declare module '@polkadot/types/lookup' { readonly prior: Vec; } - /** @name PalletStakingSlashingSpanRecord (561) */ + /** @name PalletStakingSlashingSpanRecord (563) */ interface PalletStakingSlashingSpanRecord extends Struct { readonly slashed: u128; readonly paidOut: u128; } - /** @name PalletStakingPalletError (562) */ + /** @name PalletStakingPalletError (564) */ interface PalletStakingPalletError extends Enum { readonly isNotController: boolean; readonly isNotStash: boolean; @@ -5202,10 +5224,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotController' | 'NotStash' | 'AlreadyBonded' | 'AlreadyPaired' | 'EmptyTargets' | 'DuplicateIndex' | 'InvalidSlashIndex' | 'InsufficientBond' | 'NoMoreChunks' | 'NoUnlockChunk' | 'FundedTarget' | 'InvalidEraToReward' | 'InvalidNumberOfNominations' | 'NotSortedAndUnique' | 'AlreadyClaimed' | 'InvalidPage' | 'IncorrectHistoryDepth' | 'IncorrectSlashingSpans' | 'BadState' | 'TooManyTargets' | 'BadTarget' | 'CannotChillOther' | 'TooManyNominators' | 'TooManyValidators' | 'CommissionTooLow' | 'BoundNotMet' | 'ControllerDeprecated' | 'CannotRestoreLedger' | 'RewardDestinationRestricted' | 'NotEnoughFunds' | 'VirtualStakerNotAllowed'; } - /** @name SpCoreCryptoKeyTypeId (566) */ + /** @name SpCoreCryptoKeyTypeId (568) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (567) */ + /** @name PalletSessionError (569) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -5215,7 +5237,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidProof' | 'NoAssociatedValidatorId' | 'DuplicatedKey' | 'NoKeys' | 'NoAccount'; } - /** @name PalletTreasuryProposal (569) */ + /** @name PalletTreasuryProposal (571) */ interface PalletTreasuryProposal extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -5223,7 +5245,7 @@ declare module '@polkadot/types/lookup' { readonly bond: u128; } - /** @name PalletTreasurySpendStatus (571) */ + /** @name PalletTreasurySpendStatus (573) */ interface PalletTreasurySpendStatus extends Struct { readonly assetKind: Null; readonly amount: u128; @@ -5233,7 +5255,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletTreasuryPaymentState; } - /** @name PalletTreasuryPaymentState (572) */ + /** @name PalletTreasuryPaymentState (574) */ interface PalletTreasuryPaymentState extends Enum { readonly isPending: boolean; readonly isAttempted: boolean; @@ -5244,10 +5266,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pending' | 'Attempted' | 'Failed'; } - /** @name FrameSupportPalletId (573) */ + /** @name FrameSupportPalletId (575) */ interface FrameSupportPalletId extends U8aFixed {} - /** @name PalletTreasuryError (574) */ + /** @name PalletTreasuryError (576) */ interface PalletTreasuryError extends Enum { readonly isInvalidIndex: boolean; readonly isTooManyApprovals: boolean; @@ -5263,7 +5285,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidIndex' | 'TooManyApprovals' | 'InsufficientPermission' | 'ProposalNotApproved' | 'FailedToConvertBalance' | 'SpendExpired' | 'EarlyPayout' | 'AlreadyAttempted' | 'PayoutError' | 'NotAttempted' | 'Inconclusive'; } - /** @name PalletBountiesBounty (575) */ + /** @name PalletBountiesBounty (577) */ interface PalletBountiesBounty extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -5273,7 +5295,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletBountiesBountyStatus; } - /** @name PalletBountiesBountyStatus (576) */ + /** @name PalletBountiesBountyStatus (578) */ interface PalletBountiesBountyStatus extends Enum { readonly isProposed: boolean; readonly isApproved: boolean; @@ -5296,7 +5318,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Proposed' | 'Approved' | 'Funded' | 'CuratorProposed' | 'Active' | 'PendingPayout'; } - /** @name PalletBountiesError (578) */ + /** @name PalletBountiesError (580) */ interface PalletBountiesError extends Enum { readonly isInsufficientProposersBalance: boolean; readonly isInvalidIndex: boolean; @@ -5312,7 +5334,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'ReasonTooBig' | 'UnexpectedStatus' | 'RequireCurator' | 'InvalidValue' | 'InvalidFee' | 'PendingPayout' | 'Premature' | 'HasActiveChildBounty' | 'TooManyQueued'; } - /** @name PalletChildBountiesChildBounty (579) */ + /** @name PalletChildBountiesChildBounty (581) */ interface PalletChildBountiesChildBounty extends Struct { readonly parentBounty: u32; readonly value: u128; @@ -5321,7 +5343,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletChildBountiesChildBountyStatus; } - /** @name PalletChildBountiesChildBountyStatus (580) */ + /** @name PalletChildBountiesChildBountyStatus (582) */ interface PalletChildBountiesChildBountyStatus extends Enum { readonly isAdded: boolean; readonly isCuratorProposed: boolean; @@ -5341,7 +5363,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Added' | 'CuratorProposed' | 'Active' | 'PendingPayout'; } - /** @name PalletChildBountiesError (581) */ + /** @name PalletChildBountiesError (583) */ interface PalletChildBountiesError extends Enum { readonly isParentBountyNotActive: boolean; readonly isInsufficientBountyBalance: boolean; @@ -5349,7 +5371,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ParentBountyNotActive' | 'InsufficientBountyBalance' | 'TooManyChildBounties'; } - /** @name PalletBagsListListNode (582) */ + /** @name PalletBagsListListNode (584) */ interface PalletBagsListListNode extends Struct { readonly id: AccountId32; readonly prev: Option; @@ -5358,20 +5380,20 @@ declare module '@polkadot/types/lookup' { readonly score: u64; } - /** @name PalletBagsListListBag (583) */ + /** @name PalletBagsListListBag (585) */ interface PalletBagsListListBag extends Struct { readonly head: Option; readonly tail: Option; } - /** @name PalletBagsListError (584) */ + /** @name PalletBagsListError (586) */ interface PalletBagsListError extends Enum { readonly isList: boolean; readonly asList: PalletBagsListListListError; readonly type: 'List'; } - /** @name PalletBagsListListListError (585) */ + /** @name PalletBagsListListListError (587) */ interface PalletBagsListListListError extends Enum { readonly isDuplicate: boolean; readonly isNotHeavier: boolean; @@ -5380,7 +5402,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Duplicate' | 'NotHeavier' | 'NotInSameBag' | 'NodeNotFound'; } - /** @name PalletNominationPoolsPoolMember (586) */ + /** @name PalletNominationPoolsPoolMember (588) */ interface PalletNominationPoolsPoolMember extends Struct { readonly poolId: u32; readonly points: u128; @@ -5388,7 +5410,7 @@ declare module '@polkadot/types/lookup' { readonly unbondingEras: BTreeMap; } - /** @name PalletNominationPoolsBondedPoolInner (591) */ + /** @name PalletNominationPoolsBondedPoolInner (593) */ interface PalletNominationPoolsBondedPoolInner extends Struct { readonly commission: PalletNominationPoolsCommission; readonly memberCounter: u32; @@ -5397,7 +5419,7 @@ declare module '@polkadot/types/lookup' { readonly state: PalletNominationPoolsPoolState; } - /** @name PalletNominationPoolsCommission (592) */ + /** @name PalletNominationPoolsCommission (594) */ interface PalletNominationPoolsCommission extends Struct { readonly current: Option>; readonly max: Option; @@ -5406,7 +5428,7 @@ declare module '@polkadot/types/lookup' { readonly claimPermission: Option; } - /** @name PalletNominationPoolsPoolRoles (595) */ + /** @name PalletNominationPoolsPoolRoles (597) */ interface PalletNominationPoolsPoolRoles extends Struct { readonly depositor: AccountId32; readonly root: Option; @@ -5414,7 +5436,7 @@ declare module '@polkadot/types/lookup' { readonly bouncer: Option; } - /** @name PalletNominationPoolsRewardPool (596) */ + /** @name PalletNominationPoolsRewardPool (598) */ interface PalletNominationPoolsRewardPool extends Struct { readonly lastRecordedRewardCounter: u128; readonly lastRecordedTotalPayouts: u128; @@ -5423,19 +5445,19 @@ declare module '@polkadot/types/lookup' { readonly totalCommissionClaimed: u128; } - /** @name PalletNominationPoolsSubPools (597) */ + /** @name PalletNominationPoolsSubPools (599) */ interface PalletNominationPoolsSubPools extends Struct { readonly noEra: PalletNominationPoolsUnbondPool; readonly withEra: BTreeMap; } - /** @name PalletNominationPoolsUnbondPool (598) */ + /** @name PalletNominationPoolsUnbondPool (600) */ interface PalletNominationPoolsUnbondPool extends Struct { readonly points: u128; readonly balance: u128; } - /** @name PalletNominationPoolsError (603) */ + /** @name PalletNominationPoolsError (605) */ interface PalletNominationPoolsError extends Enum { readonly isPoolNotFound: boolean; readonly isPoolMemberNotFound: boolean; @@ -5477,7 +5499,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PoolNotFound' | 'PoolMemberNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'AccountBelongsToOtherPool' | 'FullyUnbonding' | 'MaxUnbondingLimit' | 'CannotWithdrawAny' | 'MinimumBondNotMet' | 'OverflowRisk' | 'NotDestroying' | 'NotNominator' | 'NotKickerOrDestroying' | 'NotOpen' | 'MaxPools' | 'MaxPoolMembers' | 'CanNotChangeState' | 'DoesNotHavePermission' | 'MetadataExceedsMaxLen' | 'Defensive' | 'PartialUnbondNotAllowedPermissionlessly' | 'MaxCommissionRestricted' | 'CommissionExceedsMaximum' | 'CommissionExceedsGlobalMaximum' | 'CommissionChangeThrottled' | 'CommissionChangeRateNotAllowed' | 'NoPendingCommission' | 'NoCommissionCurrentSet' | 'PoolIdInUse' | 'InvalidPoolId' | 'BondExtraRestricted' | 'NothingToAdjust' | 'NothingToSlash' | 'AlreadyMigrated' | 'NotMigrated' | 'NotSupported'; } - /** @name PalletNominationPoolsDefensiveError (604) */ + /** @name PalletNominationPoolsDefensiveError (606) */ interface PalletNominationPoolsDefensiveError extends Enum { readonly isNotEnoughSpaceInUnbondPool: boolean; readonly isPoolNotFound: boolean; @@ -5489,7 +5511,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotEnoughSpaceInUnbondPool' | 'PoolNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'BondedStashKilledPrematurely' | 'DelegationUnsupported' | 'SlashNotApplied'; } - /** @name PalletSchedulerScheduled (607) */ + /** @name PalletSchedulerScheduled (609) */ interface PalletSchedulerScheduled extends Struct { readonly maybeId: Option; readonly priority: u8; @@ -5498,14 +5520,14 @@ declare module '@polkadot/types/lookup' { readonly origin: TangleTestnetRuntimeOriginCaller; } - /** @name PalletSchedulerRetryConfig (609) */ + /** @name PalletSchedulerRetryConfig (611) */ interface PalletSchedulerRetryConfig extends Struct { readonly totalRetries: u8; readonly remaining: u8; readonly period: u64; } - /** @name PalletSchedulerError (610) */ + /** @name PalletSchedulerError (612) */ interface PalletSchedulerError extends Enum { readonly isFailedToSchedule: boolean; readonly isNotFound: boolean; @@ -5515,7 +5537,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange' | 'Named'; } - /** @name PalletPreimageOldRequestStatus (611) */ + /** @name PalletPreimageOldRequestStatus (613) */ interface PalletPreimageOldRequestStatus extends Enum { readonly isUnrequested: boolean; readonly asUnrequested: { @@ -5531,7 +5553,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unrequested' | 'Requested'; } - /** @name PalletPreimageRequestStatus (613) */ + /** @name PalletPreimageRequestStatus (615) */ interface PalletPreimageRequestStatus extends Enum { readonly isUnrequested: boolean; readonly asUnrequested: { @@ -5547,7 +5569,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unrequested' | 'Requested'; } - /** @name PalletPreimageError (617) */ + /** @name PalletPreimageError (619) */ interface PalletPreimageError extends Enum { readonly isTooBig: boolean; readonly isAlreadyNoted: boolean; @@ -5561,13 +5583,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooBig' | 'AlreadyNoted' | 'NotAuthorized' | 'NotNoted' | 'Requested' | 'NotRequested' | 'TooMany' | 'TooFew' | 'NoCost'; } - /** @name SpStakingOffenceOffenceDetails (618) */ + /** @name SpStakingOffenceOffenceDetails (620) */ interface SpStakingOffenceOffenceDetails extends Struct { readonly offender: ITuple<[AccountId32, SpStakingExposure]>; readonly reporters: Vec; } - /** @name PalletTxPauseError (620) */ + /** @name PalletTxPauseError (622) */ interface PalletTxPauseError extends Enum { readonly isIsPaused: boolean; readonly isIsUnpaused: boolean; @@ -5576,34 +5598,34 @@ declare module '@polkadot/types/lookup' { readonly type: 'IsPaused' | 'IsUnpaused' | 'Unpausable' | 'NotFound'; } - /** @name PalletImOnlineError (623) */ + /** @name PalletImOnlineError (625) */ interface PalletImOnlineError extends Enum { readonly isInvalidKey: boolean; readonly isDuplicatedHeartbeat: boolean; readonly type: 'InvalidKey' | 'DuplicatedHeartbeat'; } - /** @name PalletIdentityRegistration (625) */ + /** @name PalletIdentityRegistration (627) */ interface PalletIdentityRegistration extends Struct { readonly judgements: Vec>; readonly deposit: u128; readonly info: PalletIdentityLegacyIdentityInfo; } - /** @name PalletIdentityRegistrarInfo (634) */ + /** @name PalletIdentityRegistrarInfo (636) */ interface PalletIdentityRegistrarInfo extends Struct { readonly account: AccountId32; readonly fee: u128; readonly fields: u64; } - /** @name PalletIdentityAuthorityProperties (636) */ + /** @name PalletIdentityAuthorityProperties (638) */ interface PalletIdentityAuthorityProperties extends Struct { readonly suffix: Bytes; readonly allocation: u32; } - /** @name PalletIdentityError (639) */ + /** @name PalletIdentityError (641) */ interface PalletIdentityError extends Enum { readonly isTooManySubAccounts: boolean; readonly isNotFound: boolean; @@ -5634,13 +5656,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooManySubAccounts' | 'NotFound' | 'NotNamed' | 'EmptyIndex' | 'FeeChanged' | 'NoIdentity' | 'StickyJudgement' | 'JudgementGiven' | 'InvalidJudgement' | 'InvalidIndex' | 'InvalidTarget' | 'TooManyRegistrars' | 'AlreadyClaimed' | 'NotSub' | 'NotOwned' | 'JudgementForDifferentIdentity' | 'JudgementPaymentFailed' | 'InvalidSuffix' | 'NotUsernameAuthority' | 'NoAllocation' | 'InvalidSignature' | 'RequiresSignature' | 'InvalidUsername' | 'UsernameTaken' | 'NoUsername' | 'NotExpired'; } - /** @name PalletUtilityError (640) */ + /** @name PalletUtilityError (642) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: 'TooManyCalls'; } - /** @name PalletMultisigMultisig (642) */ + /** @name PalletMultisigMultisig (644) */ interface PalletMultisigMultisig extends Struct { readonly when: PalletMultisigTimepoint; readonly deposit: u128; @@ -5648,7 +5670,7 @@ declare module '@polkadot/types/lookup' { readonly approvals: Vec; } - /** @name PalletMultisigError (643) */ + /** @name PalletMultisigError (645) */ interface PalletMultisigError extends Enum { readonly isMinimumThreshold: boolean; readonly isAlreadyApproved: boolean; @@ -5667,7 +5689,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'MinimumThreshold' | 'AlreadyApproved' | 'NoApprovalsNeeded' | 'TooFewSignatories' | 'TooManySignatories' | 'SignatoriesOutOfOrder' | 'SenderInSignatories' | 'NotFound' | 'NotOwner' | 'NoTimepoint' | 'WrongTimepoint' | 'UnexpectedTimepoint' | 'MaxWeightTooLow' | 'AlreadyStored'; } - /** @name FpRpcTransactionStatus (646) */ + /** @name FpRpcTransactionStatus (648) */ interface FpRpcTransactionStatus extends Struct { readonly transactionHash: H256; readonly transactionIndex: u32; @@ -5678,10 +5700,10 @@ declare module '@polkadot/types/lookup' { readonly logsBloom: EthbloomBloom; } - /** @name EthbloomBloom (649) */ + /** @name EthbloomBloom (650) */ interface EthbloomBloom extends U8aFixed {} - /** @name EthereumReceiptReceiptV3 (651) */ + /** @name EthereumReceiptReceiptV3 (652) */ interface EthereumReceiptReceiptV3 extends Enum { readonly isLegacy: boolean; readonly asLegacy: EthereumReceiptEip658ReceiptData; @@ -5692,7 +5714,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Eip2930' | 'Eip1559'; } - /** @name EthereumReceiptEip658ReceiptData (652) */ + /** @name EthereumReceiptEip658ReceiptData (653) */ interface EthereumReceiptEip658ReceiptData extends Struct { readonly statusCode: u8; readonly usedGas: U256; @@ -5700,14 +5722,14 @@ declare module '@polkadot/types/lookup' { readonly logs: Vec; } - /** @name EthereumBlock (653) */ + /** @name EthereumBlock (654) */ interface EthereumBlock extends Struct { readonly header: EthereumHeader; readonly transactions: Vec; readonly ommers: Vec; } - /** @name EthereumHeader (654) */ + /** @name EthereumHeader (655) */ interface EthereumHeader extends Struct { readonly parentHash: H256; readonly ommersHash: H256; @@ -5726,23 +5748,23 @@ declare module '@polkadot/types/lookup' { readonly nonce: EthereumTypesHashH64; } - /** @name EthereumTypesHashH64 (655) */ + /** @name EthereumTypesHashH64 (656) */ interface EthereumTypesHashH64 extends U8aFixed {} - /** @name PalletEthereumError (660) */ + /** @name PalletEthereumError (661) */ interface PalletEthereumError extends Enum { readonly isInvalidSignature: boolean; readonly isPreLogExists: boolean; readonly type: 'InvalidSignature' | 'PreLogExists'; } - /** @name PalletEvmCodeMetadata (661) */ + /** @name PalletEvmCodeMetadata (662) */ interface PalletEvmCodeMetadata extends Struct { readonly size_: u64; readonly hash_: H256; } - /** @name PalletEvmError (663) */ + /** @name PalletEvmError (664) */ interface PalletEvmError extends Enum { readonly isBalanceLow: boolean; readonly isFeeOverflow: boolean; @@ -5760,13 +5782,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'InvalidChainId' | 'InvalidSignature' | 'Reentrancy' | 'TransactionMustComeFromEOA' | 'Undefined'; } - /** @name PalletHotfixSufficientsError (664) */ + /** @name PalletHotfixSufficientsError (665) */ interface PalletHotfixSufficientsError extends Enum { readonly isMaxAddressCountExceeded: boolean; readonly type: 'MaxAddressCountExceeded'; } - /** @name PalletAirdropClaimsError (666) */ + /** @name PalletAirdropClaimsError (667) */ interface PalletAirdropClaimsError extends Enum { readonly isInvalidEthereumSignature: boolean; readonly isInvalidNativeSignature: boolean; @@ -5779,21 +5801,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidEthereumSignature' | 'InvalidNativeSignature' | 'InvalidNativeAccount' | 'SignerHasNoClaim' | 'SenderHasNoClaim' | 'PotUnderflow' | 'InvalidStatement' | 'VestedBalanceExists'; } - /** @name PalletProxyProxyDefinition (669) */ + /** @name PalletProxyProxyDefinition (670) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: TangleTestnetRuntimeProxyType; readonly delay: u64; } - /** @name PalletProxyAnnouncement (673) */ + /** @name PalletProxyAnnouncement (674) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u64; } - /** @name PalletProxyError (675) */ + /** @name PalletProxyError (676) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -5806,7 +5828,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooMany' | 'NotFound' | 'NotProxy' | 'Unproxyable' | 'Duplicate' | 'NoPermission' | 'Unannounced' | 'NoSelfProxy'; } - /** @name PalletMultiAssetDelegationOperatorOperatorMetadata (676) */ + /** @name PalletMultiAssetDelegationOperatorOperatorMetadata (677) */ interface PalletMultiAssetDelegationOperatorOperatorMetadata extends Struct { readonly stake: u128; readonly delegationCount: u32; @@ -5816,26 +5838,26 @@ declare module '@polkadot/types/lookup' { readonly blueprintIds: Vec; } - /** @name TangleTestnetRuntimeMaxDelegations (677) */ + /** @name TangleTestnetRuntimeMaxDelegations (678) */ type TangleTestnetRuntimeMaxDelegations = Null; - /** @name TangleTestnetRuntimeMaxOperatorBlueprints (678) */ + /** @name TangleTestnetRuntimeMaxOperatorBlueprints (679) */ type TangleTestnetRuntimeMaxOperatorBlueprints = Null; - /** @name PalletMultiAssetDelegationOperatorOperatorBondLessRequest (680) */ + /** @name PalletMultiAssetDelegationOperatorOperatorBondLessRequest (681) */ interface PalletMultiAssetDelegationOperatorOperatorBondLessRequest extends Struct { readonly amount: u128; readonly requestTime: u32; } - /** @name PalletMultiAssetDelegationOperatorDelegatorBond (682) */ + /** @name PalletMultiAssetDelegationOperatorDelegatorBond (683) */ interface PalletMultiAssetDelegationOperatorDelegatorBond extends Struct { readonly delegator: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; } - /** @name PalletMultiAssetDelegationOperatorOperatorStatus (684) */ + /** @name PalletMultiAssetDelegationOperatorOperatorStatus (685) */ interface PalletMultiAssetDelegationOperatorOperatorStatus extends Enum { readonly isActive: boolean; readonly isInactive: boolean; @@ -5844,52 +5866,52 @@ declare module '@polkadot/types/lookup' { readonly type: 'Active' | 'Inactive' | 'Leaving'; } - /** @name PalletMultiAssetDelegationOperatorOperatorSnapshot (686) */ + /** @name PalletMultiAssetDelegationOperatorOperatorSnapshot (687) */ interface PalletMultiAssetDelegationOperatorOperatorSnapshot extends Struct { readonly stake: u128; readonly delegations: Vec; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorMetadata (687) */ + /** @name PalletMultiAssetDelegationDelegatorDelegatorMetadata (688) */ interface PalletMultiAssetDelegationDelegatorDelegatorMetadata extends Struct { - readonly deposits: BTreeMap; + readonly deposits: BTreeMap; readonly withdrawRequests: Vec; readonly delegations: Vec; readonly delegatorUnstakeRequests: Vec; readonly status: PalletMultiAssetDelegationDelegatorDelegatorStatus; } - /** @name TangleTestnetRuntimeMaxWithdrawRequests (688) */ + /** @name TangleTestnetRuntimeMaxWithdrawRequests (689) */ type TangleTestnetRuntimeMaxWithdrawRequests = Null; - /** @name TangleTestnetRuntimeMaxUnstakeRequests (689) */ + /** @name TangleTestnetRuntimeMaxUnstakeRequests (690) */ type TangleTestnetRuntimeMaxUnstakeRequests = Null; - /** @name PalletMultiAssetDelegationDelegatorWithdrawRequest (694) */ + /** @name PalletMultiAssetDelegationDelegatorWithdrawRequest (695) */ interface PalletMultiAssetDelegationDelegatorWithdrawRequest extends Struct { - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; readonly requestedRound: u32; } - /** @name PalletMultiAssetDelegationDelegatorBondInfoDelegator (697) */ + /** @name PalletMultiAssetDelegationDelegatorBondInfoDelegator (698) */ interface PalletMultiAssetDelegationDelegatorBondInfoDelegator extends Struct { readonly operator: AccountId32; readonly amount: u128; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; } - /** @name PalletMultiAssetDelegationDelegatorBondLessRequest (700) */ + /** @name PalletMultiAssetDelegationDelegatorBondLessRequest (701) */ interface PalletMultiAssetDelegationDelegatorBondLessRequest extends Struct { readonly operator: AccountId32; - readonly assetId: u128; + readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; readonly requestedRound: u32; readonly blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorStatus (702) */ + /** @name PalletMultiAssetDelegationDelegatorDelegatorStatus (703) */ interface PalletMultiAssetDelegationDelegatorDelegatorStatus extends Enum { readonly isActive: boolean; readonly isLeavingScheduled: boolean; @@ -5897,19 +5919,19 @@ declare module '@polkadot/types/lookup' { readonly type: 'Active' | 'LeavingScheduled'; } - /** @name PalletMultiAssetDelegationRewardsRewardConfig (703) */ + /** @name PalletMultiAssetDelegationRewardsRewardConfig (705) */ interface PalletMultiAssetDelegationRewardsRewardConfig extends Struct { readonly configs: BTreeMap; readonly whitelistedBlueprintIds: Vec; } - /** @name PalletMultiAssetDelegationRewardsRewardConfigForAssetVault (705) */ + /** @name PalletMultiAssetDelegationRewardsRewardConfigForAssetVault (707) */ interface PalletMultiAssetDelegationRewardsRewardConfigForAssetVault extends Struct { readonly apy: Percent; readonly cap: u128; } - /** @name PalletMultiAssetDelegationError (708) */ + /** @name PalletMultiAssetDelegationError (710) */ interface PalletMultiAssetDelegationError extends Enum { readonly isAlreadyOperator: boolean; readonly isBondTooLow: boolean; @@ -5958,10 +5980,13 @@ declare module '@polkadot/types/lookup' { readonly isCapExceedsTotalSupply: boolean; readonly isPendingUnstakeRequestExists: boolean; readonly isBlueprintNotSelected: boolean; - readonly type: 'AlreadyOperator' | 'BondTooLow' | 'NotAnOperator' | 'CannotExit' | 'AlreadyLeaving' | 'NotLeavingOperator' | 'NotLeavingRound' | 'LeavingRoundNotReached' | 'NoScheduledBondLess' | 'BondLessRequestNotSatisfied' | 'NotActiveOperator' | 'NotOfflineOperator' | 'AlreadyDelegator' | 'NotDelegator' | 'WithdrawRequestAlreadyExists' | 'InsufficientBalance' | 'NoWithdrawRequest' | 'NoBondLessRequest' | 'BondLessNotReady' | 'BondLessRequestAlreadyExists' | 'ActiveServicesUsingAsset' | 'NoActiveDelegation' | 'AssetNotWhitelisted' | 'NotAuthorized' | 'MaxBlueprintsExceeded' | 'AssetNotFound' | 'BlueprintAlreadyWhitelisted' | 'NowithdrawRequests' | 'NoMatchingwithdrawRequest' | 'AssetAlreadyInVault' | 'AssetNotInVault' | 'VaultNotFound' | 'DuplicateBlueprintId' | 'BlueprintIdNotFound' | 'NotInFixedMode' | 'MaxDelegationsExceeded' | 'MaxUnstakeRequestsExceeded' | 'MaxWithdrawRequestsExceeded' | 'DepositOverflow' | 'UnstakeAmountTooLarge' | 'StakeOverflow' | 'InsufficientStakeRemaining' | 'ApyExceedsMaximum' | 'CapCannotBeZero' | 'CapExceedsTotalSupply' | 'PendingUnstakeRequestExists' | 'BlueprintNotSelected'; + readonly isErc20TransferFailed: boolean; + readonly isEvmAbiEncode: boolean; + readonly isEvmAbiDecode: boolean; + readonly type: 'AlreadyOperator' | 'BondTooLow' | 'NotAnOperator' | 'CannotExit' | 'AlreadyLeaving' | 'NotLeavingOperator' | 'NotLeavingRound' | 'LeavingRoundNotReached' | 'NoScheduledBondLess' | 'BondLessRequestNotSatisfied' | 'NotActiveOperator' | 'NotOfflineOperator' | 'AlreadyDelegator' | 'NotDelegator' | 'WithdrawRequestAlreadyExists' | 'InsufficientBalance' | 'NoWithdrawRequest' | 'NoBondLessRequest' | 'BondLessNotReady' | 'BondLessRequestAlreadyExists' | 'ActiveServicesUsingAsset' | 'NoActiveDelegation' | 'AssetNotWhitelisted' | 'NotAuthorized' | 'MaxBlueprintsExceeded' | 'AssetNotFound' | 'BlueprintAlreadyWhitelisted' | 'NowithdrawRequests' | 'NoMatchingwithdrawRequest' | 'AssetAlreadyInVault' | 'AssetNotInVault' | 'VaultNotFound' | 'DuplicateBlueprintId' | 'BlueprintIdNotFound' | 'NotInFixedMode' | 'MaxDelegationsExceeded' | 'MaxUnstakeRequestsExceeded' | 'MaxWithdrawRequestsExceeded' | 'DepositOverflow' | 'UnstakeAmountTooLarge' | 'StakeOverflow' | 'InsufficientStakeRemaining' | 'ApyExceedsMaximum' | 'CapCannotBeZero' | 'CapExceedsTotalSupply' | 'PendingUnstakeRequestExists' | 'BlueprintNotSelected' | 'Erc20TransferFailed' | 'EvmAbiEncode' | 'EvmAbiDecode'; } - /** @name TanglePrimitivesServicesServiceRequest (711) */ + /** @name TanglePrimitivesServicesServiceRequest (713) */ interface TanglePrimitivesServicesServiceRequest extends Struct { readonly blueprint: u64; readonly owner: AccountId32; @@ -5972,7 +5997,7 @@ declare module '@polkadot/types/lookup' { readonly operatorsWithApprovalState: Vec>; } - /** @name TanglePrimitivesServicesApprovalState (717) */ + /** @name TanglePrimitivesServicesApprovalState (719) */ interface TanglePrimitivesServicesApprovalState extends Enum { readonly isPending: boolean; readonly isApproved: boolean; @@ -5983,7 +6008,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pending' | 'Approved' | 'Rejected'; } - /** @name TanglePrimitivesServicesService (719) */ + /** @name TanglePrimitivesServicesService (721) */ interface TanglePrimitivesServicesService extends Struct { readonly id: u64; readonly blueprint: u64; @@ -5994,21 +6019,21 @@ declare module '@polkadot/types/lookup' { readonly ttl: u64; } - /** @name TanglePrimitivesServicesJobCall (725) */ + /** @name TanglePrimitivesServicesJobCall (727) */ interface TanglePrimitivesServicesJobCall extends Struct { readonly serviceId: u64; readonly job: u8; readonly args: Vec; } - /** @name TanglePrimitivesServicesJobCallResult (726) */ + /** @name TanglePrimitivesServicesJobCallResult (728) */ interface TanglePrimitivesServicesJobCallResult extends Struct { readonly serviceId: u64; readonly callId: u64; readonly result: Vec; } - /** @name PalletServicesUnappliedSlash (727) */ + /** @name PalletServicesUnappliedSlash (729) */ interface PalletServicesUnappliedSlash extends Struct { readonly serviceId: u64; readonly operator: AccountId32; @@ -6018,13 +6043,30 @@ declare module '@polkadot/types/lookup' { readonly payout: u128; } - /** @name TanglePrimitivesServicesOperatorProfile (729) */ + /** @name TanglePrimitivesServicesOperatorProfile (731) */ interface TanglePrimitivesServicesOperatorProfile extends Struct { readonly services: BTreeSet; readonly blueprints: BTreeSet; } - /** @name PalletServicesModuleError (732) */ + /** @name TanglePrimitivesServicesStagingServicePayment (734) */ + interface TanglePrimitivesServicesStagingServicePayment extends Struct { + readonly requestId: u64; + readonly refundTo: TanglePrimitivesAccount; + readonly asset: TanglePrimitivesServicesAsset; + readonly amount: u128; + } + + /** @name TanglePrimitivesAccount (735) */ + interface TanglePrimitivesAccount extends Enum { + readonly isId: boolean; + readonly asId: AccountId32; + readonly isAddress: boolean; + readonly asAddress: H160; + readonly type: 'Id' | 'Address'; + } + + /** @name PalletServicesModuleError (736) */ interface PalletServicesModuleError extends Enum { readonly isBlueprintNotFound: boolean; readonly isBlueprintCreationInterrupted: boolean; @@ -6066,10 +6108,14 @@ declare module '@polkadot/types/lookup' { readonly isUnappliedSlashNotFound: boolean; readonly isMasterBlueprintServiceManagerRevisionNotFound: boolean; readonly isMaxMasterBlueprintServiceManagerVersionsExceeded: boolean; - readonly type: 'BlueprintNotFound' | 'BlueprintCreationInterrupted' | 'AlreadyRegistered' | 'InvalidRegistrationInput' | 'NotAllowedToUnregister' | 'NotAllowedToUpdatePriceTargets' | 'InvalidRequestInput' | 'InvalidJobCallInput' | 'InvalidJobResult' | 'NotRegistered' | 'ApprovalInterrupted' | 'RejectionInterrupted' | 'ServiceRequestNotFound' | 'ServiceInitializationInterrupted' | 'ServiceNotFound' | 'TerminationInterrupted' | 'TypeCheck' | 'MaxPermittedCallersExceeded' | 'MaxServiceProvidersExceeded' | 'MaxServicesPerUserExceeded' | 'MaxFieldsExceeded' | 'ApprovalNotRequested' | 'JobDefinitionNotFound' | 'ServiceOrJobCallNotFound' | 'JobCallResultNotFound' | 'EvmAbiEncode' | 'EvmAbiDecode' | 'OperatorProfileNotFound' | 'MaxServicesPerProviderExceeded' | 'OperatorNotActive' | 'NoAssetsProvided' | 'MaxAssetsPerServiceExceeded' | 'OffenderNotOperator' | 'OffenderNotActiveOperator' | 'NoSlashingOrigin' | 'NoDisputeOrigin' | 'UnappliedSlashNotFound' | 'MasterBlueprintServiceManagerRevisionNotFound' | 'MaxMasterBlueprintServiceManagerVersionsExceeded'; + readonly isErc20TransferFailed: boolean; + readonly isMissingEVMOrigin: boolean; + readonly isExpectedEVMAddress: boolean; + readonly isExpectedAccountId: boolean; + readonly type: 'BlueprintNotFound' | 'BlueprintCreationInterrupted' | 'AlreadyRegistered' | 'InvalidRegistrationInput' | 'NotAllowedToUnregister' | 'NotAllowedToUpdatePriceTargets' | 'InvalidRequestInput' | 'InvalidJobCallInput' | 'InvalidJobResult' | 'NotRegistered' | 'ApprovalInterrupted' | 'RejectionInterrupted' | 'ServiceRequestNotFound' | 'ServiceInitializationInterrupted' | 'ServiceNotFound' | 'TerminationInterrupted' | 'TypeCheck' | 'MaxPermittedCallersExceeded' | 'MaxServiceProvidersExceeded' | 'MaxServicesPerUserExceeded' | 'MaxFieldsExceeded' | 'ApprovalNotRequested' | 'JobDefinitionNotFound' | 'ServiceOrJobCallNotFound' | 'JobCallResultNotFound' | 'EvmAbiEncode' | 'EvmAbiDecode' | 'OperatorProfileNotFound' | 'MaxServicesPerProviderExceeded' | 'OperatorNotActive' | 'NoAssetsProvided' | 'MaxAssetsPerServiceExceeded' | 'OffenderNotOperator' | 'OffenderNotActiveOperator' | 'NoSlashingOrigin' | 'NoDisputeOrigin' | 'UnappliedSlashNotFound' | 'MasterBlueprintServiceManagerRevisionNotFound' | 'MaxMasterBlueprintServiceManagerVersionsExceeded' | 'Erc20TransferFailed' | 'MissingEVMOrigin' | 'ExpectedEVMAddress' | 'ExpectedAccountId'; } - /** @name TanglePrimitivesServicesTypeCheckError (733) */ + /** @name TanglePrimitivesServicesTypeCheckError (737) */ interface TanglePrimitivesServicesTypeCheckError extends Enum { readonly isArgumentTypeMismatch: boolean; readonly asArgumentTypeMismatch: { @@ -6091,7 +6137,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ArgumentTypeMismatch' | 'NotEnoughArguments' | 'ResultTypeMismatch'; } - /** @name PalletTangleLstBondedPoolBondedPoolInner (734) */ + /** @name PalletTangleLstBondedPoolBondedPoolInner (738) */ interface PalletTangleLstBondedPoolBondedPoolInner extends Struct { readonly commission: PalletTangleLstCommission; readonly roles: PalletTangleLstPoolsPoolRoles; @@ -6099,7 +6145,7 @@ declare module '@polkadot/types/lookup' { readonly metadata: PalletTangleLstBondedPoolPoolMetadata; } - /** @name PalletTangleLstCommission (735) */ + /** @name PalletTangleLstCommission (739) */ interface PalletTangleLstCommission extends Struct { readonly current: Option>; readonly max: Option; @@ -6108,7 +6154,7 @@ declare module '@polkadot/types/lookup' { readonly claimPermission: Option; } - /** @name PalletTangleLstPoolsPoolRoles (737) */ + /** @name PalletTangleLstPoolsPoolRoles (741) */ interface PalletTangleLstPoolsPoolRoles extends Struct { readonly depositor: AccountId32; readonly root: Option; @@ -6116,13 +6162,13 @@ declare module '@polkadot/types/lookup' { readonly bouncer: Option; } - /** @name PalletTangleLstBondedPoolPoolMetadata (738) */ + /** @name PalletTangleLstBondedPoolPoolMetadata (742) */ interface PalletTangleLstBondedPoolPoolMetadata extends Struct { readonly name: Option; readonly icon: Option; } - /** @name PalletTangleLstSubPoolsRewardPool (739) */ + /** @name PalletTangleLstSubPoolsRewardPool (743) */ interface PalletTangleLstSubPoolsRewardPool extends Struct { readonly lastRecordedRewardCounter: u128; readonly lastRecordedTotalPayouts: u128; @@ -6131,24 +6177,24 @@ declare module '@polkadot/types/lookup' { readonly totalCommissionClaimed: u128; } - /** @name PalletTangleLstSubPools (740) */ + /** @name PalletTangleLstSubPools (744) */ interface PalletTangleLstSubPools extends Struct { readonly noEra: PalletTangleLstSubPoolsUnbondPool; readonly withEra: BTreeMap; } - /** @name PalletTangleLstSubPoolsUnbondPool (741) */ + /** @name PalletTangleLstSubPoolsUnbondPool (745) */ interface PalletTangleLstSubPoolsUnbondPool extends Struct { readonly points: u128; readonly balance: u128; } - /** @name PalletTangleLstPoolsPoolMember (747) */ + /** @name PalletTangleLstPoolsPoolMember (751) */ interface PalletTangleLstPoolsPoolMember extends Struct { readonly unbondingEras: BTreeMap>; } - /** @name PalletTangleLstClaimPermission (752) */ + /** @name PalletTangleLstClaimPermission (756) */ interface PalletTangleLstClaimPermission extends Enum { readonly isPermissioned: boolean; readonly isPermissionlessCompound: boolean; @@ -6157,7 +6203,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissioned' | 'PermissionlessCompound' | 'PermissionlessWithdraw' | 'PermissionlessAll'; } - /** @name PalletTangleLstError (753) */ + /** @name PalletTangleLstError (757) */ interface PalletTangleLstError extends Enum { readonly isPoolNotFound: boolean; readonly isPoolMemberNotFound: boolean; @@ -6196,7 +6242,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PoolNotFound' | 'PoolMemberNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'FullyUnbonding' | 'MaxUnbondingLimit' | 'CannotWithdrawAny' | 'MinimumBondNotMet' | 'OverflowRisk' | 'NotDestroying' | 'NotNominator' | 'NotKickerOrDestroying' | 'NotOpen' | 'MaxPools' | 'MaxPoolMembers' | 'CanNotChangeState' | 'DoesNotHavePermission' | 'MetadataExceedsMaxLen' | 'Defensive' | 'PartialUnbondNotAllowedPermissionlessly' | 'MaxCommissionRestricted' | 'CommissionExceedsMaximum' | 'CommissionExceedsGlobalMaximum' | 'CommissionChangeThrottled' | 'CommissionChangeRateNotAllowed' | 'NoPendingCommission' | 'NoCommissionCurrentSet' | 'PoolIdInUse' | 'InvalidPoolId' | 'BondExtraRestricted' | 'NothingToAdjust' | 'PoolTokenCreationFailed' | 'NoBalanceToUnbond'; } - /** @name PalletTangleLstDefensiveError (754) */ + /** @name PalletTangleLstDefensiveError (758) */ interface PalletTangleLstDefensiveError extends Enum { readonly isNotEnoughSpaceInUnbondPool: boolean; readonly isPoolNotFound: boolean; @@ -6206,40 +6252,40 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotEnoughSpaceInUnbondPool' | 'PoolNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'BondedStashKilledPrematurely'; } - /** @name FrameSystemExtensionsCheckNonZeroSender (757) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (761) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (758) */ + /** @name FrameSystemExtensionsCheckSpecVersion (762) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (759) */ + /** @name FrameSystemExtensionsCheckTxVersion (763) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (760) */ + /** @name FrameSystemExtensionsCheckGenesis (764) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (763) */ + /** @name FrameSystemExtensionsCheckNonce (767) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (764) */ + /** @name FrameSystemExtensionsCheckWeight (768) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (765) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (769) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name FrameMetadataHashExtensionCheckMetadataHash (766) */ + /** @name FrameMetadataHashExtensionCheckMetadataHash (770) */ interface FrameMetadataHashExtensionCheckMetadataHash extends Struct { readonly mode: FrameMetadataHashExtensionMode; } - /** @name FrameMetadataHashExtensionMode (767) */ + /** @name FrameMetadataHashExtensionMode (771) */ interface FrameMetadataHashExtensionMode extends Enum { readonly isDisabled: boolean; readonly isEnabled: boolean; readonly type: 'Disabled' | 'Enabled'; } - /** @name TangleTestnetRuntimeRuntime (769) */ + /** @name TangleTestnetRuntimeRuntime (773) */ type TangleTestnetRuntimeRuntime = Null; } // declare module diff --git a/types/src/metadata.json b/types/src/metadata.json index 630abe92..b4b035eb 100644 --- a/types/src/metadata.json +++ b/types/src/metadata.json @@ -1 +1 @@ -{"jsonrpc":"2.0","result":"0x6d6574610e090c000c1c73705f636f72651863727970746f2c4163636f756e7449643332000004000401205b75383b2033325d0000040000032000000008000800000503000c08306672616d655f73797374656d2c4163636f756e74496e666f08144e6f6e636501102c4163636f756e74446174610114001401146e6f6e63651001144e6f6e6365000124636f6e73756d657273100120526566436f756e7400012470726f766964657273100120526566436f756e7400012c73756666696369656e7473100120526566436f756e740001106461746114012c4163636f756e74446174610000100000050500140c3c70616c6c65745f62616c616e6365731474797065732c4163636f756e7444617461041c42616c616e63650118001001106672656518011c42616c616e6365000120726573657276656418011c42616c616e636500011866726f7a656e18011c42616c616e6365000114666c6167731c01284578747261466c61677300001800000507001c0c3c70616c6c65745f62616c616e636573147479706573284578747261466c61677300000400180110753132380000200000050000240c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540128000c01186e6f726d616c2801045400012c6f7065726174696f6e616c280104540001246d616e6461746f7279280104540000280c2873705f77656967687473247765696768745f76321857656967687400000801207265665f74696d652c010c75363400012870726f6f665f73697a652c010c75363400002c000006300030000005060034083c7072696d69746976655f74797065731048323536000004000401205b75383b2033325d00003800000208003c102873705f72756e74696d651c67656e65726963186469676573741844696765737400000401106c6f677340013c5665633c4469676573744974656d3e000040000002440044102873705f72756e74696d651c67656e6572696318646967657374284469676573744974656d0001142850726552756e74696d650800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e00060024436f6e73656e7375730800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000400105365616c0800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000500144f74686572040038011c5665633c75383e0000006452756e74696d65456e7669726f6e6d656e745570646174656400080000480000030400000008004c00000250005008306672616d655f73797374656d2c4576656e745265636f7264080445015404540134000c011470686173655502011450686173650001146576656e7454010445000118746f70696373c10101185665633c543e000054085874616e676c655f746573746e65745f72756e74696d653052756e74696d654576656e7400018c1853797374656d04005801706672616d655f73797374656d3a3a4576656e743c52756e74696d653e000100105375646f04007c016c70616c6c65745f7375646f3a3a4576656e743c52756e74696d653e0003001841737365747304008c017470616c6c65745f6173736574733a3a4576656e743c52756e74696d653e0005002042616c616e636573040090017c70616c6c65745f62616c616e6365733a3a4576656e743c52756e74696d653e000600485472616e73616374696f6e5061796d656e7404009801a870616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4576656e743c52756e74696d653e0007001c4772616e64706104009c015470616c6c65745f6772616e6470613a3a4576656e74000a001c496e64696365730400ac017870616c6c65745f696e64696365733a3a4576656e743c52756e74696d653e000b002444656d6f63726163790400b0018070616c6c65745f64656d6f63726163793a3a4576656e743c52756e74696d653e000c001c436f756e63696c0400c401fc70616c6c65745f636f6c6c6563746976653a3a4576656e743c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d001c56657374696e670400c8017870616c6c65745f76657374696e673a3a4576656e743c52756e74696d653e000e0024456c656374696f6e730400cc01a470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4576656e743c52756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400d801d070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a4576656e743c52756e74696d653e0010001c5374616b696e670400ec017870616c6c65745f7374616b696e673a3a4576656e743c52756e74696d653e0011001c53657373696f6e04000501015470616c6c65745f73657373696f6e3a3a4576656e7400120020547265617375727904000901017c70616c6c65745f74726561737572793a3a4576656e743c52756e74696d653e00140020426f756e7469657304000d01017c70616c6c65745f626f756e746965733a3a4576656e743c52756e74696d653e001500344368696c64426f756e7469657304001101019470616c6c65745f6368696c645f626f756e746965733a3a4576656e743c52756e74696d653e00160020426167734c69737404001501018070616c6c65745f626167735f6c6973743a3a4576656e743c52756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304001901019c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a4576656e743c52756e74696d653e001800245363686564756c657204003501018070616c6c65745f7363686564756c65723a3a4576656e743c52756e74696d653e00190020507265696d61676504004101017c70616c6c65745f707265696d6167653a3a4576656e743c52756e74696d653e001a00204f6666656e63657304004501015870616c6c65745f6f6666656e6365733a3a4576656e74001b001c5478506175736504004d01017c70616c6c65745f74785f70617573653a3a4576656e743c52756e74696d653e001c0020496d4f6e6c696e6504005901018070616c6c65745f696d5f6f6e6c696e653a3a4576656e743c52756e74696d653e001d00204964656e7469747904007901017c70616c6c65745f6964656e746974793a3a4576656e743c52756e74696d653e001e001c5574696c69747904008101015470616c6c65745f7574696c6974793a3a4576656e74001f00204d756c746973696704008501017c70616c6c65745f6d756c74697369673a3a4576656e743c52756e74696d653e00200020457468657265756d04008d01015870616c6c65745f657468657265756d3a3a4576656e740021000c45564d0400b901016870616c6c65745f65766d3a3a4576656e743c52756e74696d653e0022001c426173654665650400c501015870616c6c65745f626173655f6665653a3a4576656e7400250018436c61696d730400d501019470616c6c65745f61697264726f705f636c61696d733a3a4576656e743c52756e74696d653e0027001450726f78790400e101017070616c6c65745f70726f78793a3a4576656e743c52756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400ed0101b470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e3a3a4576656e743c52756e74696d653e002d002053657276696365730400f901017c70616c6c65745f73657276696365733a3a4576656e743c52756e74696d653e0033000c4c737404004102018470616c6c65745f74616e676c655f6c73743a3a4576656e743c52756e74696d653e00340000580c306672616d655f73797374656d1870616c6c6574144576656e7404045400011c4045787472696e7369635375636365737304013464697370617463685f696e666f5c01304469737061746368496e666f00000490416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e3c45787472696e7369634661696c656408013864697370617463685f6572726f7268013444697370617463684572726f7200013464697370617463685f696e666f5c01304469737061746368496e666f00010450416e2065787472696e736963206661696c65642e2c436f64655570646174656400020450603a636f6465602077617320757064617465642e284e65774163636f756e7404011c6163636f756e74000130543a3a4163636f756e7449640003046841206e6577206163636f756e742077617320637265617465642e344b696c6c65644163636f756e7404011c6163636f756e74000130543a3a4163636f756e74496400040458416e206163636f756e7420776173207265617065642e2052656d61726b656408011873656e646572000130543a3a4163636f756e7449640001106861736834011c543a3a48617368000504704f6e206f6e2d636861696e2072656d61726b2068617070656e65642e4455706772616465417574686f72697a6564080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00060468416e20757067726164652077617320617574686f72697a65642e04704576656e7420666f72207468652053797374656d2070616c6c65742e5c0c346672616d655f737570706f7274206469737061746368304469737061746368496e666f00000c0118776569676874280118576569676874000114636c6173736001344469737061746368436c617373000120706179735f666565640110506179730000600c346672616d655f737570706f7274206469737061746368344469737061746368436c61737300010c184e6f726d616c0000002c4f7065726174696f6e616c000100244d616e6461746f727900020000640c346672616d655f737570706f727420646973706174636810506179730001080c596573000000084e6f0001000068082873705f72756e74696d653444697370617463684572726f72000138144f746865720000003043616e6e6f744c6f6f6b7570000100244261644f726967696e000200184d6f64756c6504006c012c4d6f64756c654572726f7200030044436f6e73756d657252656d61696e696e670004002c4e6f50726f76696465727300050040546f6f4d616e79436f6e73756d65727300060014546f6b656e0400700128546f6b656e4572726f720007002841726974686d65746963040074013c41726974686d657469634572726f72000800345472616e73616374696f6e616c04007801485472616e73616374696f6e616c4572726f7200090024457868617573746564000a0028436f7272757074696f6e000b002c556e617661696c61626c65000c0038526f6f744e6f74416c6c6f776564000d00006c082873705f72756e74696d652c4d6f64756c654572726f720000080114696e64657808010875380001146572726f7248018c5b75383b204d41585f4d4f44554c455f4552524f525f454e434f4445445f53495a455d000070082873705f72756e74696d6528546f6b656e4572726f720001284046756e6473556e617661696c61626c65000000304f6e6c7950726f76696465720001003042656c6f774d696e696d756d0002003043616e6e6f7443726561746500030030556e6b6e6f776e41737365740004001846726f7a656e0005002c556e737570706f727465640006004043616e6e6f74437265617465486f6c64000700344e6f74457870656e6461626c650008001c426c6f636b65640009000074083473705f61726974686d657469633c41726974686d657469634572726f7200010c24556e646572666c6f77000000204f766572666c6f77000100384469766973696f6e42795a65726f0002000078082873705f72756e74696d65485472616e73616374696f6e616c4572726f72000108304c696d6974526561636865640000001c4e6f4c61796572000100007c0c2c70616c6c65745f7375646f1870616c6c6574144576656e7404045400011014537564696404012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e00047041207375646f2063616c6c206a75737420746f6f6b20706c6163652e284b65794368616e67656408010c6f6c648801504f7074696f6e3c543a3a4163636f756e7449643e04b4546865206f6c64207375646f206b657920286966206f6e65207761732070726576696f75736c7920736574292e010c6e6577000130543a3a4163636f756e7449640488546865206e6577207375646f206b657920286966206f6e652077617320736574292e010478546865207375646f206b657920686173206265656e20757064617465642e284b657952656d6f76656400020480546865206b657920776173207065726d616e656e746c792072656d6f7665642e285375646f4173446f6e6504012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e0304c841205b7375646f5f61735d2850616c6c65743a3a7375646f5f6173292063616c6c206a75737420746f6f6b20706c6163652e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574800418526573756c740804540184044501680108084f6b040084000000000c45727204006800000100008400000400008804184f7074696f6e04045401000108104e6f6e6500000010536f6d6504000000000100008c0c3470616c6c65745f6173736574731870616c6c6574144576656e740804540004490001681c437265617465640c012061737365745f6964180128543a3a4173736574496400011c63726561746f72000130543a3a4163636f756e7449640001146f776e6572000130543a3a4163636f756e74496400000474536f6d6520617373657420636c6173732077617320637265617465642e184973737565640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500010460536f6d65206173736574732077657265206973737565642e2c5472616e7366657272656410012061737365745f6964180128543a3a4173736574496400011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500020474536f6d65206173736574732077657265207472616e736665727265642e184275726e65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400011c62616c616e6365180128543a3a42616c616e63650003046c536f6d652061737365747320776572652064657374726f7965642e2c5465616d4368616e67656410012061737365745f6964180128543a3a41737365744964000118697373756572000130543a3a4163636f756e74496400011461646d696e000130543a3a4163636f756e74496400011c667265657a6572000130543a3a4163636f756e74496400040470546865206d616e6167656d656e74207465616d206368616e6765642e304f776e65724368616e67656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400050448546865206f776e6572206368616e6765642e1846726f7a656e08012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400060478536f6d65206163636f756e74206077686f60207761732066726f7a656e2e1854686177656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400070478536f6d65206163636f756e74206077686f6020776173207468617765642e2c417373657446726f7a656e04012061737365745f6964180128543a3a4173736574496400080484536f6d65206173736574206061737365745f696460207761732066726f7a656e2e2c417373657454686177656404012061737365745f6964180128543a3a4173736574496400090484536f6d65206173736574206061737365745f69646020776173207468617765642e444163636f756e747344657374726f7965640c012061737365745f6964180128543a3a417373657449640001486163636f756e74735f64657374726f79656410010c7533320001486163636f756e74735f72656d61696e696e6710010c753332000a04a04163636f756e747320776572652064657374726f79656420666f7220676976656e2061737365742e48417070726f76616c7344657374726f7965640c012061737365745f6964180128543a3a4173736574496400014c617070726f76616c735f64657374726f79656410010c75333200014c617070726f76616c735f72656d61696e696e6710010c753332000b04a4417070726f76616c7320776572652064657374726f79656420666f7220676976656e2061737365742e484465737472756374696f6e5374617274656404012061737365745f6964180128543a3a41737365744964000c04d0416e20617373657420636c61737320697320696e207468652070726f63657373206f66206265696e672064657374726f7965642e2444657374726f79656404012061737365745f6964180128543a3a41737365744964000d0474416e20617373657420636c617373207761732064657374726f7965642e30466f7263654372656174656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000e048c536f6d6520617373657420636c6173732077617320666f7263652d637265617465642e2c4d6574616461746153657414012061737365745f6964180128543a3a417373657449640001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000f049c4e6577206d6574616461746120686173206265656e2073657420666f7220616e2061737365742e3c4d65746164617461436c656172656404012061737365745f6964180128543a3a417373657449640010049c4d6574616461746120686173206265656e20636c656172656420666f7220616e2061737365742e40417070726f7665645472616e7366657210012061737365745f6964180128543a3a41737365744964000118736f75726365000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650011043101284164646974696f6e616c292066756e64732068617665206265656e20617070726f76656420666f72207472616e7366657220746f20612064657374696e6174696f6e206163636f756e742e44417070726f76616c43616e63656c6c65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964001204f0416e20617070726f76616c20666f72206163636f756e74206064656c656761746560207761732063616e63656c6c656420627920606f776e6572602e4c5472616e73666572726564417070726f76656414012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e74496400012c64657374696e6174696f6e000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650013083101416e2060616d6f756e746020776173207472616e7366657272656420696e2069747320656e7469726574792066726f6d20606f776e65726020746f206064657374696e6174696f6e602062796074686520617070726f766564206064656c6567617465602e4841737365745374617475734368616e67656404012061737365745f6964180128543a3a41737365744964001404f8416e2061737365742068617320686164206974732061747472696275746573206368616e676564206279207468652060466f72636560206f726967696e2e5841737365744d696e42616c616e63654368616e67656408012061737365745f6964180128543a3a4173736574496400013c6e65775f6d696e5f62616c616e6365180128543a3a42616c616e63650015040101546865206d696e5f62616c616e6365206f6620616e20617373657420686173206265656e207570646174656420627920746865206173736574206f776e65722e1c546f75636865640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640001246465706f7369746f72000130543a3a4163636f756e744964001604fc536f6d65206163636f756e74206077686f6020776173206372656174656420776974682061206465706f7369742066726f6d20606465706f7369746f72602e1c426c6f636b656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640017047c536f6d65206163636f756e74206077686f602077617320626c6f636b65642e244465706f73697465640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365001804dc536f6d65206173736574732077657265206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e2457697468647261776e0c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650019042101536f6d652061737365747320776572652077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574900c3c70616c6c65745f62616c616e6365731870616c6c6574144576656e740804540004490001581c456e646f77656408011c6163636f756e74000130543a3a4163636f756e744964000130667265655f62616c616e6365180128543a3a42616c616e6365000004b8416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e20447573744c6f737408011c6163636f756e74000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650001083d01416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c78726573756c74696e6720696e20616e206f75747269676874206c6f73732e205472616e736665720c011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650002044c5472616e73666572207375636365656465642e2842616c616e636553657408010c77686f000130543a3a4163636f756e74496400011066726565180128543a3a42616c616e636500030468412062616c616e6365207761732073657420627920726f6f742e20526573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000404e0536f6d652062616c616e63652077617320726573657276656420286d6f7665642066726f6d206672656520746f207265736572766564292e28556e726573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000504e8536f6d652062616c616e63652077617320756e726573657276656420286d6f7665642066726f6d20726573657276656420746f2066726565292e4852657365727665526570617472696174656410011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500014864657374696e6174696f6e5f7374617475739401185374617475730006084d01536f6d652062616c616e636520776173206d6f7665642066726f6d207468652072657365727665206f6620746865206669727374206163636f756e7420746f20746865207365636f6e64206163636f756e742ed846696e616c20617267756d656e7420696e64696361746573207468652064657374696e6174696f6e2062616c616e636520747970652e1c4465706f73697408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000704d8536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20576974686472617708010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650008041d01536f6d6520616d6f756e74207761732077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e1c536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650009040101536f6d6520616d6f756e74207761732072656d6f7665642066726f6d20746865206163636f756e742028652e672e20666f72206d69736265686176696f72292e184d696e74656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000a049c536f6d6520616d6f756e7420776173206d696e74656420696e746f20616e206163636f756e742e184275726e656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000b049c536f6d6520616d6f756e7420776173206275726e65642066726f6d20616e206163636f756e742e2453757370656e64656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000c041501536f6d6520616d6f756e74207761732073757370656e6465642066726f6d20616e206163636f756e74202869742063616e20626520726573746f726564206c61746572292e20526573746f72656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000d04a4536f6d6520616d6f756e742077617320726573746f72656420696e746f20616e206163636f756e742e20557067726164656404010c77686f000130543a3a4163636f756e744964000e0460416e206163636f756e74207761732075706772616465642e18497373756564040118616d6f756e74180128543a3a42616c616e6365000f042d01546f74616c2069737375616e63652077617320696e637265617365642062792060616d6f756e74602c206372656174696e6720612063726564697420746f2062652062616c616e6365642e2452657363696e646564040118616d6f756e74180128543a3a42616c616e63650010042501546f74616c2069737375616e636520776173206465637265617365642062792060616d6f756e74602c206372656174696e672061206465627420746f2062652062616c616e6365642e184c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500110460536f6d652062616c616e636520776173206c6f636b65642e20556e6c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500120468536f6d652062616c616e63652077617320756e6c6f636b65642e1846726f7a656e08010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500130460536f6d652062616c616e6365207761732066726f7a656e2e1854686177656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500140460536f6d652062616c616e636520776173207468617765642e4c546f74616c49737375616e6365466f7263656408010c6f6c64180128543a3a42616c616e636500010c6e6577180128543a3a42616c616e6365001504ac5468652060546f74616c49737375616e6365602077617320666f72636566756c6c79206368616e6765642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749414346672616d655f737570706f72741874726169747318746f6b656e73106d6973633442616c616e6365537461747573000108104672656500000020526573657276656400010000980c6870616c6c65745f7472616e73616374696f6e5f7061796d656e741870616c6c6574144576656e74040454000104485472616e73616374696f6e466565506169640c010c77686f000130543a3a4163636f756e74496400012861637475616c5f66656518013042616c616e63654f663c543e00010c74697018013042616c616e63654f663c543e000008590141207472616e73616374696f6e20666565206061637475616c5f666565602c206f662077686963682060746970602077617320616464656420746f20746865206d696e696d756d20696e636c7573696f6e206665652c5c686173206265656e2070616964206279206077686f602e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749c0c3870616c6c65745f6772616e6470611870616c6c6574144576656e7400010c384e6577417574686f726974696573040134617574686f726974795f736574a00134417574686f726974794c6973740000048c4e657720617574686f726974792073657420686173206265656e206170706c6965642e185061757365640001049843757272656e7420617574686f726974792073657420686173206265656e207061757365642e1c526573756d65640002049c43757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574a0000002a400a400000408a83000a80c5073705f636f6e73656e7375735f6772616e6470610c617070185075626c69630000040004013c656432353531393a3a5075626c69630000ac0c3870616c6c65745f696e64696365731870616c6c6574144576656e7404045400010c34496e64657841737369676e656408010c77686f000130543a3a4163636f756e744964000114696e64657810013c543a3a4163636f756e74496e6465780000047441206163636f756e7420696e646578207761732061737369676e65642e28496e6465784672656564040114696e64657810013c543a3a4163636f756e74496e646578000104bc41206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e2c496e64657846726f7a656e080114696e64657810013c543a3a4163636f756e74496e64657800010c77686f000130543a3a4163636f756e744964000204e841206163636f756e7420696e64657820686173206265656e2066726f7a656e20746f206974732063757272656e74206163636f756e742049442e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b00c4070616c6c65745f64656d6f63726163791870616c6c6574144576656e740404540001442050726f706f73656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000004bc41206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e185461626c656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000104d841207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e3845787465726e616c5461626c656400020494416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e1c537461727465640801247265665f696e64657810013c5265666572656e64756d496e6465780001247468726573686f6c64b40134566f74655468726573686f6c640003045c41207265666572656e64756d2068617320626567756e2e185061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000404ac412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e244e6f745061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000504ac412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e2443616e63656c6c65640401247265665f696e64657810013c5265666572656e64756d496e6465780006048041207265666572656e64756d20686173206265656e2063616e63656c6c65642e2444656c65676174656408010c77686f000130543a3a4163636f756e744964000118746172676574000130543a3a4163636f756e744964000704dc416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e2c556e64656c65676174656404011c6163636f756e74000130543a3a4163636f756e744964000804e4416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e185665746f65640c010c77686f000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114756e74696c300144426c6f636b4e756d626572466f723c543e00090494416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e2c426c61636b6c697374656404013470726f706f73616c5f6861736834011c543a3a48617368000a04c4412070726f706f73616c5f6861736820686173206265656e20626c61636b6c6973746564207065726d616e656e746c792e14566f7465640c0114766f746572000130543a3a4163636f756e7449640001247265665f696e64657810013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e000b0490416e206163636f756e742068617320766f74656420696e2061207265666572656e64756d205365636f6e6465640801207365636f6e646572000130543a3a4163636f756e74496400012870726f705f696e64657810012450726f70496e646578000c0488416e206163636f756e7420686173207365636f6e64656420612070726f706f73616c4050726f706f73616c43616e63656c656404012870726f705f696e64657810012450726f70496e646578000d0460412070726f706f73616c20676f742063616e63656c65642e2c4d657461646174615365740801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0e04d44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e207365742e3c4d65746164617461436c65617265640801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0f04e44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e20636c65617265642e4c4d657461646174615472616e736665727265640c0128707265765f6f776e6572c001344d657461646174614f776e6572046050726576696f7573206d65746164617461206f776e65722e01146f776e6572c001344d657461646174614f776e6572044c4e6577206d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e1004ac4d6574616461746120686173206265656e207472616e7366657272656420746f206e6577206f776e65722e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b40c4070616c6c65745f64656d6f637261637938766f74655f7468726573686f6c6434566f74655468726573686f6c6400010c5053757065724d616a6f72697479417070726f76650000005053757065724d616a6f72697479416761696e73740001003853696d706c654d616a6f7269747900020000b80c4070616c6c65745f64656d6f637261637910766f74652c4163636f756e74566f7465041c42616c616e636501180108205374616e64617264080110766f7465bc0110566f746500011c62616c616e636518011c42616c616e63650000001453706c697408010c61796518011c42616c616e636500010c6e617918011c42616c616e636500010000bc0c4070616c6c65745f64656d6f637261637910766f746510566f74650000040008000000c00c4070616c6c65745f64656d6f6372616379147479706573344d657461646174614f776e657200010c2045787465726e616c0000002050726f706f73616c040010012450726f70496e646578000100285265666572656e64756d040010013c5265666572656e64756d496e64657800020000c40c4470616c6c65745f636f6c6c6563746976651870616c6c6574144576656e7408045400044900011c2050726f706f73656410011c6163636f756e74000130543a3a4163636f756e74496400013870726f706f73616c5f696e64657810013450726f706f73616c496e64657800013470726f706f73616c5f6861736834011c543a3a486173680001247468726573686f6c6410012c4d656d626572436f756e74000008490141206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e3c604d656d626572436f756e7460292e14566f74656414011c6163636f756e74000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114766f746564200110626f6f6c00010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e74000108050141206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e671501612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e20417070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000204c041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2c446973617070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000304d041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e20457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c74000404210141206d6f74696f6e207761732065786563757465643b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e384d656d626572457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c740005044901412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e18436c6f7365640c013470726f706f73616c5f6861736834011c543a3a4861736800010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e740006045501412070726f706f73616c2077617320636c6f736564206265636175736520697473207468726573686f6c64207761732072656163686564206f7220616674657220697473206475726174696f6e207761732075702e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c80c3870616c6c65745f76657374696e671870616c6c6574144576656e740404540001083856657374696e675570646174656408011c6163636f756e74000130543a3a4163636f756e744964000120756e76657374656418013042616c616e63654f663c543e000008510154686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e6469636174652061206368616e676520696e2066756e647320617661696c61626c652e25015468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e4056657374696e67436f6d706c6574656404011c6163636f756e74000130543a3a4163636f756e7449640001049c416e205c5b6163636f756e745c5d20686173206265636f6d652066756c6c79207665737465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574cc0c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144576656e7404045400011c1c4e65775465726d04012c6e65775f6d656d62657273d001ec5665633c283c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e7449642c2042616c616e63654f663c543e293e000014450141206e6577207465726d2077697468206e65775f6d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e550174686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e65644501666f72207468697320707572706f73652e204120604e65775465726d285c5b5c5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e645501736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f2c626567696e20776974682e24456d7074795465726d00010831014e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6dc8604e65775465726d285c5b5c5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e34456c656374696f6e4572726f72000204e4496e7465726e616c206572726f722068617070656e6564207768696c6520747279696e6720746f20706572666f726d20656c656374696f6e2e304d656d6265724b69636b65640401186d656d6265720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000308410141206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f723060456d7074795465726d602e2452656e6f756e63656404012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400040498536f6d656f6e65206861732072656e6f756e6365642074686569722063616e6469646163792e4043616e646964617465536c617368656408012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0005103901412063616e6469646174652077617320736c617368656420627920616d6f756e742064756520746f206661696c696e6720746f206f627461696e20612073656174206173206d656d626572206f722872756e6e65722d75702e00e44e6f74652074686174206f6c64206d656d6265727320616e642072756e6e6572732d75702061726520616c736f2063616e646964617465732e4453656174486f6c646572536c617368656408012c736561745f686f6c6465720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000604350141207365617420686f6c6465722077617320736c617368656420627920616d6f756e74206279206265696e6720666f72636566756c6c792072656d6f7665642066726f6d20746865207365742e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d0000002d400d400000408001800d80c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144576656e7404045400011838536f6c7574696f6e53746f7265640c011c636f6d70757465dc013c456c656374696f6e436f6d707574650001186f726967696e8801504f7074696f6e3c543a3a4163636f756e7449643e000130707265765f656a6563746564200110626f6f6c00001cb44120736f6c7574696f6e207761732073746f72656420776974682074686520676976656e20636f6d707574652e00510154686520606f726967696e6020696e6469636174657320746865206f726967696e206f662074686520736f6c7574696f6e2e20496620606f726967696e602069732060536f6d65284163636f756e74496429602c59017468652073746f72656420736f6c7574696f6e20776173207375626d697474656420696e20746865207369676e65642070686173652062792061206d696e657220776974682074686520604163636f756e744964602e25014f74686572776973652c2074686520736f6c7574696f6e207761732073746f7265642065697468657220647572696e672074686520756e7369676e6564207068617365206f722062794d0160543a3a466f7263654f726967696e602e205468652060626f6f6c6020697320607472756560207768656e20612070726576696f757320736f6c7574696f6e2077617320656a656374656420746f206d616b6548726f6f6d20666f722074686973206f6e652e44456c656374696f6e46696e616c697a656408011c636f6d70757465dc013c456c656374696f6e436f6d7075746500011473636f7265e00134456c656374696f6e53636f7265000104190154686520656c656374696f6e20686173206265656e2066696e616c697a65642c20776974682074686520676976656e20636f6d7075746174696f6e20616e642073636f72652e38456c656374696f6e4661696c656400020c4c416e20656c656374696f6e206661696c65642e0001014e6f74206d7563682063616e20626520736169642061626f757420776869636820636f6d7075746573206661696c656420696e207468652070726f636573732e20526577617264656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0003042501416e206163636f756e7420686173206265656e20726577617264656420666f72207468656972207369676e6564207375626d697373696f6e206265696e672066696e616c697a65642e1c536c617368656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0004042101416e206163636f756e7420686173206265656e20736c617368656420666f72207375626d697474696e6720616e20696e76616c6964207369676e6564207375626d697373696f6e2e4450686173655472616e736974696f6e65640c011066726f6de4016050686173653c426c6f636b4e756d626572466f723c543e3e000108746fe4016050686173653c426c6f636b4e756d626572466f723c543e3e000114726f756e6410010c753332000504b85468657265207761732061207068617365207472616e736974696f6e20696e206120676976656e20726f756e642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574dc089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653c456c656374696f6e436f6d707574650001141c4f6e436861696e000000185369676e656400010020556e7369676e65640002002046616c6c6261636b00030024456d657267656e637900040000e0084473705f6e706f735f656c656374696f6e7334456c656374696f6e53636f726500000c01346d696e696d616c5f7374616b6518013c457874656e64656442616c616e636500012473756d5f7374616b6518013c457874656e64656442616c616e636500014473756d5f7374616b655f7371756172656418013c457874656e64656442616c616e63650000e4089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651450686173650408426e013001100c4f6666000000185369676e656400010020556e7369676e65640400e8012828626f6f6c2c20426e2900020024456d657267656e637900030000e800000408203000ec103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144576656e740404540001481c457261506169640c01246572615f696e646578100120457261496e64657800014076616c696461746f725f7061796f757418013042616c616e63654f663c543e00012472656d61696e64657218013042616c616e63654f663c543e000008550154686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973c07468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e2052657761726465640c01147374617368000130543a3a4163636f756e74496400011064657374f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000118616d6f756e7418013042616c616e63654f663c543e0001040d01546865206e6f6d696e61746f7220686173206265656e207265776172646564206279207468697320616d6f756e7420746f20746869732064657374696e6174696f6e2e1c536c61736865640801187374616b6572000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0002041d0141207374616b6572202876616c696461746f72206f72206e6f6d696e61746f722920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e34536c6173685265706f727465640c012476616c696461746f72000130543a3a4163636f756e7449640001206672616374696f6ef4011c50657262696c6c000124736c6173685f657261100120457261496e64657800030859014120736c61736820666f722074686520676976656e2076616c696461746f722c20666f722074686520676976656e2070657263656e74616765206f66207468656972207374616b652c2061742074686520676976656e54657261206173206265656e207265706f727465642e684f6c64536c617368696e675265706f727444697363617264656404013473657373696f6e5f696e64657810013053657373696f6e496e6465780004081901416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64446e6f742062652070726f6365737365642e385374616b657273456c65637465640005048441206e657720736574206f66207374616b6572732077617320656c65637465642e18426f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000610d0416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d004d014e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c210169742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e20556e626f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00070490416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e2457697468647261776e0801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0008085901416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365606466726f6d2074686520756e6c6f636b696e672071756575652e184b69636b65640801246e6f6d696e61746f72000130543a3a4163636f756e7449640001147374617368000130543a3a4163636f756e744964000904b441206e6f6d696e61746f7220686173206265656e206b69636b65642066726f6d20612076616c696461746f722e545374616b696e67456c656374696f6e4661696c6564000a04ac54686520656c656374696f6e206661696c65642e204e6f206e65772065726120697320706c616e6e65642e1c4368696c6c65640401147374617368000130543a3a4163636f756e744964000b042101416e206163636f756e74206861732073746f707065642070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e345061796f7574537461727465640801246572615f696e646578100120457261496e64657800013c76616c696461746f725f7374617368000130543a3a4163636f756e744964000c0498546865207374616b657273272072657761726473206172652067657474696e6720706169642e4456616c696461746f7250726566735365740801147374617368000130543a3a4163636f756e7449640001147072656673f8013856616c696461746f725072656673000d0498412076616c696461746f72206861732073657420746865697220707265666572656e6365732e68536e617073686f74566f7465727353697a65457863656564656404011073697a6510010c753332000e0468566f746572732073697a65206c696d697420726561636865642e6c536e617073686f745461726765747353697a65457863656564656404011073697a6510010c753332000f046c546172676574732073697a65206c696d697420726561636865642e20466f7263654572610401106d6f64650101011c466f7263696e670010047441206e657720666f72636520657261206d6f646520776173207365742e64436f6e74726f6c6c65724261746368446570726563617465640401206661696c7572657310010c753332001104a45265706f7274206f66206120636f6e74726f6c6c6572206261746368206465707265636174696f6e2e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574f0083870616c6c65745f7374616b696e674452657761726444657374696e6174696f6e04244163636f756e74496401000114185374616b656400000014537461736800010028436f6e74726f6c6c65720002001c4163636f756e7404000001244163636f756e744964000300104e6f6e6500040000f40c3473705f61726974686d65746963287065725f7468696e67731c50657262696c6c0000040010010c7533320000f8083870616c6c65745f7374616b696e673856616c696461746f7250726566730000080128636f6d6d697373696f6efc011c50657262696c6c00011c626c6f636b6564200110626f6f6c0000fc000006f4000101083870616c6c65745f7374616b696e671c466f7263696e67000110284e6f74466f7263696e6700000020466f7263654e657700010024466f7263654e6f6e650002002c466f726365416c776179730003000005010c3870616c6c65745f73657373696f6e1870616c6c6574144576656e74000104284e657753657373696f6e04013473657373696f6e5f696e64657810013053657373696f6e496e64657800000839014e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f74207468659c626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657409010c3c70616c6c65745f74726561737572791870616c6c6574144576656e74080454000449000130205370656e64696e670401406275646765745f72656d61696e696e6718013c42616c616e63654f663c542c20493e000004e45765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e1c417761726465640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000114617761726418013c42616c616e63654f663c542c20493e00011c6163636f756e74000130543a3a4163636f756e7449640001047c536f6d652066756e64732068617665206265656e20616c6c6f63617465642e144275726e7404012c6275726e745f66756e647318013c42616c616e63654f663c542c20493e00020488536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20526f6c6c6f766572040140726f6c6c6f7665725f62616c616e636518013c42616c616e63654f663c542c20493e0003042d015370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e1c4465706f73697404011476616c756518013c42616c616e63654f663c542c20493e0004047c536f6d652066756e64732068617665206265656e206465706f73697465642e345370656e64417070726f7665640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000118616d6f756e7418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640005049c41206e6577207370656e642070726f706f73616c20686173206265656e20617070726f7665642e3c55706461746564496e61637469766508012c726561637469766174656418013c42616c616e63654f663c542c20493e00012c646561637469766174656418013c42616c616e63654f663c542c20493e000604cc54686520696e6163746976652066756e6473206f66207468652070616c6c65742068617665206265656e20757064617465642e4841737365745370656e64417070726f766564180114696e6465781001285370656e64496e64657800012861737365745f6b696e64840130543a3a41737365744b696e64000118616d6f756e74180150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000138543a3a42656e656669636961727900012876616c69645f66726f6d300144426c6f636b4e756d626572466f723c543e0001246578706972655f6174300144426c6f636b4e756d626572466f723c543e000704b441206e6577206173736574207370656e642070726f706f73616c20686173206265656e20617070726f7665642e4041737365745370656e64566f69646564040114696e6465781001285370656e64496e64657800080474416e20617070726f766564207370656e642077617320766f696465642e1050616964080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a49640009044c41207061796d656e742068617070656e65642e345061796d656e744661696c6564080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a4964000a049041207061796d656e74206661696c656420616e642063616e20626520726574726965642e385370656e6450726f636573736564040114696e6465781001285370656e64496e646578000b084d0141207370656e64207761732070726f63657373656420616e642072656d6f7665642066726f6d207468652073746f726167652e204974206d696768742068617665206265656e207375636365737366756c6c797070616964206f72206974206d6179206861766520657870697265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65740d010c3c70616c6c65745f626f756e746965731870616c6c6574144576656e7408045400044900012c38426f756e747950726f706f736564040114696e64657810012c426f756e7479496e646578000004504e657720626f756e74792070726f706f73616c2e38426f756e747952656a6563746564080114696e64657810012c426f756e7479496e646578000110626f6e6418013c42616c616e63654f663c542c20493e000104cc4120626f756e74792070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e48426f756e7479426563616d65416374697665040114696e64657810012c426f756e7479496e646578000204b84120626f756e74792070726f706f73616c2069732066756e64656420616e6420626563616d65206163746976652e34426f756e747941776172646564080114696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000304944120626f756e7479206973206177617264656420746f20612062656e65666963696172792e34426f756e7479436c61696d65640c0114696e64657810012c426f756e7479496e6465780001187061796f757418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640004048c4120626f756e747920697320636c61696d65642062792062656e65666963696172792e38426f756e747943616e63656c6564040114696e64657810012c426f756e7479496e646578000504584120626f756e74792069732063616e63656c6c65642e38426f756e7479457874656e646564040114696e64657810012c426f756e7479496e646578000604704120626f756e74792065787069727920697320657874656e6465642e38426f756e7479417070726f766564040114696e64657810012c426f756e7479496e646578000704544120626f756e747920697320617070726f7665642e3c43757261746f7250726f706f736564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000804744120626f756e74792063757261746f722069732070726f706f7365642e4443757261746f72556e61737369676e6564040124626f756e74795f696410012c426f756e7479496e6465780009047c4120626f756e74792063757261746f7220697320756e61737369676e65642e3c43757261746f724163636570746564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000a04744120626f756e74792063757261746f722069732061636365707465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657411010c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144576656e74040454000110144164646564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780000046041206368696c642d626f756e74792069732061646465642e1c417761726465640c0114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000104ac41206368696c642d626f756e7479206973206177617264656420746f20612062656e65666963696172792e1c436c61696d6564100114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780001187061796f757418013042616c616e63654f663c543e00012c62656e6566696369617279000130543a3a4163636f756e744964000204a441206368696c642d626f756e747920697320636c61696d65642062792062656e65666963696172792e2043616e63656c6564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780003047041206368696c642d626f756e74792069732063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657415010c4070616c6c65745f626167735f6c6973741870616c6c6574144576656e740804540004490001082052656261676765640c010c77686f000130543a3a4163636f756e74496400011066726f6d300120543a3a53636f7265000108746f300120543a3a53636f7265000004a44d6f76656420616e206163636f756e742066726f6d206f6e652062616720746f20616e6f746865722e3053636f72655570646174656408010c77686f000130543a3a4163636f756e7449640001246e65775f73636f7265300120543a3a53636f7265000104d855706461746564207468652073636f7265206f6620736f6d65206163636f756e7420746f2074686520676976656e20616d6f756e742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657419010c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f73746174651d010124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e1d01085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e6700020000210104184f7074696f6e0404540125010108104e6f6e6500000010536f6d65040025010000010000250100000408f400002901085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7350436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d62657200002d0104184f7074696f6e0404540131010108104e6f6e6500000010536f6d650400310100000100003101085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7364436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e7449640001000035010c4070616c6c65745f7363686564756c65721870616c6c6574144576656e74040454000124245363686564756c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c753332000004505363686564756c656420736f6d65207461736b2e2043616e63656c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001044c43616e63656c656420736f6d65207461736b2e28446973706174636865640c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118726573756c748001384469737061746368526573756c74000204544469737061746368656420736f6d65207461736b2e2052657472795365741001107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118706572696f64300144426c6f636b4e756d626572466f723c543e00011c726574726965730801087538000304a0536574206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e38526574727943616e63656c6c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000404ac43616e63656c206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e3c43616c6c556e617661696c61626c650801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e00050429015468652063616c6c20666f72207468652070726f7669646564206861736820776173206e6f7420666f756e6420736f20746865207461736b20686173206265656e2061626f727465642e38506572696f6469634661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0006043d0154686520676976656e207461736b2077617320756e61626c6520746f2062652072656e657765642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b2e2c52657472794661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0007085d0154686520676976656e207461736b2077617320756e61626c6520746f20626520726574726965642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b206f722074686572659c776173206e6f7420656e6f7567682077656967687420746f2072657363686564756c652069742e545065726d616e656e746c794f7665727765696768740801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000804f054686520676976656e207461736b2063616e206e657665722062652065786563757465642073696e6365206974206973206f7665727765696768742e04304576656e747320747970652e3901000004083010003d0104184f7074696f6e04045401040108104e6f6e6500000010536f6d65040004000001000041010c3c70616c6c65745f707265696d6167651870616c6c6574144576656e7404045400010c144e6f7465640401106861736834011c543a3a48617368000004684120707265696d61676520686173206265656e206e6f7465642e245265717565737465640401106861736834011c543a3a48617368000104784120707265696d61676520686173206265656e207265717565737465642e1c436c65617265640401106861736834011c543a3a486173680002046c4120707265696d616765206861732062656e20636c65617265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657445010c3c70616c6c65745f6f6666656e6365731870616c6c6574144576656e740001041c4f6666656e63650801106b696e64490101104b696e6400012074696d65736c6f743801384f706171756554696d65536c6f7400000c5101546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e643501286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4c5c5b6b696e642c2074696d65736c6f745c5d2e04304576656e747320747970652e49010000031000000008004d010c3c70616c6c65745f74785f70617573651870616c6c6574144576656e740404540001082843616c6c50617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000004b8546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f77207061757365642e3043616c6c556e70617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000104c0546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f7720756e7061757365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574510100000408550155010055010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000059010c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144576656e7404045400010c444865617274626561745265636569766564040130617574686f726974795f69645d010138543a3a417574686f726974794964000004c041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f726974794964602e1c416c6c476f6f64000104d041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2c536f6d654f66666c696e6504011c6f66666c696e656101016c5665633c4964656e74696669636174696f6e5475706c653c543e3e000204290141742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e047c54686520604576656e746020656e756d206f6620746869732070616c6c65745d01104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139185075626c69630000040004013c737232353531393a3a5075626c696300006101000002650100650100000408006901006901082873705f7374616b696e67204578706f7375726508244163636f756e74496401001c42616c616e63650118000c0114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e00006d01000006180071010000027501007501082873705f7374616b696e6748496e646976696475616c4578706f7375726508244163636f756e74496401001c42616c616e636501180008010c77686f0001244163636f756e74496400011476616c75656d01011c42616c616e6365000079010c3c70616c6c65745f6964656e746974791870616c6c6574144576656e740404540001442c4964656e7469747953657404010c77686f000130543a3a4163636f756e744964000004ec41206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e3c4964656e74697479436c656172656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000104cc41206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e384964656e746974794b696c6c656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000204c441206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e484a756467656d656e7452657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780003049c41206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e504a756467656d656e74556e72657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780004048841206a756467656d656e74207265717565737420776173207265747261637465642e384a756467656d656e74476976656e080118746172676574000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780005049441206a756467656d656e742077617320676976656e2062792061207265676973747261722e38526567697374726172416464656404013c7265676973747261725f696e646578100138526567697374726172496e646578000604584120726567697374726172207761732061646465642e405375624964656e7469747941646465640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000704f441207375622d6964656e746974792077617320616464656420746f20616e206964656e7469747920616e6420746865206465706f73697420706169642e485375624964656e7469747952656d6f7665640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000804090141207375622d6964656e74697479207761732072656d6f7665642066726f6d20616e206964656e7469747920616e6420746865206465706f7369742066726565642e485375624964656e746974795265766f6b65640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000908190141207375622d6964656e746974792077617320636c65617265642c20616e642074686520676976656e206465706f7369742072657061747269617465642066726f6d20746865c86d61696e206964656e74697479206163636f756e7420746f20746865207375622d6964656e74697479206163636f756e742e38417574686f726974794164646564040124617574686f72697479000130543a3a4163636f756e744964000a047c4120757365726e616d6520617574686f72697479207761732061646465642e40417574686f7269747952656d6f766564040124617574686f72697479000130543a3a4163636f756e744964000b04844120757365726e616d6520617574686f72697479207761732072656d6f7665642e2c557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000c04744120757365726e616d65207761732073657420666f72206077686f602e38557365726e616d655175657565640c010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e00012865787069726174696f6e300144426c6f636b4e756d626572466f723c543e000d0419014120757365726e616d6520776173207175657565642c20627574206077686f60206d75737420616363657074206974207072696f7220746f206065787069726174696f6e602e48507265617070726f76616c4578706972656404011477686f7365000130543a3a4163636f756e744964000e043901412071756575656420757365726e616d6520706173736564206974732065787069726174696f6e20776974686f7574206265696e6720636c61696d656420616e64207761732072656d6f7665642e485072696d617279557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000f0401014120757365726e616d6520776173207365742061732061207072696d61727920616e642063616e206265206c6f6f6b65642075702066726f6d206077686f602e5c44616e676c696e67557365726e616d6552656d6f76656408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e0010085d01412064616e676c696e6720757365726e616d652028617320696e2c206120757365726e616d6520636f72726573706f6e64696e6720746f20616e206163636f756e742074686174206861732072656d6f766564206974736c6964656e746974792920686173206265656e2072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65747d010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000081010c3870616c6c65745f7574696c6974791870616c6c6574144576656e74000118404261746368496e746572727570746564080114696e64657810010c7533320001146572726f7268013444697370617463684572726f7200000855014261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061734877656c6c20617320746865206572726f722e384261746368436f6d706c65746564000104c84261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e604261746368436f6d706c65746564576974684572726f7273000204b44261746368206f66206469737061746368657320636f6d706c657465642062757420686173206572726f72732e344974656d436f6d706c657465640003041d01412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206e6f206572726f722e284974656d4661696c65640401146572726f7268013444697370617463684572726f720004041101412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206572726f722e30446973706174636865644173040118726573756c748001384469737061746368526573756c7400050458412063616c6c2077617320646973706174636865642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657485010c3c70616c6c65745f6d756c74697369671870616c6c6574144576656e740404540001102c4e65774d756c74697369670c0124617070726f76696e67000130543a3a4163636f756e7449640001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c486173680000048c41206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e404d756c7469736967417070726f76616c100124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000104c841206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e404d756c74697369674578656375746564140124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000118726573756c748001384469737061746368526573756c740002049c41206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e444d756c746973696743616e63656c6c656410012863616e63656c6c696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000304a041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65748901083c70616c6c65745f6d756c74697369672454696d65706f696e74042c426c6f636b4e756d62657201300008011868656967687430012c426c6f636b4e756d626572000114696e64657810010c75333200008d010c3c70616c6c65745f657468657265756d1870616c6c6574144576656e7400010420457865637574656414011066726f6d9101011048313630000108746f91010110483136300001407472616e73616374696f6e5f686173683401104832353600012c657869745f726561736f6e9901012845786974526561736f6e00012865787472615f6461746138011c5665633c75383e000004c8416e20657468657265756d207472616e73616374696f6e20776173207375636365737366756c6c792065786563757465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749101083c7072696d69746976655f7479706573104831363000000400950101205b75383b2032305d0000950100000314000000080099010c2065766d5f636f7265146572726f722845786974526561736f6e0001101c5375636365656404009d01012c4578697453756363656564000000144572726f720400a1010124457869744572726f72000100185265766572740400b10101284578697452657665727400020014466174616c0400b501012445786974466174616c000300009d010c2065766d5f636f7265146572726f722c457869745375636365656400010c1c53746f707065640000002052657475726e656400010020537569636964656400020000a1010c2065766d5f636f7265146572726f7224457869744572726f7200014038537461636b556e646572666c6f7700000034537461636b4f766572666c6f770001002c496e76616c69644a756d7000020030496e76616c696452616e67650003004444657369676e61746564496e76616c69640004002c43616c6c546f6f446565700005003c437265617465436f6c6c6973696f6e0006004c437265617465436f6e74726163744c696d69740007002c496e76616c6964436f64650400a50101184f70636f6465000f002c4f75744f664f6666736574000800204f75744f66476173000900244f75744f6646756e64000a002c5043556e646572666c6f77000b002c437265617465456d707479000c00144f746865720400a9010144436f773c277374617469632c207374723e000d00204d61784e6f6e6365000e0000a5010c2065766d5f636f7265186f70636f6465184f70636f64650000040008010875380000a901040c436f7704045401ad01000400ad01000000ad010000050200b1010c2065766d5f636f7265146572726f72284578697452657665727400010420526576657274656400000000b5010c2065766d5f636f7265146572726f722445786974466174616c000110304e6f74537570706f7274656400000048556e68616e646c6564496e746572727570740001004043616c6c4572726f724173466174616c0400a1010124457869744572726f72000200144f746865720400a9010144436f773c277374617469632c207374723e00030000b9010c2870616c6c65745f65766d1870616c6c6574144576656e740404540001140c4c6f6704010c6c6f67bd01010c4c6f670000047c457468657265756d206576656e74732066726f6d20636f6e7472616374732e1c4372656174656404011c616464726573739101011048313630000104b44120636f6e747261637420686173206265656e206372656174656420617420676976656e20616464726573732e34437265617465644661696c656404011c61646472657373910101104831363000020405014120636f6e74726163742077617320617474656d7074656420746f20626520637265617465642c206275742074686520657865637574696f6e206661696c65642e20457865637574656404011c616464726573739101011048313630000304f84120636f6e747261637420686173206265656e206578656375746564207375636365737366756c6c79207769746820737461746573206170706c6965642e3845786563757465644661696c656404011c61646472657373910101104831363000040465014120636f6e747261637420686173206265656e2065786563757465642077697468206572726f72732e20537461746573206172652072657665727465642077697468206f6e6c79206761732066656573206170706c6965642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574bd010c20657468657265756d0c6c6f670c4c6f6700000c011c616464726573739101011048313630000118746f70696373c10101245665633c483235363e0001106461746138011442797465730000c1010000023400c5010c3c70616c6c65745f626173655f6665651870616c6c6574144576656e7400010c404e65774261736546656550657247617304010c666565c9010110553235360000003c426173654665654f766572666c6f77000100344e6577456c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000200047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c901083c7072696d69746976655f7479706573105532353600000400cd0101205b7536343b20345d0000cd01000003040000003000d1010c3473705f61726974686d65746963287065725f7468696e67731c5065726d696c6c0000040010010c7533320000d5010c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144576656e740404540001041c436c61696d65640c0124726563697069656e74000130543a3a4163636f756e744964000118736f75726365d90101304d756c746941646472657373000118616d6f756e7418013042616c616e63654f663c543e0000048c536f6d656f6e6520636c61696d656420736f6d65206e617469766520746f6b656e732e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d9010c5470616c6c65745f61697264726f705f636c61696d73147574696c73304d756c7469416464726573730001080c45564d0400dd01013c457468657265756d41646472657373000000184e6174697665040000012c4163636f756e744964333200010000dd01105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733c457468657265756d4164647265737300000400950101205b75383b2032305d0000e1010c3070616c6c65745f70726f78791870616c6c6574144576656e740404540001143450726f78794578656375746564040118726573756c748001384469737061746368526573756c74000004bc412070726f78792077617320657865637574656420636f72726563746c792c20776974682074686520676976656e2e2c507572654372656174656410011070757265000130543a3a4163636f756e74496400010c77686f000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f787954797065000150646973616d626967756174696f6e5f696e646578e901010c753136000108dc412070757265206163636f756e7420686173206265656e2063726561746564206279206e65772070726f7879207769746820676976656e90646973616d626967756174696f6e20696e64657820616e642070726f787920747970652e24416e6e6f756e6365640c01107265616c000130543a3a4163636f756e74496400011470726f7879000130543a3a4163636f756e74496400012463616c6c5f6861736834013443616c6c486173684f663c543e000204e0416e20616e6e6f756e63656d656e742077617320706c6163656420746f206d616b6520612063616c6c20696e20746865206675747572652e2850726f7879416464656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00030448412070726f7879207761732061646465642e3050726f787952656d6f76656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00040450412070726f7879207761732072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574e501085874616e676c655f746573746e65745f72756e74696d652450726f7879547970650001100c416e790000002c4e6f6e5472616e7366657200010028476f7665726e616e63650002001c5374616b696e6700030000e9010000050400ed010c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144576656e7404045400015c384f70657261746f724a6f696e656404010c77686f000130543a3a4163636f756e7449640000045c416e206f70657261746f7220686173206a6f696e65642e604f70657261746f724c656176696e675363686564756c656404010c77686f000130543a3a4163636f756e7449640001048c416e206f70657261746f7220686173207363686564756c656420746f206c656176652e584f70657261746f724c6561766543616e63656c6c656404010c77686f000130543a3a4163636f756e744964000204b8416e206f70657261746f72206861732063616e63656c6c6564207468656972206c6561766520726571756573742e544f70657261746f724c65617665457865637574656404010c77686f000130543a3a4163636f756e744964000304b4416e206f70657261746f7220686173206578656375746564207468656972206c6561766520726571756573742e404f70657261746f72426f6e644d6f726508010c77686f000130543a3a4163636f756e74496400013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00040498416e206f70657261746f722068617320696e63726561736564207468656972207374616b652e644f70657261746f72426f6e644c6573735363686564756c656408010c77686f000130543a3a4163636f756e744964000138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504c8416e206f70657261746f7220686173207363686564756c656420746f206465637265617365207468656972207374616b652e604f70657261746f72426f6e644c657373457865637574656404010c77686f000130543a3a4163636f756e744964000604b8416e206f70657261746f7220686173206578656375746564207468656972207374616b652064656372656173652e644f70657261746f72426f6e644c65737343616e63656c6c656404010c77686f000130543a3a4163636f756e744964000704dc416e206f70657261746f72206861732063616e63656c6c6564207468656972207374616b6520646563726561736520726571756573742e4c4f70657261746f7257656e744f66666c696e6504010c77686f000130543a3a4163636f756e74496400080474416e206f70657261746f722068617320676f6e65206f66666c696e652e484f70657261746f7257656e744f6e6c696e6504010c77686f000130543a3a4163636f756e74496400090470416e206f70657261746f722068617320676f6e65206f6e6c696e652e244465706f73697465640c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964180128543a3a41737365744964000a046041206465706f73697420686173206265656e206d6164652e445363686564756c656477697468647261770c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964180128543a3a41737365744964000b047c416e20776974686472617720686173206265656e207363686564756c65642e404578656375746564776974686472617704010c77686f000130543a3a4163636f756e744964000c0478416e20776974686472617720686173206265656e2065786563757465642e4443616e63656c6c6564776974686472617704010c77686f000130543a3a4163636f756e744964000d047c416e20776974686472617720686173206265656e2063616e63656c6c65642e2444656c65676174656410010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964180128543a3a41737365744964000e046c412064656c65676174696f6e20686173206265656e206d6164652e685363686564756c656444656c656761746f72426f6e644c65737310010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964180128543a3a41737365744964000f04bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e207363686564756c65642e64457865637574656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001004b8412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2065786563757465642e6843616e63656c6c656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001104bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2063616e63656c6c65642e54496e63656e74697665415059416e644361705365740c01207661756c745f6964180128543a3a5661756c74496400010c617079f101014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e00120419014576656e7420656d6974746564207768656e20616e20696e63656e746976652041505920616e6420636170206172652073657420666f72206120726577617264207661756c7450426c75657072696e7457686974656c6973746564040130626c75657072696e745f696410010c753332001304e44576656e7420656d6974746564207768656e206120626c75657072696e742069732077686974656c697374656420666f7220726577617264734c417373657455706461746564496e5661756c7410010c77686f000130543a3a4163636f756e7449640001207661756c745f6964180128543a3a5661756c74496400012061737365745f6964180128543a3a41737365744964000118616374696f6ef501012c4173736574416374696f6e00140498417373657420686173206265656e207570646174656420746f20726577617264207661756c743c4f70657261746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e001504644f70657261746f7220686173206265656e20736c61736865644044656c656761746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0016046844656c656761746f7220686173206265656e20736c617368656404744576656e747320656d6974746564206279207468652070616c6c65742ef1010c3473705f61726974686d65746963287065725f7468696e67731c50657263656e740000040008010875380000f501107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c726577617264732c4173736574416374696f6e0001080c4164640000001852656d6f766500010000f9010c3c70616c6c65745f7365727669636573186d6f64756c65144576656e7404045400014040426c75657072696e74437265617465640801146f776e6572000130543a3a4163636f756e74496404bc546865206163636f756e742074686174206372656174656420746865207365727669636520626c75657072696e742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0004a441206e6577207365727669636520626c75657072696e7420686173206265656e20637265617465642e3c507265526567697374726174696f6e0801206f70657261746f72000130543a3a4163636f756e74496404bc546865206163636f756e742074686174207072652d7265676973746572656420617320616e206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0104dc416e206f70657261746f7220686173207072652d7265676973746572656420666f722061207365727669636520626c75657072696e742e285265676973746572656410012070726f7669646572000130543a3a4163636f756e74496404a8546865206163636f756e74207468617420726567697374657265642061732061206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e012c707265666572656e636573fd01014c4f70657261746f72507265666572656e63657304f454686520707265666572656e63657320666f7220746865206f70657261746f7220666f72207468697320737065636966696320626c75657072696e742e0144726567697374726174696f6e5f61726773090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e049054686520617267756d656e7473207573656420666f7220726567697374726174696f6e2e020490416e206e6577206f70657261746f7220686173206265656e20726567697374657265642e30556e726567697374657265640801206f70657261746f72000130543a3a4163636f756e74496404b4546865206163636f756e74207468617420756e7265676973746572656420617320616d206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e030488416e206f70657261746f7220686173206265656e20756e726567697374657265642e4c507269636554617267657473557064617465640c01206f70657261746f72000130543a3a4163636f756e74496404c4546865206163636f756e74207468617420757064617465642074686520617070726f76616c20707265666572656e63652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e013470726963655f74617267657473050201305072696365546172676574730458546865206e657720707269636520746172676574732e0404cc546865207072696365207461726765747320666f7220616e206f70657261746f7220686173206265656e20757064617465642e40536572766963655265717565737465641801146f776e6572000130543a3a4163636f756e744964049c546865206163636f756e742074686174207265717565737465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c73390201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f766564390201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e01186173736574733d02013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e05048441206e6577207365727669636520686173206265656e207265717565737465642e585365727669636552657175657374417070726f7665641401206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e74207468617420617070726f7665642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c73390201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f766564390201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e060490412073657276696365207265717565737420686173206265656e20617070726f7665642e58536572766963655265717565737452656a65637465640c01206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e7420746861742072656a65637465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e070490412073657276696365207265717565737420686173206265656e2072656a65637465642e4053657276696365496e697469617465641401146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128726571756573745f696430010c75363404c0546865204944206f662074686520736572766963652072657175657374207468617420676f7420617070726f7665642e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e01186173736574733d02013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e08047441207365727669636520686173206265656e20696e697469617465642e44536572766963655465726d696e617465640c01146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e09047841207365727669636520686173206265656e207465726d696e617465642e244a6f6243616c6c656414011863616c6c6572000130543a3a4163636f756e7449640480546865206163636f756e7420746861742063616c6c656420746865206a6f622e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e011061726773090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e046454686520617267756d656e7473206f6620746865206a6f622e0a045841206a6f6220686173206265656e2063616c6c65642e484a6f62526573756c745375626d69747465641401206f70657261746f72000130543a3a4163636f756e74496404a8546865206163636f756e742074686174207375626d697474656420746865206a6f6220726573756c742e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0118726573756c74090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e045854686520726573756c74206f6620746865206a6f622e0b048041206a6f6220726573756c7420686173206265656e207375626d69747465642e2c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e000c049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e38556e6170706c696564536c617368180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780d048c416e204f70657261746f722068617320616e20756e6170706c69656420736c6173682e38536c617368446973636172646564180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780e0484416e20556e6170706c69656420536c61736820676f74206469736361726465642e904d6173746572426c75657072696e74536572766963654d616e61676572526576697365640801207265766973696f6e10010c75333204f0546865207265766973696f6e206e756d626572206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e011c61646472657373910101104831363004d05468652061646472657373206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e0f04d8546865204d617374657220426c75657072696e742053657276696365204d616e6167657220686173206265656e20726576697365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574fd010c4474616e676c655f7072696d6974697665732073657276696365734c4f70657261746f72507265666572656e636573000008010c6b65790102013465636473613a3a5075626c696300013470726963655f74617267657473050201305072696365546172676574730000010200000321000000080005020c4474616e676c655f7072696d69746976657320736572766963657330507269636554617267657473000014010c63707530010c75363400010c6d656d30010c75363400012c73746f726167655f68646430010c75363400012c73746f726167655f73736430010c75363400013073746f726167655f6e766d6530010c753634000009020000020d02000d02104474616e676c655f7072696d697469766573207365727669636573146669656c64144669656c6408044300244163636f756e74496401000140104e6f6e6500000010426f6f6c0400200110626f6f6c0001001455696e74380400080108753800020010496e743804001102010869380003001855696e7431360400e901010c75313600040014496e74313604001502010c6931360005001855696e743332040010010c75333200060014496e74333204001902010c6933320007001855696e743634040030010c75363400080014496e74363404001d02010c69363400090018537472696e6704002102017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e000a00144279746573040025020180426f756e6465645665633c75382c20433a3a4d61784669656c647353697a653e000b001441727261790400290201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000c00104c6973740400290201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000d001853747275637408002102017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e00002d02016d01426f756e6465645665633c0a28426f756e646564537472696e673c433a3a4d61784669656c647353697a653e2c20426f783c4669656c643c432c204163636f756e7449643e3e292c20433a3a0a4d61784669656c647353697a653e000e00244163636f756e74496404000001244163636f756e744964006400001102000005090015020000050a0019020000050b001d020000050c002102104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040025020144426f756e6465645665633c75382c20533e000025020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000029020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010d02045300000400090201185665633c543e00002d020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013102045300000400350201185665633c543e000031020000040821020d02003502000002310200390200000200003d02000002180041020c4470616c6c65745f74616e676c655f6c73741870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f737461746545020124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654902019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e4d0201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e4502104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e67000200004902104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e50436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d62657200004d0204184f7074696f6e0404540151020108104e6f6e6500000010536f6d650400510200000100005102104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e64436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e74496400010000550208306672616d655f73797374656d14506861736500010c384170706c7945787472696e736963040010010c7533320000003046696e616c697a6174696f6e00010038496e697469616c697a6174696f6e0002000059020000023901005d0208306672616d655f73797374656d584c61737452756e74696d6555706772616465496e666f0000080130737065635f76657273696f6e6102014c636f6465633a3a436f6d706163743c7533323e000124737065635f6e616d65ad01016473705f72756e74696d653a3a52756e74696d65537472696e67000061020000061000650208306672616d655f73797374656d60436f646555706772616465417574686f72697a6174696f6e0404540000080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c000069020c306672616d655f73797374656d1870616c6c65741043616c6c04045400012c1872656d61726b04011872656d61726b38011c5665633c75383e00000c684d616b6520736f6d65206f6e2d636861696e2072656d61726b2e008843616e20626520657865637574656420627920657665727920606f726967696e602e387365745f686561705f7061676573040114706167657330010c753634000104f853657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e207365745f636f6465040110636f646538011c5665633c75383e0002046453657420746865206e65772072756e74696d6520636f64652e5c7365745f636f64655f776974686f75745f636865636b73040110636f646538011c5665633c75383e000310190153657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e0051014e6f746520746861742072756e74696d652075706772616465732077696c6c206e6f742072756e20696620746869732069732063616c6c656420776974682061206e6f742d696e6372656173696e6720737065632076657273696f6e212c7365745f73746f726167650401146974656d736d0201345665633c4b657956616c75653e0004046853657420736f6d65206974656d73206f662073746f726167652e306b696c6c5f73746f726167650401106b657973750201205665633c4b65793e000504744b696c6c20736f6d65206974656d732066726f6d2073746f726167652e2c6b696c6c5f70726566697808011870726566697838010c4b657900011c7375626b65797310010c75333200061011014b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e0039012a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465723d0174686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e4472656d61726b5f776974685f6576656e7404011872656d61726b38011c5665633c75383e000704a44d616b6520736f6d65206f6e2d636861696e2072656d61726b20616e6420656d6974206576656e742e44617574686f72697a655f75706772616465040124636f64655f6861736834011c543a3a486173680009106101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e80617574686f72697a655f757067726164655f776974686f75745f636865636b73040124636f64655f6861736834011c543a3a48617368000a206101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e005d015741524e494e473a205468697320617574686f72697a657320616e207570677261646520746861742077696c6c2074616b6520706c61636520776974686f757420616e792073616665747920636865636b732c20666f7259016578616d706c652074686174207468652073706563206e616d652072656d61696e73207468652073616d6520616e642074686174207468652076657273696f6e206e756d62657220696e637265617365732e204e6f74f07265636f6d6d656e64656420666f72206e6f726d616c207573652e205573652060617574686f72697a655f757067726164656020696e73746561642e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e606170706c795f617574686f72697a65645f75706772616465040110636f646538011c5665633c75383e000b24550150726f766964652074686520707265696d616765202872756e74696d652062696e617279292060636f64656020666f7220616e2075706772616465207468617420686173206265656e20617574686f72697a65642e00490149662074686520617574686f72697a6174696f6e20726571756972656420612076657273696f6e20636865636b2c20746869732063616c6c2077696c6c20656e73757265207468652073706563206e616d65e872656d61696e7320756e6368616e67656420616e6420746861742074686520737065632076657273696f6e2068617320696e637265617365642e005901446570656e64696e67206f6e207468652072756e74696d65277320604f6e536574436f64656020636f6e66696775726174696f6e2c20746869732066756e6374696f6e206d6179206469726563746c79206170706c791101746865206e65772060636f64656020696e207468652073616d6520626c6f636b206f7220617474656d707420746f207363686564756c652074686520757067726164652e0060416c6c206f726967696e732061726520616c6c6f7765642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e6d020000027102007102000004083838007502000002380079020c306672616d655f73797374656d186c696d69747330426c6f636b5765696768747300000c0128626173655f626c6f636b2801185765696768740001246d61785f626c6f636b2801185765696768740001247065725f636c6173737d0201845065724469737061746368436c6173733c57656967687473506572436c6173733e00007d020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c617373040454018102000c01186e6f726d616c810201045400012c6f7065726174696f6e616c81020104540001246d616e6461746f72798102010454000081020c306672616d655f73797374656d186c696d6974733c57656967687473506572436c6173730000100138626173655f65787472696e7369632801185765696768740001346d61785f65787472696e736963850201384f7074696f6e3c5765696768743e0001246d61785f746f74616c850201384f7074696f6e3c5765696768743e0001207265736572766564850201384f7074696f6e3c5765696768743e0000850204184f7074696f6e04045401280108104e6f6e6500000010536f6d65040028000001000089020c306672616d655f73797374656d186c696d6974732c426c6f636b4c656e677468000004010c6d61788d0201545065724469737061746368436c6173733c7533323e00008d020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540110000c01186e6f726d616c1001045400012c6f7065726174696f6e616c100104540001246d616e6461746f72791001045400009102082873705f776569676874733c52756e74696d65446257656967687400000801107265616430010c753634000114777269746530010c75363400009502082873705f76657273696f6e3852756e74696d6556657273696f6e0000200124737065635f6e616d65ad01013452756e74696d65537472696e67000124696d706c5f6e616d65ad01013452756e74696d65537472696e67000144617574686f72696e675f76657273696f6e10010c753332000130737065635f76657273696f6e10010c753332000130696d706c5f76657273696f6e10010c753332000110617069739902011c4170697356656300014c7472616e73616374696f6e5f76657273696f6e10010c75333200013473746174655f76657273696f6e080108753800009902040c436f77040454019d020004009d020000009d02000002a10200a10200000408a5021000a502000003080000000800a9020c306672616d655f73797374656d1870616c6c6574144572726f720404540001243c496e76616c6964537065634e616d650000081101546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e685370656356657273696f6e4e65656473546f496e63726561736500010841015468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e744661696c6564546f4578747261637452756e74696d6556657273696f6e00020cec4661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e0009014569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e4c4e6f6e44656661756c74436f6d706f73697465000304fc537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e3c4e6f6e5a65726f526566436f756e74000404350154686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e3043616c6c46696c7465726564000504d0546865206f726967696e2066696c7465722070726576656e74207468652063616c6c20746f20626520646973706174636865642e6c4d756c7469426c6f636b4d6967726174696f6e734f6e676f696e67000604550141206d756c74692d626c6f636b206d6967726174696f6e206973206f6e676f696e6720616e642070726576656e7473207468652063757272656e7420636f64652066726f6d206265696e67207265706c616365642e444e6f7468696e67417574686f72697a6564000704584e6f207570677261646520617574686f72697a65642e30556e617574686f72697a656400080494546865207375626d697474656420636f6465206973206e6f7420617574686f72697a65642e046c4572726f7220666f72207468652053797374656d2070616c6c6574ad020c4070616c6c65745f74696d657374616d701870616c6c65741043616c6c0404540001040c73657404010c6e6f772c0124543a3a4d6f6d656e7400004c54536574207468652063757272656e742074696d652e005501546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6ed470686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e0041015468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e7420737065636966696564206279685b60436f6e6669673a3a4d696e696d756d506572696f64605d2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0051015468697320646973706174636820636c617373206973205f4d616e6461746f72795f20746f20656e73757265206974206765747320657865637574656420696e2074686520626c6f636b2e204265206177617265510174686174206368616e67696e672074686520636f6d706c6578697479206f6620746869732063616c6c20636f756c6420726573756c742065786861757374696e6720746865207265736f757263657320696e206184626c6f636b20746f206578656375746520616e79206f746865722063616c6c732e0034232320436f6d706c657869747931012d20604f2831296020284e6f7465207468617420696d706c656d656e746174696f6e73206f6620604f6e54696d657374616d7053657460206d75737420616c736f20626520604f283129602955012d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f283129602062656361757365206f6620604469645570646174653a3a74616b656020696e402020606f6e5f66696e616c697a656029d42d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f736574602e204d75737420626520604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb1020c2c70616c6c65745f7375646f1870616c6c65741043616c6c040454000114107375646f04011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000004350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e547375646f5f756e636865636b65645f77656967687408011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000114350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e2d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b05375646f207573657220746f20737065636966792074686520776569676874206f66207468652063616c6c2e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e1c7365745f6b657904010c6e6577bd0201504163636f756e7449644c6f6f6b75704f663c543e0002085d0141757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f106b65792e1c7375646f5f617308010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0003104d0141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d406120676976656e206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2872656d6f76655f6b657900040c845065726d616e656e746c792072656d6f76657320746865207375646f206b65792e006c2a2a546869732063616e6e6f7420626520756e2d646f6e652e2a2a040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb502085874616e676c655f746573746e65745f72756e74696d652c52756e74696d6543616c6c0001941853797374656d0400690201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53797374656d2c2052756e74696d653e0001002454696d657374616d700400ad0201b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54696d657374616d702c2052756e74696d653e000200105375646f0400b10201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5375646f2c2052756e74696d653e000300184173736574730400b90201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4173736574732c2052756e74696d653e0005002042616c616e6365730400c10201b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c42616c616e6365732c2052756e74696d653e00060010426162650400c90201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426162652c2052756e74696d653e0009001c4772616e6470610400ed0201b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4772616e6470612c2052756e74696d653e000a001c496e646963657304001d0301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496e64696365732c2052756e74696d653e000b002444656d6f63726163790400210301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44656d6f63726163792c2052756e74696d653e000c001c436f756e63696c04003d0301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436f756e63696c2c2052756e74696d653e000d001c56657374696e670400410301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c56657374696e672c2052756e74696d653e000e0024456c656374696f6e730400490301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e732c2052756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400510301fd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e50726f76696465724d756c746950686173652c2052756e74696d653e0010001c5374616b696e670400390401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5374616b696e672c2052756e74696d653e0011001c53657373696f6e04006d0401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657373696f6e2c2052756e74696d653e0012002054726561737572790400750401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54726561737572792c2052756e74696d653e00140020426f756e7469657304007d0401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426f756e746965732c2052756e74696d653e001500344368696c64426f756e746965730400810401c90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4368696c64426f756e746965732c2052756e74696d653e00160020426167734c6973740400850401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426167734c6973742c2052756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c730400890401d10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4e6f6d696e6174696f6e506f6f6c732c2052756e74696d653e001800245363686564756c65720400a50401b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5363686564756c65722c2052756e74696d653e00190020507265696d6167650400ad0401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c507265696d6167652c2052756e74696d653e001a001c547850617573650400b10401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c547850617573652c2052756e74696d653e001c0020496d4f6e6c696e650400b50401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496d4f6e6c696e652c2052756e74696d653e001d00204964656e746974790400c10401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4964656e746974792c2052756e74696d653e001e001c5574696c6974790400650501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5574696c6974792c2052756e74696d653e001f00204d756c746973696704007d0501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c74697369672c2052756e74696d653e00200020457468657265756d0400850501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c457468657265756d2c2052756e74696d653e0021000c45564d0400ad0501a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c45564d2c2052756e74696d653e0022002844796e616d69634665650400bd0501bd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44796e616d69634665652c2052756e74696d653e0024001c426173654665650400c10501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426173654665652c2052756e74696d653e00250044486f7466697853756666696369656e74730400c50501d90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c486f7466697853756666696369656e74732c2052756e74696d653e00260018436c61696d730400cd0501ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436c61696d732c2052756e74696d653e0027001450726f78790400f90501a90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c50726f78792c2052756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400010601e50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c7469417373657444656c65676174696f6e2c2052756e74696d653e002d002053657276696365730400150601b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657276696365732c2052756e74696d653e0033000c4c73740400e50601a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4c73742c2052756e74696d653e00340000b9020c3470616c6c65745f6173736574731870616c6c65741043616c6c080454000449000180186372656174650c010869646d01014c543a3a41737365744964506172616d6574657200011461646d696ebd0201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e6365180128543a3a42616c616e636500004ce849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d2061207075626c6963206f726967696e2e00250154686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c7920616e6420697473206f776e657220697320746865206f726967696e2e006101546865206f726967696e206d75737420636f6e666f726d20746f2074686520636f6e6669677572656420604372656174654f726967696e6020616e6420686176652073756666696369656e742066756e647320667265652e00bc46756e6473206f662073656e64657220617265207265736572766564206279206041737365744465706f736974602e002c506172616d65746572733a59012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d206061646d696e603a205468652061646d696e206f66207468697320636c617373206f66206173736574732e205468652061646d696e2069732074686520696e697469616c2061646472657373206f6620656163689c6d656d626572206f662074686520617373657420636c61737327732061646d696e207465616d2e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e0098456d69747320604372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296030666f7263655f63726561746510010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e00013469735f73756666696369656e74200110626f6f6c00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500014cf849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d20612070726976696c65676564206f726967696e2e00b454686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c792e00a4546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e602e009c556e6c696b652060637265617465602c206e6f2066756e6473206172652072657365727665642e0059012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d20606f776e6572603a20546865206f776e6572206f66207468697320636c617373206f66206173736574732e20546865206f776e6572206861732066756c6c20737570657275736572207065726d697373696f6e7325016f76657220746869732061737365742c20627574206d6179206c61746572206368616e676520616e6420636f6e66696775726520746865207065726d697373696f6e73207573696e6790607472616e736665725f6f776e6572736869706020616e6420607365745f7465616d602e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e00ac456d6974732060466f7263654372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f283129603473746172745f64657374726f7904010869646d01014c543a3a41737365744964506172616d6574657200022cdc5374617274207468652070726f63657373206f662064657374726f79696e6720612066756e6769626c6520617373657420636c6173732e0059016073746172745f64657374726f79602069732074686520666972737420696e206120736572696573206f662065787472696e7369637320746861742073686f756c642062652063616c6c65642c20746f20616c6c6f77786465737472756374696f6e206f6620616e20617373657420636c6173732e005101546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e60206f72206d75737420626520605369676e65646020627920746865206173736574277320606f776e6572602e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00f854686520617373657420636c617373206d7573742062652066726f7a656e206265666f72652063616c6c696e67206073746172745f64657374726f79602e4064657374726f795f6163636f756e747304010869646d01014c543a3a41737365744964506172616d65746572000330cc44657374726f7920616c6c206163636f756e7473206173736f6369617465642077697468206120676976656e2061737365742e005d016064657374726f795f6163636f756e7473602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79310164657374726f7920616c6c206163636f756e74732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d697460206163636f756e747320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d4456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f7965644163636f756e747360206576656e742e4464657374726f795f617070726f76616c7304010869646d01014c543a3a41737365744964506172616d65746572000430610144657374726f7920616c6c20617070726f76616c73206173736f6369617465642077697468206120676976656e20617373657420757020746f20746865206d61782028543a3a52656d6f76654974656d734c696d6974292e0061016064657374726f795f617070726f76616c73602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79390164657374726f7920616c6c20617070726f76616c732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d69746020617070726f76616c7320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d8456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f796564417070726f76616c7360206576656e742e3866696e6973685f64657374726f7904010869646d01014c543a3a41737365744964506172616d65746572000528c4436f6d706c6574652064657374726f79696e6720617373657420616e6420756e726573657276652063757272656e63792e0055016066696e6973685f64657374726f79602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e64207468655901617373657420697320696e2061206044657374726f79696e67602073746174652e20416c6c206163636f756e7473206f7220617070726f76616c732073686f756c642062652064657374726f796564206265666f72651468616e642e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00e045616368207375636365737366756c2063616c6c20656d6974732074686520604576656e743a3a44657374726f79656460206576656e742e106d696e740c010869646d01014c543a3a41737365744964506172616d6574657200012c62656e6566696369617279bd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000630884d696e7420617373657473206f66206120706172746963756c617220636c6173732e003901546865206f726967696e206d757374206265205369676e656420616e64207468652073656e646572206d7573742062652074686520497373756572206f662074686520617373657420606964602e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206d696e7465642e0d012d206062656e6566696369617279603a20546865206163636f756e7420746f206265206372656469746564207769746820746865206d696e746564206173736574732ec42d2060616d6f756e74603a2054686520616d6f756e74206f662074686520617373657420746f206265206d696e7465642e0094456d697473206049737375656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296055014d6f6465733a205072652d6578697374696e672062616c616e6365206f66206062656e6566696369617279603b204163636f756e74207072652d6578697374656e6365206f66206062656e6566696369617279602e106275726e0c010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500073c4501526564756365207468652062616c616e6365206f66206077686f60206279206173206d75636820617320706f737369626c6520757020746f2060616d6f756e746020617373657473206f6620606964602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204d616e61676572206f662074686520617373657420606964602e00d04261696c73207769746820604e6f4163636f756e746020696620746865206077686f6020697320616c726561647920646561642e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206275726e65642ea02d206077686f603a20546865206163636f756e7420746f20626520646562697465642066726f6d2e29012d2060616d6f756e74603a20546865206d6178696d756d20616d6f756e74206279207768696368206077686f6027732062616c616e63652073686f756c6420626520726564756365642e005101456d69747320604275726e6564602077697468207468652061637475616c20616d6f756e74206275726e65642e20496620746869732074616b6573207468652062616c616e636520746f2062656c6f772074686539016d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74206275726e656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296009014d6f6465733a20506f73742d6578697374656e6365206f66206077686f603b20507265202620706f7374205a6f6d6269652d737461747573206f66206077686f602e207472616e736665720c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000848d04d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e4c7472616e736665725f6b6565705f616c6976650c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500094859014d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722c206b656570696e67207468652073656e646572206163636f756e7420616c6976652e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e38666f7263655f7472616e7366657210010869646d01014c543a3a41737365744964506172616d65746572000118736f75726365bd0201504163636f756e7449644c6f6f6b75704f663c543e00011064657374bd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000a4cb44d6f766520736f6d65206173736574732066726f6d206f6e65206163636f756e7420746f20616e6f746865722e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e982d2060736f75726365603a20546865206163636f756e7420746f20626520646562697465642e942d206064657374603a20546865206163636f756e7420746f2062652063726564697465642e59012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652060736f757263656027732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e64590160646573746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e4d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652060736f75726365602062616c616e63652061626f7665207a65726f20627574d462656c6f7720746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f66206064657374603b20506f73742d6578697374656e6365206f662060736f75726365603b204163636f756e74207072652d6578697374656e6365206f661c6064657374602e18667265657a6508010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000b305501446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e20617373657420606964602066726f6d20616e206163636f756e74206077686f602e206077686f604d016d75737420616c726561647920657869737420617320616e20656e74727920696e20604163636f756e746073206f66207468652061737365742e20496620796f752077616e7420746f20667265657a6520616ef46163636f756e74207468617420646f6573206e6f74206861766520616e20656e7472792c207573652060746f7563685f6f74686572602066697273742e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e882d206077686f603a20546865206163636f756e7420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f28312960107468617708010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000c28e8416c6c6f7720756e70726976696c65676564207472616e736665727320746f20616e642066726f6d20616e206163636f756e7420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e902d206077686f603a20546865206163636f756e7420746f20626520756e66726f7a656e2e003c456d6974732060546861776564602e00385765696768743a20604f2831296030667265657a655f617373657404010869646d01014c543a3a41737365744964506172616d65746572000d24f0446973616c6c6f77206675727468657220756e70726976696c65676564207472616e736665727320666f722074686520617373657420636c6173732e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f2831296028746861775f617373657404010869646d01014c543a3a41737365744964506172616d65746572000e24c4416c6c6f7720756e70726976696c65676564207472616e736665727320666f722074686520617373657420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206265207468617765642e003c456d6974732060546861776564602e00385765696768743a20604f28312960487472616e736665725f6f776e65727368697008010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e000f28744368616e676520746865204f776e6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742e0054456d69747320604f776e65724368616e676564602e00385765696768743a20604f28312960207365745f7465616d10010869646d01014c543a3a41737365744964506172616d65746572000118697373756572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ebd0201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572bd0201504163636f756e7449644c6f6f6b75704f663c543e001030c44368616e676520746865204973737565722c2041646d696e20616e6420467265657a6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e0050456d69747320605465616d4368616e676564602e00385765696768743a20604f28312960307365745f6d6574616461746110010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c7308010875380011407853657420746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00d846756e6473206f662073656e64657220617265207265736572766564206163636f7264696e6720746f2074686520666f726d756c613a5101604d657461646174614465706f73697442617365202b204d657461646174614465706f73697450657242797465202a20286e616d652e6c656e202b2073796d626f6c2e6c656e29602074616b696e6720696e746f8c6163636f756e7420616e7920616c72656164792072657365727665642066756e64732e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e00385765696768743a20604f2831296038636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200122c80436c65617220746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00a4416e79206465706f73697420697320667265656420666f7220746865206173736574206f776e65722e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f7365745f6d6574616461746114010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c001338b8466f72636520746865206d6574616461746120666f7220616e20617373657420746f20736f6d652076616c75652e006c4f726967696e206d75737420626520466f7263654f726967696e2e0068416e79206465706f736974206973206c65667420616c6f6e652e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e0051015765696768743a20604f284e202b20532960207768657265204e20616e6420532061726520746865206c656e677468206f6620746865206e616d6520616e642073796d626f6c20726573706563746976656c792e50666f7263655f636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200142c80436c65617220746865206d6574616461746120666f7220616e2061737365742e006c4f726967696e206d75737420626520466f7263654f726967696e2e0060416e79206465706f7369742069732072657475726e65642e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f61737365745f73746174757320010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e000118697373756572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ebd0201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572bd0201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500013469735f73756666696369656e74200110626f6f6c00012469735f66726f7a656e200110626f6f6c00155898416c746572207468652061747472696275746573206f66206120676976656e2061737365742e00744f726967696e206d7573742062652060466f7263654f726967696e602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e51012d206069735f73756666696369656e74603a20576865746865722061206e6f6e2d7a65726f2062616c616e6365206f662074686973206173736574206973206465706f736974206f662073756666696369656e744d0176616c756520746f206163636f756e7420666f722074686520737461746520626c6f6174206173736f6369617465642077697468206974732062616c616e63652073746f726167652e2049662073657420746f55016074727565602c207468656e206e6f6e2d7a65726f2062616c616e636573206d61792062652073746f72656420776974686f757420612060636f6e73756d657260207265666572656e63652028616e6420746875734d01616e20454420696e207468652042616c616e6365732070616c6c6574206f7220776861746576657220656c7365206973207573656420746f20636f6e74726f6c20757365722d6163636f756e742073746174652067726f777468292e3d012d206069735f66726f7a656e603a2057686574686572207468697320617373657420636c6173732069732066726f7a656e2065786365707420666f72207065726d697373696f6e65642f61646d696e34696e737472756374696f6e732e00e8456d697473206041737365745374617475734368616e67656460207769746820746865206964656e74697479206f66207468652061737365742e00385765696768743a20604f2831296040617070726f76655f7472616e736665720c010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650016502d01417070726f766520616e20616d6f756e74206f6620617373657420666f72207472616e7366657220627920612064656c6567617465642074686972642d7061727479206163636f756e742e00584f726967696e206d757374206265205369676e65642e004d01456e737572657320746861742060417070726f76616c4465706f7369746020776f727468206f66206043757272656e6379602069732072657365727665642066726f6d207369676e696e67206163636f756e745501666f722074686520707572706f7365206f6620686f6c64696e672074686520617070726f76616c2e20496620736f6d65206e6f6e2d7a65726f20616d6f756e74206f662061737365747320697320616c72656164794901617070726f7665642066726f6d207369676e696e67206163636f756e7420746f206064656c6567617465602c207468656e20697420697320746f70706564207570206f7220756e726573657276656420746f546d656574207468652072696768742076616c75652e0045014e4f54453a20546865207369676e696e67206163636f756e7420646f6573206e6f74206e65656420746f206f776e2060616d6f756e7460206f66206173736574732061742074686520706f696e74206f66446d616b696e6720746869732063616c6c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e0d012d206064656c6567617465603a20546865206163636f756e7420746f2064656c6567617465207065726d697373696f6e20746f207472616e736665722061737365742e49012d2060616d6f756e74603a2054686520616d6f756e74206f662061737365742074686174206d6179206265207472616e73666572726564206279206064656c6567617465602e204966207468657265206973e0616c726561647920616e20617070726f76616c20696e20706c6163652c207468656e207468697320616374732061646469746976656c792e0090456d6974732060417070726f7665645472616e7366657260206f6e20737563636573732e00385765696768743a20604f283129603c63616e63656c5f617070726f76616c08010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e001734490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e003d014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c616365206265747765656e207369676e657220616e642c6064656c6567617465602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f2831296054666f7263655f63616e63656c5f617070726f76616c0c010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e00012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e001834490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e0049014f726967696e206d7573742062652065697468657220466f7263654f726967696e206f72205369676e6564206f726967696e207769746820746865207369676e6572206265696e67207468652041646d696e686163636f756e74206f662074686520617373657420606964602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f28312960447472616e736665725f617070726f76656410010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e00012c64657374696e6174696f6ebd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650019484d015472616e7366657220736f6d652061737365742062616c616e63652066726f6d20612070726576696f75736c792064656c656761746564206163636f756e7420746f20736f6d652074686972642d7061727479206163636f756e742e0049014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c6163652062792074686520606f776e65726020746f207468651c7369676e65722e00590149662074686520656e7469726520616d6f756e7420617070726f76656420666f72207472616e73666572206973207472616e736665727265642c207468656e20616e79206465706f7369742070726576696f75736c79b472657365727665642062792060617070726f76655f7472616e736665726020697320756e72657365727665642e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e61012d20606f776e6572603a20546865206163636f756e742077686963682070726576696f75736c7920617070726f76656420666f722061207472616e73666572206f66206174206c656173742060616d6f756e746020616e64bc66726f6d207768696368207468652061737365742062616c616e63652077696c6c2062652077697468647261776e2e61012d206064657374696e6174696f6e603a20546865206163636f756e7420746f207768696368207468652061737365742062616c616e6365206f662060616d6f756e74602077696c6c206265207472616e736665727265642eb42d2060616d6f756e74603a2054686520616d6f756e74206f662061737365747320746f207472616e736665722e009c456d69747320605472616e73666572726564417070726f76656460206f6e20737563636573732e00385765696768743a20604f2831296014746f75636804010869646d01014c543a3a41737365744964506172616d65746572001a24c043726561746520616e206173736574206163636f756e7420666f72206e6f6e2d70726f7669646572206173736574732e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e005d012d20606f726967696e603a204d757374206265205369676e65643b20746865207369676e6572206163636f756e74206d75737420686176652073756666696369656e742066756e647320666f722061206465706f736974382020746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e18726566756e6408010869646d01014c543a3a41737365744964506172616d65746572000128616c6c6f775f6275726e200110626f6f6c001b28590152657475726e20746865206465706f7369742028696620616e7929206f6620616e206173736574206163636f756e74206f72206120636f6e73756d6572207265666572656e63652028696620616e7929206f6620616e206163636f756e742e0068546865206f726967696e206d757374206265205369676e65642e003d012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f72207768696368207468652063616c6c657220776f756c64206c696b6520746865206465706f7369742c2020726566756e6465642e5d012d2060616c6c6f775f6275726e603a20496620607472756560207468656e20617373657473206d61792062652064657374726f79656420696e206f7264657220746f20636f6d706c6574652074686520726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e3c7365745f6d696e5f62616c616e636508010869646d01014c543a3a41737365744964506172616d6574657200012c6d696e5f62616c616e6365180128543a3a42616c616e6365001c30945365747320746865206d696e696d756d2062616c616e6365206f6620616e2061737365742e0021014f6e6c7920776f726b73206966207468657265206172656e277420616e79206163636f756e747320746861742061726520686f6c64696e6720746865206173736574206f72206966e0746865206e65772076616c7565206f6620606d696e5f62616c616e636560206973206c657373207468616e20746865206f6c64206f6e652e00fc4f726967696e206d757374206265205369676e656420616e64207468652073656e6465722068617320746f20626520746865204f776e6572206f66207468652c617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742ec02d20606d696e5f62616c616e6365603a20546865206e65772076616c7565206f6620606d696e5f62616c616e6365602e00d4456d697473206041737365744d696e42616c616e63654368616e67656460206576656e74207768656e207375636365737366756c2e2c746f7563685f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e001d288843726561746520616e206173736574206163636f756e7420666f72206077686f602e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e0061012d20606f726967696e603a204d757374206265205369676e65642062792060467265657a657260206f72206041646d696e60206f662074686520617373657420606964603b20746865207369676e6572206163636f756e74dc20206d75737420686176652073756666696369656e742066756e647320666f722061206465706f73697420746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e8c2d206077686f603a20546865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e30726566756e645f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e001e285d0152657475726e20746865206465706f7369742028696620616e7929206f66206120746172676574206173736574206163636f756e742e2055736566756c20696620796f752061726520746865206465706f7369746f722e005d01546865206f726967696e206d757374206265205369676e656420616e642065697468657220746865206163636f756e74206f776e65722c206465706f7369746f722c206f72206173736574206041646d696e602e20496e61016f7264657220746f206275726e2061206e6f6e2d7a65726f2062616c616e6365206f66207468652061737365742c207468652063616c6c6572206d75737420626520746865206163636f756e7420616e642073686f756c64347573652060726566756e64602e0019012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420686f6c64696e672061206465706f7369742e7c2d206077686f603a20546865206163636f756e7420746f20726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e14626c6f636b08010869646d01014c543a3a41737365744964506172616d6574657200010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e001f285901446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e206173736574206069646020746f20616e642066726f6d20616e206163636f756e74206077686f602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00b82d20606964603a20546865206964656e746966696572206f6620746865206163636f756e7427732061737365742e942d206077686f603a20546865206163636f756e7420746f20626520756e626c6f636b65642e0040456d6974732060426c6f636b6564602e00385765696768743a20604f28312960040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ebd020c2873705f72756e74696d65306d756c746961646472657373304d756c74694164647265737308244163636f756e7449640100304163636f756e74496e6465780110011408496404000001244163636f756e74496400000014496e6465780400610201304163636f756e74496e6465780001000c526177040038011c5665633c75383e0002002441646472657373333204000401205b75383b2033325d000300244164647265737332300400950101205b75383b2032305d00040000c1020c3c70616c6c65745f62616c616e6365731870616c6c65741043616c6c080454000449000124507472616e736665725f616c6c6f775f646561746808011064657374bd0201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e636500001cd45472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e003501607472616e736665725f616c6c6f775f6465617468602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e11014966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74b06f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e38666f7263655f7472616e736665720c0118736f75726365bd0201504163636f756e7449644c6f6f6b75704f663c543e00011064657374bd0201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000208610145786163746c7920617320607472616e736665725f616c6c6f775f6465617468602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74446d6179206265207370656369666965642e4c7472616e736665725f6b6565705f616c69766508011064657374bd0201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000318590153616d6520617320746865205b607472616e736665725f616c6c6f775f6465617468605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74606b696c6c20746865206f726967696e206163636f756e742e00e8393925206f66207468652074696d6520796f752077616e74205b607472616e736665725f616c6c6f775f6465617468605d20696e73746561642e00f05b607472616e736665725f616c6c6f775f6465617468605d3a207374727563742e50616c6c65742e68746d6c236d6574686f642e7472616e73666572307472616e736665725f616c6c08011064657374bd0201504163636f756e7449644c6f6f6b75704f663c543e0001286b6565705f616c697665200110626f6f6c00043c05015472616e736665722074686520656e74697265207472616e7366657261626c652062616c616e63652066726f6d207468652063616c6c6572206163636f756e742e0059014e4f54453a20546869732066756e6374696f6e206f6e6c7920617474656d70747320746f207472616e73666572205f7472616e7366657261626c655f2062616c616e6365732e2054686973206d65616e7320746861746101616e79206c6f636b65642c2072657365727665642c206f72206578697374656e7469616c206465706f7369747320287768656e20606b6565705f616c6976656020697320607472756560292c2077696c6c206e6f742062655d017472616e7366657272656420627920746869732066756e6374696f6e2e20546f20656e73757265207468617420746869732066756e6374696f6e20726573756c747320696e2061206b696c6c6564206163636f756e742c4501796f75206d69676874206e65656420746f207072657061726520746865206163636f756e742062792072656d6f76696e6720616e79207265666572656e636520636f756e746572732c2073746f72616765406465706f736974732c206574632e2e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205369676e65642e00a02d206064657374603a2054686520726563697069656e74206f6620746865207472616e736665722e59012d20606b6565705f616c697665603a204120626f6f6c65616e20746f2064657465726d696e652069662074686520607472616e736665725f616c6c60206f7065726174696f6e2073686f756c642073656e6420616c6c4d0120206f66207468652066756e647320746865206163636f756e74206861732c2063617573696e67207468652073656e646572206163636f756e7420746f206265206b696c6c6564202866616c7365292c206f72590120207472616e736665722065766572797468696e6720657863657074206174206c6561737420746865206578697374656e7469616c206465706f7369742c2077686963682077696c6c2067756172616e74656520746f9c20206b656570207468652073656e646572206163636f756e7420616c697665202874727565292e3c666f7263655f756e7265736572766508010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e74180128543a3a42616c616e636500050cb0556e7265736572766520736f6d652062616c616e63652066726f6d2061207573657220627920666f7263652e006c43616e206f6e6c792062652063616c6c656420627920524f4f542e40757067726164655f6163636f756e747304010c77686f390201445665633c543a3a4163636f756e7449643e0006207055706772616465206120737065636966696564206163636f756e742e00742d20606f726967696e603a204d75737420626520605369676e6564602e902d206077686f603a20546865206163636f756e7420746f2062652075706772616465642e005501546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966206174206c6561737420616c6c2062757420313025206f6620746865206163636f756e7473206e656564656420746f410162652075706772616465642e20285765206c657420736f6d65206e6f74206861766520746f206265207570677261646564206a75737420696e206f7264657220746f20616c6c6f7720666f722074686558706f73736962696c697479206f6620636875726e292e44666f7263655f7365745f62616c616e636508010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e0001206e65775f667265656d010128543a3a42616c616e636500080cac5365742074686520726567756c61722062616c616e6365206f66206120676976656e206163636f756e742e00b0546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e6c666f7263655f61646a7573745f746f74616c5f69737375616e6365080124646972656374696f6ec502014c41646a7573746d656e74446972656374696f6e00011464656c74616d010128543a3a42616c616e6365000914b841646a7573742074686520746f74616c2069737375616e636520696e20612073617475726174696e67207761792e00fc43616e206f6e6c792062652063616c6c656420627920726f6f7420616e6420616c77617973206e65656473206120706f736974697665206064656c7461602e002423204578616d706c65106275726e08011476616c75656d010128543a3a42616c616e63650001286b6565705f616c697665200110626f6f6c000a1cfc4275726e2074686520737065636966696564206c697175696420667265652062616c616e63652066726f6d20746865206f726967696e206163636f756e742e002501496620746865206f726967696e2773206163636f756e7420656e64732075702062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c7409016f6620746865206275726e20616e6420606b6565705f616c697665602069732066616c73652c20746865206163636f756e742077696c6c206265207265617065642e005101556e6c696b652073656e64696e672066756e647320746f2061205f6275726e5f20616464726573732c207768696368206d6572656c79206d616b6573207468652066756e647320696e61636365737369626c652c21017468697320606275726e60206f7065726174696f6e2077696c6c2072656475636520746f74616c2069737375616e63652062792074686520616d6f756e74205f6275726e65645f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5020c3c70616c6c65745f62616c616e6365731474797065734c41646a7573746d656e74446972656374696f6e00010820496e63726561736500000020446563726561736500010000c9020c2c70616c6c65745f626162651870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66cd020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66dd020140543a3a4b65794f776e657250726f6f6600001009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66cd020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66dd020140543a3a4b65794f776e657250726f6f6600012009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e0d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e48706c616e5f636f6e6669675f6368616e6765040118636f6e666967e10201504e657874436f6e66696744657363726970746f720002105d01506c616e20616e2065706f636820636f6e666967206368616e67652e205468652065706f636820636f6e666967206368616e6765206973207265636f7264656420616e642077696c6c20626520656e6163746564206f6e5101746865206e6578742063616c6c20746f2060656e6163745f65706f63685f6368616e6765602e2054686520636f6e6669672077696c6c20626520616374697661746564206f6e652065706f63682061667465722e59014d756c7469706c652063616c6c7320746f2074686973206d6574686f642077696c6c207265706c61636520616e79206578697374696e6720706c616e6e656420636f6e666967206368616e6765207468617420686164546e6f74206265656e20656e6163746564207965742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ecd02084873705f636f6e73656e7375735f736c6f74734445717569766f636174696f6e50726f6f66081848656164657201d10208496401d502001001206f6666656e646572d50201084964000110736c6f74d9020110536c6f7400013066697273745f686561646572d10201184865616465720001347365636f6e645f686561646572d10201184865616465720000d102102873705f72756e74696d651c67656e65726963186865616465721848656164657208184e756d62657201301048617368000014012c706172656e745f68617368340130486173683a3a4f75747075740001186e756d6265722c01184e756d62657200012873746174655f726f6f74340130486173683a3a4f757470757400013c65787472696e736963735f726f6f74340130486173683a3a4f75747075740001186469676573743c01184469676573740000d5020c4473705f636f6e73656e7375735f626162650c617070185075626c69630000040004013c737232353531393a3a5075626c69630000d902084873705f636f6e73656e7375735f736c6f747310536c6f740000040030010c7536340000dd02082873705f73657373696f6e3c4d656d6265727368697050726f6f6600000c011c73657373696f6e10013053657373696f6e496e646578000128747269655f6e6f646573750201305665633c5665633c75383e3e00013c76616c696461746f725f636f756e7410013856616c696461746f72436f756e740000e1020c4473705f636f6e73656e7375735f626162651c64696765737473504e657874436f6e66696744657363726970746f7200010408563108010463e5020128287536342c2075363429000134616c6c6f7765645f736c6f7473e9020130416c6c6f776564536c6f747300010000e50200000408303000e902084473705f636f6e73656e7375735f6261626530416c6c6f776564536c6f747300010c305072696d617279536c6f7473000000745072696d617279416e645365636f6e64617279506c61696e536c6f74730001006c5072696d617279416e645365636f6e64617279565246536c6f747300020000ed020c3870616c6c65745f6772616e6470611870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66f10201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f6619030140543a3a4b65794f776e657250726f6f6600001009015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66f10201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f6619030140543a3a4b65794f776e657250726f6f6600012409015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e000d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e306e6f74655f7374616c6c656408011464656c6179300144426c6f636b4e756d626572466f723c543e00016c626573745f66696e616c697a65645f626c6f636b5f6e756d626572300144426c6f636b4e756d626572466f723c543e0002303d014e6f74652074686174207468652063757272656e7420617574686f7269747920736574206f6620746865204752414e4450412066696e616c6974792067616467657420686173207374616c6c65642e006101546869732077696c6c2074726967676572206120666f7263656420617574686f7269747920736574206368616e67652061742074686520626567696e6e696e67206f6620746865206e6578742073657373696f6e2c20746f6101626520656e6163746564206064656c61796020626c6f636b7320616674657220746861742e20546865206064656c6179602073686f756c64206265206869676820656e6f75676820746f20736166656c7920617373756d654901746861742074686520626c6f636b207369676e616c6c696e672074686520666f72636564206368616e67652077696c6c206e6f742062652072652d6f7267656420652e672e203130303020626c6f636b732e5d0154686520626c6f636b2070726f64756374696f6e207261746520287768696368206d617920626520736c6f77656420646f776e2062656361757365206f662066696e616c697479206c616767696e67292073686f756c64510162652074616b656e20696e746f206163636f756e74207768656e2063686f6f73696e6720746865206064656c6179602e20546865204752414e44504120766f74657273206261736564206f6e20746865206e65775501617574686f726974792077696c6c20737461727420766f74696e67206f6e20746f70206f662060626573745f66696e616c697a65645f626c6f636b5f6e756d6265726020666f72206e65772066696e616c697a65644d01626c6f636b732e2060626573745f66696e616c697a65645f626c6f636b5f6e756d626572602073686f756c64206265207468652068696768657374206f6620746865206c61746573742066696e616c697a6564c4626c6f636b206f6620616c6c2076616c696461746f7273206f6620746865206e657720617574686f72697479207365742e00584f6e6c792063616c6c61626c6520627920726f6f742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef102085073705f636f6e73656e7375735f6772616e6470614445717569766f636174696f6e50726f6f660804480134044e0130000801187365745f6964300114536574496400013065717569766f636174696f6ef502014845717569766f636174696f6e3c482c204e3e0000f502085073705f636f6e73656e7375735f6772616e6470613045717569766f636174696f6e0804480134044e013001081c507265766f74650400f90201890166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265766f74653c0a482c204e3e2c20417574686f726974795369676e61747572652c3e00000024507265636f6d6d697404000d0301910166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265636f6d6d69740a3c482c204e3e2c20417574686f726974795369676e61747572652c3e00010000f902084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a8045601fd02045301010300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273740903011828562c2053290001187365636f6e640903011828562c2053290000fd02084066696e616c6974795f6772616e6470611c507265766f74650804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000001030c5073705f636f6e73656e7375735f6772616e6470610c617070245369676e61747572650000040005030148656432353531393a3a5369676e617475726500000503000003400000000800090300000408fd020103000d03084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456011103045301010300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273741503011828562c2053290001187365636f6e641503011828562c20532900001103084066696e616c6974795f6772616e64706124507265636f6d6d69740804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000015030000040811030103001903081c73705f636f726510566f6964000100001d030c3870616c6c65745f696e64696365731870616c6c65741043616c6c04045400011414636c61696d040114696e64657810013c543a3a4163636f756e74496e6465780000309841737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e00dc5061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00f02d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e207472616e7366657208010c6e6577bd0201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e6465780001305d0141737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6eb86973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0025012d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e1066726565040114696e64657810013c543a3a4163636f756e74496e646578000230944672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e005d015061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e000d012d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e0084456d6974732060496e646578467265656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e38666f7263655f7472616e736665720c010c6e6577bd0201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e646578000118667265657a65200110626f6f6c0003345501466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c7265616479e868656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00a42d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e41012d2060667265657a65603a2069662073657420746f206074727565602c2077696c6c20667265657a652074686520696e64657820736f2069742063616e6e6f74206265207472616e736665727265642e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e18667265657a65040114696e64657810013c543a3a4163636f756e74496e6465780004304101467265657a6520616e20696e64657820736f2069742077696c6c20616c7761797320706f696e7420746f207468652073656e646572206163636f756e742e205468697320636f6e73756d657320746865206465706f7369742e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d757374206861766520616c6e6f6e2d66726f7a656e206163636f756e742060696e646578602e00ac2d2060696e646578603a2074686520696e64657820746f2062652066726f7a656e20696e20706c6163652e0088456d6974732060496e64657846726f7a656e60206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e21030c4070616c6c65745f64656d6f63726163791870616c6c65741043616c6c04045400014c1c70726f706f736508012070726f706f73616c25030140426f756e64656443616c6c4f663c543e00011476616c75656d01013042616c616e63654f663c543e0000249c50726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e001501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737480686176652066756e647320746f20636f76657220746865206465706f7369742e00d42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e15012d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e0044456d697473206050726f706f736564602e187365636f6e6404012070726f706f73616c6102012450726f70496e646578000118b45369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e64657211016d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e00c82d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e10766f74650801247265665f696e6465786102013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e00021c3101566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3bb86f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00dc2d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e842d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e40656d657267656e63795f63616e63656c0401247265665f696e64657810013c5265666572656e64756d496e6465780003204d015363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d652c7265666572656e64756d2e00f8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e00d02d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e003c5765696768743a20604f283129602e4065787465726e616c5f70726f706f736504012070726f706f73616c25030140426f756e64656443616c6c4f663c543e0004182d015363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c2c7265666572656e64756d2e00e8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e6465787465726e616c5f70726f706f73655f6d616a6f7269747904012070726f706f73616c25030140426f756e64656443616c6c4f663c543e00052c55015363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c655c616e2065787465726e616c207265666572656e64756d2e00ec546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f283129606065787465726e616c5f70726f706f73655f64656661756c7404012070726f706f73616c25030140426f756e64656443616c6c4f663c543e00062c45015363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f807363686564756c6520616e2065787465726e616c207265666572656e64756d2e00e8546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f2831296028666173745f747261636b0c013470726f706f73616c5f6861736834011c543a3a48617368000134766f74696e675f706572696f64300144426c6f636b4e756d626572466f723c543e00011464656c6179300144426c6f636b4e756d626572466f723c543e0007404d015363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c65646101696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e65e8627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e00d0546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e00f42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e5d012d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f88094d75737420626520616c776179732067726561746572207468616e207a65726f2e350109466f72206046617374547261636b4f726967696e60206d75737420626520657175616c206f722067726561746572207468616e206046617374547261636b566f74696e67506572696f64602e51012d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265b82020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e0040456d697473206053746172746564602e00385765696768743a20604f28312960347665746f5f65787465726e616c04013470726f706f73616c5f6861736834011c543a3a48617368000824b85665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e00d8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e002d012d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e003c456d69747320605665746f6564602e00fc5765696768743a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f657273604463616e63656c5f7265666572656e64756d0401247265665f696e6465786102013c5265666572656e64756d496e64657800091c5052656d6f76652061207265666572656e64756d2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e00d42d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e004423205765696768743a20604f283129602e2064656c65676174650c0108746fbd0201504163636f756e7449644c6f6f6b75704f663c543e000128636f6e76696374696f6e31030128436f6e76696374696f6e00011c62616c616e636518013042616c616e63654f663c543e000a50390144656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e0055015468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f7220746865c874696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a7420202d2062652064656c65676174696e6720616c72656164793b206f72590120202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656494202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e0045012d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e55012d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e20746865410120206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e61012d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d757374206e6f74b420206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e0048456d697473206044656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e28756e64656c6567617465000b30cc556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e005d01546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64dc6f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062655463757272656e746c792064656c65676174696e672e0050456d6974732060556e64656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e58636c6561725f7075626c69635f70726f706f73616c73000c1470436c6561727320616c6c207075626c69632070726f706f73616c732e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e003c5765696768743a20604f283129602e18756e6c6f636b040118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e000d1ca0556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00b82d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e00bc5765696768743a20604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e2c72656d6f76655f766f7465040114696e64657810013c5265666572656e64756d496e646578000e6c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e000c49663a882d20746865207265666572656e64756d207761732063616e63656c6c65642c206f727c2d20746865207265666572656e64756d206973206f6e676f696e672c206f72902d20746865207265666572656e64756d2068617320656e64656420737563682074686174fc20202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f72d420202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f728420202d20746865206163636f756e74206d61646520612073706c697420766f74655d012e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72655866756e6473206265696e6720617661696c61626c652e00a849662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643aec2d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64dc2d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64bc2d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f76657259012e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c766559012a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756de46f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e004901546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465887265676973746572656420666f72207265666572656e64756d2060696e646578602e00f42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e4472656d6f76655f6f746865725f766f7465080118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c5265666572656e64756d496e646578000f3c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e004d0149662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f2d016072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c5501656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7298626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e004d012d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f725420207265666572656e64756d2060696e646578602ef42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e24626c61636b6c69737408013470726f706f73616c5f6861736834011c543a3a4861736800013c6d617962655f7265665f696e6465783503015c4f7074696f6e3c5265666572656e64756d496e6465783e00103c45015065726d616e656e746c7920706c61636520612070726f706f73616c20696e746f2074686520626c61636b6c6973742e20546869732070726576656e74732069742066726f6d2065766572206265696e673c70726f706f73656420616761696e2e00510149662063616c6c6564206f6e206120717565756564207075626c6963206f722065787465726e616c2070726f706f73616c2c207468656e20746869732077696c6c20726573756c7420696e206974206265696e67510172656d6f7665642e2049662074686520607265665f696e6465786020737570706c69656420697320616e20616374697665207265666572656e64756d2077697468207468652070726f706f73616c20686173682c687468656e2069742077696c6c2062652063616e63656c6c65642e00ec546865206469737061746368206f726967696e206f6620746869732063616c6c206d7573742062652060426c61636b6c6973744f726967696e602e00f82d206070726f706f73616c5f68617368603a205468652070726f706f73616c206861736820746f20626c61636b6c697374207065726d616e656e746c792e45012d20607265665f696e646578603a20416e206f6e676f696e67207265666572656e64756d2077686f73652068617368206973206070726f706f73616c5f68617368602c2077686963682077696c6c2062652863616e63656c6c65642e0041015765696768743a20604f28702960202874686f756768206173207468697320697320616e20686967682d70726976696c6567652064697370617463682c20776520617373756d65206974206861732061502020726561736f6e61626c652076616c7565292e3c63616e63656c5f70726f706f73616c04012870726f705f696e6465786102012450726f70496e64657800111c4852656d6f766520612070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c50726f706f73616c4f726967696e602e00d02d206070726f705f696e646578603a2054686520696e646578206f66207468652070726f706f73616c20746f2063616e63656c2e00e45765696768743a20604f28702960207768657265206070203d205075626c696350726f70733a3a3c543e3a3a6465636f64655f6c656e282960307365745f6d657461646174610801146f776e6572c001344d657461646174614f776e65720001286d617962655f686173683903013c4f7074696f6e3c543a3a486173683e00123cd8536574206f7220636c6561722061206d65746164617461206f6620612070726f706f73616c206f722061207265666572656e64756d2e002c506172616d65746572733acc2d20606f726967696e603a204d75737420636f72726573706f6e6420746f2074686520604d657461646174614f776e6572602e3d01202020202d206045787465726e616c4f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479417070726f766560402020202020207468726573686f6c642e5901202020202d206045787465726e616c44656661756c744f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479416761696e737460402020202020207468726573686f6c642e4501202020202d206045787465726e616c4d616a6f726974794f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053696d706c654d616a6f7269747960402020202020207468726573686f6c642ec8202020202d20605369676e65646020627920612063726561746f7220666f722061207075626c69632070726f706f73616c2ef4202020202d20605369676e65646020746f20636c6561722061206d6574616461746120666f7220612066696e6973686564207265666572656e64756d2ee4202020202d2060526f6f746020746f207365742061206d6574616461746120666f7220616e206f6e676f696e67207265666572656e64756d2eb42d20606f776e6572603a20616e206964656e746966696572206f662061206d65746164617461206f776e65722e51012d20606d617962655f68617368603a205468652068617368206f6620616e206f6e2d636861696e2073746f72656420707265696d6167652e20604e6f6e656020746f20636c6561722061206d657461646174612e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e250310346672616d655f737570706f72741874726169747324707265696d616765731c426f756e64656408045401b5020448012903010c184c656761637904011068617368340124483a3a4f757470757400000018496e6c696e6504002d030134426f756e646564496e6c696e65000100184c6f6f6b757008011068617368340124483a3a4f757470757400010c6c656e10010c7533320002000029030c2873705f72756e74696d65187472616974732c426c616b6554776f323536000000002d030c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000031030c4070616c6c65745f64656d6f637261637928636f6e76696374696f6e28436f6e76696374696f6e00011c104e6f6e65000000204c6f636b65643178000100204c6f636b65643278000200204c6f636b65643378000300204c6f636b65643478000400204c6f636b65643578000500204c6f636b6564367800060000350304184f7074696f6e04045401100108104e6f6e6500000010536f6d650400100000010000390304184f7074696f6e04045401340108104e6f6e6500000010536f6d6504003400000100003d030c4470616c6c65745f636f6c6c6563746976651870616c6c65741043616c6c0804540004490001182c7365745f6d656d626572730c012c6e65775f6d656d62657273390201445665633c543a3a4163636f756e7449643e0001147072696d658801504f7074696f6e3c543a3a4163636f756e7449643e0001246f6c645f636f756e7410012c4d656d626572436f756e74000060805365742074686520636f6c6c6563746976652773206d656d626572736869702e0045012d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642ee02d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e59012d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e205573656420666f7250202077656967687420657374696d6174696f6e2e00d4546865206469737061746368206f6620746869732063616c6c206d75737420626520605365744d656d626572734f726967696e602e0051014e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d61784d656d6265727360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c2062757421012020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e002823205741524e494e473a005901546865206070616c6c65742d636f6c6c656374697665602063616e20616c736f206265206d616e61676564206279206c6f676963206f757473696465206f66207468652070616c6c6574207468726f75676820746865b8696d706c656d656e746174696f6e206f6620746865207472616974205b604368616e67654d656d62657273605d2e5501416e792063616c6c20746f20607365745f6d656d6265727360206d757374206265206361726566756c207468617420746865206d656d6265722073657420646f65736e277420676574206f7574206f662073796e63a477697468206f74686572206c6f676963206d616e6167696e6720746865206d656d626572207365742e0038232320436f6d706c65786974793a502d20604f284d50202b204e29602077686572653ae020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429e020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564299820202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564291c6578656375746508012070726f706f73616cb502017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646102010c753332000124f0446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e00a84f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e0038232320436f6d706c65786974793a5c2d20604f2842202b204d202b205029602077686572653ad82d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429882d20604d60206d656d626572732d636f756e742028636f64652d626f756e64656429a82d2060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c601c70726f706f73650c01247468726573686f6c646102012c4d656d626572436f756e7400012070726f706f73616cb502017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646102010c753332000238f84164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e00845265717569726573207468652073656e64657220746f206265206d656d6265722e004101607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029546f722070757420757020666f7220766f74696e672e0034232320436f6d706c6578697479ac2d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c420202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653af4202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c20326029fc202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d2032602910766f74650c012070726f706f73616c34011c543a3a48617368000114696e6465786102013450726f706f73616c496e64657800011c617070726f7665200110626f6f6c000324f041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e008c5265717569726573207468652073656e64657220746f2062652061206d656d6265722e0049015472616e73616374696f6e20666565732077696c6c2062652077616976656420696620746865206d656d62657220697320766f74696e67206f6e20616e7920706172746963756c61722070726f706f73616c5101666f72207468652066697273742074696d6520616e64207468652063616c6c206973207375636365737366756c2e2053756273657175656e7420766f7465206368616e6765732077696c6c206368617267652061106665652e34232320436f6d706c657869747909012d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564294c646973617070726f76655f70726f706f73616c04013470726f706f73616c5f6861736834011c543a3a486173680005285901446973617070726f766520612070726f706f73616c2c20636c6f73652c20616e642072656d6f76652069742066726f6d207468652073797374656d2c207265676172646c657373206f66206974732063757272656e741873746174652e00884d7573742062652063616c6c65642062792074686520526f6f74206f726967696e2e002c506172616d65746572733a1d012a206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20746861742073686f756c6420626520646973617070726f7665642e0034232320436f6d706c6578697479ac4f285029207768657265205020697320746865206e756d626572206f66206d61782070726f706f73616c7314636c6f736510013470726f706f73616c5f6861736834011c543a3a48617368000114696e6465786102013450726f706f73616c496e64657800015470726f706f73616c5f7765696768745f626f756e642801185765696768740001306c656e6774685f626f756e646102010c7533320006604d01436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e0055014d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e00490149662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f7465206966206974206973bc68617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e00490149662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e732501756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e00610149662074686520636c6f7365206f7065726174696f6e20636f6d706c65746573207375636365737366756c6c79207769746820646973617070726f76616c2c20746865207472616e73616374696f6e206665652077696c6c5d016265207761697665642e204f746865727769736520657865637574696f6e206f662074686520617070726f766564206f7065726174696f6e2077696c6c206265206368617267656420746f207468652063616c6c65722e0061012b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642470726f706f73616c2e61012b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b65642076696135016073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e0034232320436f6d706c6578697479742d20604f2842202b204d202b205031202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c820202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652ea420202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e41030c3870616c6c65745f76657374696e671870616c6c65741043616c6c0404540001181076657374000024b8556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e005d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e28766573745f6f74686572040118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e00012cb8556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051012d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e3c7665737465645f7472616e73666572080118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65450301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00023464437265617465206120766573746564207472616e736665722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00cc2d2060746172676574603a20546865206163636f756e7420726563656976696e6720746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e54666f7263655f7665737465645f7472616e736665720c0118736f75726365bd0201504163636f756e7449644c6f6f6b75704f663c543e000118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65450301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00033860466f726365206120766573746564207472616e736665722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00e82d2060736f75726365603a20546865206163636f756e742077686f73652066756e64732073686f756c64206265207472616e736665727265642e11012d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e3c6d657267655f7363686564756c657308013c7363686564756c65315f696e64657810010c75333200013c7363686564756c65325f696e64657810010c7533320004545d014d657267652074776f2076657374696e67207363686564756c657320746f6765746865722c206372656174696e672061206e65772076657374696e67207363686564756c65207468617420756e6c6f636b73206f7665725501746865206869676865737420706f737369626c6520737461727420616e6420656e6420626c6f636b732e20496620626f7468207363686564756c6573206861766520616c7265616479207374617274656420746865590163757272656e7420626c6f636b2077696c6c206265207573656420617320746865207363686564756c652073746172743b207769746820746865206361766561742074686174206966206f6e65207363686564756c655d0169732066696e6973686564206279207468652063757272656e7420626c6f636b2c20746865206f746865722077696c6c206265207472656174656420617320746865206e6577206d6572676564207363686564756c652c2c756e6d6f6469666965642e00f84e4f54453a20496620607363686564756c65315f696e646578203d3d207363686564756c65325f696e6465786020746869732069732061206e6f2d6f702e41014e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b207072696f7220746f206d657267696e672e61014e4f54453a20496620626f7468207363686564756c6573206861766520656e646564206279207468652063757272656e7420626c6f636b2c206e6f206e6577207363686564756c652077696c6c206265206372656174656464616e6420626f74682077696c6c2062652072656d6f7665642e006c4d6572676564207363686564756c6520617474726962757465733a35012d20607374617274696e675f626c6f636b603a20604d4158287363686564756c65312e7374617274696e675f626c6f636b2c207363686564756c6564322e7374617274696e675f626c6f636b2c48202063757272656e745f626c6f636b29602e21012d2060656e64696e675f626c6f636b603a20604d4158287363686564756c65312e656e64696e675f626c6f636b2c207363686564756c65322e656e64696e675f626c6f636b29602e59012d20606c6f636b6564603a20607363686564756c65312e6c6f636b65645f61742863757272656e745f626c6f636b29202b207363686564756c65322e6c6f636b65645f61742863757272656e745f626c6f636b29602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00e82d20607363686564756c65315f696e646578603a20696e646578206f6620746865206669727374207363686564756c6520746f206d657267652eec2d20607363686564756c65325f696e646578603a20696e646578206f6620746865207365636f6e64207363686564756c6520746f206d657267652e74666f7263655f72656d6f76655f76657374696e675f7363686564756c65080118746172676574bd02018c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263650001387363686564756c655f696e64657810010c7533320005187c466f7263652072656d6f766520612076657374696e67207363686564756c6500c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00c82d2060746172676574603a20416e206163636f756e7420746861742068617320612076657374696e67207363686564756c6515012d20607363686564756c655f696e646578603a205468652076657374696e67207363686564756c6520696e64657820746861742073686f756c642062652072656d6f766564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e45030c3870616c6c65745f76657374696e673076657374696e675f696e666f2c56657374696e67496e666f081c42616c616e636501182c426c6f636b4e756d6265720130000c01186c6f636b656418011c42616c616e63650001247065725f626c6f636b18011c42616c616e63650001387374617274696e675f626c6f636b30012c426c6f636b4e756d626572000049030c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c65741043616c6c04045400011810766f7465080114766f746573390201445665633c543a3a4163636f756e7449643e00011476616c75656d01013042616c616e63654f663c543e00004c5901566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746fe07365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e005d0155706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e642061206465706f73697420616d6f756e742069734d0172657365727665642e20546865206465706f736974206973206261736564206f6e20746865206e756d626572206f6620766f74657320616e642063616e2062652075706461746564206f7665722074696d652e004c5468652060766f746573602073686f756c643a4420202d206e6f7420626520656d7074792e550120202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e6411012020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e0049014966206076616c756560206973206d6f7265207468616e206077686f60277320667265652062616c616e63652c207468656e20746865206d6178696d756d206f66207468652074776f20697320757365642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e6700550149742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f202a2a4e4f542a2a20706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865a86c6f636b20616e64206b65657020736f6d6520666f722066757274686572206f7065726174696f6e732e3072656d6f76655f766f7465720001146c52656d6f766520606f726967696e60206173206120766f7465722e00b8546869732072656d6f76657320746865206c6f636b20616e642072657475726e7320746865206465706f7369742e00fc546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420616e64206265206120766f7465722e407375626d69745f63616e64696461637904013c63616e6469646174655f636f756e746102010c75333200023c11015375626d6974206f6e6573656c6620666f722063616e6469646163792e204120666978656420616d6f756e74206f66206465706f736974206973207265636f726465642e005d01416c6c2063616e64696461746573206172652077697065642061742074686520656e64206f6620746865207465726d2e205468657920656974686572206265636f6d652061206d656d6265722f72756e6e65722d75702ccc6f72206c65617665207468652073797374656d207768696c65207468656972206465706f73697420697320736c61736865642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e67005d014576656e20696620612063616e64696461746520656e6473207570206265696e672061206d656d6265722c2074686579206d7573742063616c6c205b6043616c6c3a3a72656e6f756e63655f63616e646964616379605d5901746f20676574207468656972206465706f736974206261636b2e204c6f73696e67207468652073706f7420696e20616e20656c656374696f6e2077696c6c20616c77617973206c65616420746f206120736c6173682e000901546865206e756d626572206f662063757272656e742063616e64696461746573206d7573742062652070726f7669646564206173207769746e65737320646174612e34232320436f6d706c6578697479a44f2843202b206c6f672843292920776865726520432069732063616e6469646174655f636f756e742e4872656e6f756e63655f63616e64696461637904012872656e6f756e63696e674d03012852656e6f756e63696e670003504d0152656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c3c6f7574636f6d65732065786973743a0049012d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c20746865206465706f736974206973f02020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e61012d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c20746865206465706f73697420697320756e72657365727665642c2072657475726e656420616e648c20206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e55012d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c20746865206465706f73697420697320756e726573657276656420616e64206f726967696e2069735501202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e6101202053696d696c617220746f205b6072656d6f76655f6d656d626572605d2853656c663a3a72656d6f76655f6d656d626572292c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865795901202061726520696d6d6564696174656c7920757365642e20496620746865207072696d652069732072656e6f756e63696e672c207468656e206e6f207072696d652077696c6c20657869737420756e74696c207468653420206e65787420726f756e642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642c20616e642068617665206f6e65206f66207468652061626f766520726f6c65732ee05468652074797065206f662072656e6f756e63696e67206d7573742062652070726f7669646564206173207769746e65737320646174612e0034232320436f6d706c6578697479dc20202d2052656e6f756e63696e673a3a43616e64696461746528636f756e74293a204f28636f756e74202b206c6f6728636f756e7429297020202d2052656e6f756e63696e673a3a4d656d6265723a204f2831297820202d2052656e6f756e63696e673a3a52756e6e657255703a204f2831293472656d6f76655f6d656d6265720c010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000128736c6173685f626f6e64200110626f6f6c000138726572756e5f656c656374696f6e200110626f6f6c000440590152656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f667c746865206f7574676f696e67206d656d62657220697320736c61736865642e005501496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c616365732074686555016f7574676f696e67206d656d6265722e204f74686572776973652c2069662060726572756e5f656c656374696f6e60206973206074727565602c2061206e65772070687261676d656e20656c656374696f6e2069737c737461727465642c20656c73652c206e6f7468696e672068617070656e732e00590149662060736c6173685f626f6e64602069732073657420746f20747275652c2074686520626f6e64206f6620746865206d656d626572206265696e672072656d6f76656420697320736c61736865642e20456c73652c3c69742069732072657475726e65642e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0041014e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e0034232320436f6d706c657869747905012d20436865636b2064657461696c73206f662072656d6f76655f616e645f7265706c6163655f6d656d626572282920616e6420646f5f70687261676d656e28292e50636c65616e5f646566756e63745f766f746572730801286e756d5f766f7465727310010c75333200012c6e756d5f646566756e637410010c7533320005244501436c65616e20616c6c20766f746572732077686f2061726520646566756e63742028692e652e207468657920646f206e6f7420736572766520616e7920707572706f736520617420616c6c292e20546865ac6465706f736974206f66207468652072656d6f76656420766f74657273206172652072657475726e65642e0001015468697320697320616e20726f6f742066756e6374696f6e20746f2062652075736564206f6e6c7920666f7220636c65616e696e67207468652073746174652e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0034232320436f6d706c65786974798c2d20436865636b2069735f646566756e63745f766f74657228292064657461696c732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e4d03086470616c6c65745f656c656374696f6e735f70687261676d656e2852656e6f756e63696e6700010c184d656d6265720000002052756e6e657255700001002443616e64696461746504006102010c7533320002000051030c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c65741043616c6c0404540001143c7375626d69745f756e7369676e65640801307261775f736f6c7574696f6e550301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e00011c7769746e65737325040158536f6c7574696f6e4f72536e617073686f7453697a65000038a45375626d6974206120736f6c7574696f6e20666f722074686520756e7369676e65642070686173652e00c8546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f6e6f6e655f5f2e003d0154686973207375626d697373696f6e20697320636865636b6564206f6e2074686520666c792e204d6f72656f7665722c207468697320756e7369676e656420736f6c7574696f6e206973206f6e6c79550176616c696461746564207768656e207375626d697474656420746f2074686520706f6f6c2066726f6d20746865202a2a6c6f63616c2a2a206e6f64652e204566666563746976656c792c2074686973206d65616e735d0174686174206f6e6c79206163746976652076616c696461746f72732063616e207375626d69742074686973207472616e73616374696f6e207768656e20617574686f72696e67206120626c6f636b202873696d696c617240746f20616e20696e686572656e74292e005901546f2070726576656e7420616e7920696e636f727265637420736f6c7574696f6e2028616e642074687573207761737465642074696d652f776569676874292c2074686973207472616e73616374696f6e2077696c6c4d0170616e69632069662074686520736f6c7574696f6e207375626d6974746564206279207468652076616c696461746f7220697320696e76616c696420696e20616e79207761792c206566666563746976656c799c70757474696e6720746865697220617574686f72696e6720726577617264206174207269736b2e00e04e6f206465706f736974206f7220726577617264206973206173736f63696174656420776974682074686973207375626d697373696f6e2e6c7365745f6d696e696d756d5f756e747275737465645f73636f72650401406d617962655f6e6578745f73636f7265290401544f7074696f6e3c456c656374696f6e53636f72653e000114b05365742061206e65772076616c756520666f7220604d696e696d756d556e7472757374656453636f7265602e00d84469737061746368206f726967696e206d75737420626520616c69676e656420776974682060543a3a466f7263654f726967696e602e00f05468697320636865636b2063616e206265207475726e6564206f66662062792073657474696e67207468652076616c756520746f20604e6f6e65602e747365745f656d657267656e63795f656c656374696f6e5f726573756c74040120737570706f7274732d040158537570706f7274733c543a3a4163636f756e7449643e0002205901536574206120736f6c7574696f6e20696e207468652071756575652c20746f2062652068616e646564206f757420746f2074686520636c69656e74206f6620746869732070616c6c657420696e20746865206e6578748863616c6c20746f2060456c656374696f6e50726f76696465723a3a656c656374602e004501546869732063616e206f6e6c79206265207365742062792060543a3a466f7263654f726967696e602c20616e64206f6e6c79207768656e207468652070686173652069732060456d657267656e6379602e00610154686520736f6c7574696f6e206973206e6f7420636865636b656420666f7220616e7920666561736962696c69747920616e6420697320617373756d656420746f206265207472757374776f727468792c20617320616e795101666561736962696c69747920636865636b20697473656c662063616e20696e207072696e6369706c652063617573652074686520656c656374696f6e2070726f6365737320746f206661696c202864756520746f686d656d6f72792f77656967687420636f6e73747261696e73292e187375626d69740401307261775f736f6c7574696f6e550301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e0003249c5375626d6974206120736f6c7574696f6e20666f7220746865207369676e65642070686173652e00d0546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f7369676e65645f5f2e005d0154686520736f6c7574696f6e20697320706f74656e7469616c6c79207175657565642c206261736564206f6e2074686520636c61696d65642073636f726520616e642070726f6365737365642061742074686520656e64506f6620746865207369676e65642070686173652e005d0141206465706f73697420697320726573657276656420616e64207265636f7264656420666f722074686520736f6c7574696f6e2e204261736564206f6e20746865206f7574636f6d652c2074686520736f6c7574696f6e15016d696768742062652072657761726465642c20736c61736865642c206f722067657420616c6c206f7220612070617274206f6620746865206465706f736974206261636b2e4c676f7665726e616e63655f66616c6c6261636b0801406d617962655f6d61785f766f746572733503012c4f7074696f6e3c7533323e0001446d617962655f6d61785f746172676574733503012c4f7074696f6e3c7533323e00041080547269676765722074686520676f7665726e616e63652066616c6c6261636b2e004901546869732063616e206f6e6c792062652063616c6c6564207768656e205b6050686173653a3a456d657267656e6379605d20697320656e61626c65642c20617320616e20616c7465726e617469766520746fc063616c6c696e67205b6043616c6c3a3a7365745f656d657267656e63795f656c656374696f6e5f726573756c74605d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5503089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173652c526177536f6c7574696f6e040453015903000c0120736f6c7574696f6e590301045300011473636f7265e00134456c656374696f6e53636f7265000114726f756e6410010c75333200005903085874616e676c655f746573746e65745f72756e74696d65384e706f73536f6c7574696f6e31360000400118766f746573315d0300000118766f74657332690300000118766f746573337d0300000118766f74657334890300000118766f74657335950300000118766f74657336a10300000118766f74657337ad0300000118766f74657338b90300000118766f74657339c5030000011c766f7465733130d1030000011c766f7465733131dd030000011c766f7465733132e9030000011c766f7465733133f5030000011c766f746573313401040000011c766f74657331350d040000011c766f746573313619040000005d0300000261030061030000040861026503006503000006e9010069030000026d03006d030000040c610271036503007103000004086503750300750300000679030079030c3473705f61726974686d65746963287065725f7468696e67731850657255313600000400e901010c75313600007d0300000281030081030000040c6102850365030085030000030200000071030089030000028d03008d030000040c61029103650300910300000303000000710300950300000299030099030000040c61029d036503009d0300000304000000710300a103000002a50300a5030000040c6102a903650300a90300000305000000710300ad03000002b10300b1030000040c6102b503650300b50300000306000000710300b903000002bd0300bd030000040c6102c103650300c10300000307000000710300c503000002c90300c9030000040c6102cd03650300cd0300000308000000710300d103000002d50300d5030000040c6102d903650300d90300000309000000710300dd03000002e10300e1030000040c6102e503650300e5030000030a000000710300e903000002ed0300ed030000040c6102f103650300f1030000030b000000710300f503000002f90300f9030000040c6102fd03650300fd030000030c000000710300010400000205040005040000040c6102090465030009040000030d0000007103000d0400000211040011040000040c6102150465030015040000030e00000071030019040000021d04001d040000040c6102210465030021040000030f0000007103002504089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736558536f6c7574696f6e4f72536e617073686f7453697a650000080118766f746572736102010c75333200011c746172676574736102010c7533320000290404184f7074696f6e04045401e00108104e6f6e6500000010536f6d650400e000000100002d04000002310400310400000408003504003504084473705f6e706f735f656c656374696f6e731c537570706f727404244163636f756e744964010000080114746f74616c18013c457874656e64656442616c616e6365000118766f74657273d001845665633c284163636f756e7449642c20457874656e64656442616c616e6365293e00003904103870616c6c65745f7374616b696e671870616c6c65741870616c6c65741043616c6c04045400017810626f6e6408011476616c75656d01013042616c616e63654f663c543e0001147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000040610154616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c80626520746865206163636f756e74207468617420636f6e74726f6c732069742e002d016076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e002101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e003c456d6974732060426f6e646564602e34232320436f6d706c6578697479d02d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e1c2d204f2831292e642d20546872656520657874726120444220656e74726965732e004d014e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e65645901756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20286f7220657175616c20746f20302920616e6420676574732072656d6f76656420617320647573742e28626f6e645f65787472610401386d61785f6164646974696f6e616c6d01013042616c616e63654f663c543e000138610141646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757030666f72207374616b696e672e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e004d01557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e5501556e6c696b65205b60626f6e64605d2853656c663a3a626f6e6429206f72205b60756e626f6e64605d2853656c663a3a756e626f6e642920746869732066756e6374696f6e20646f6573206e6f7420696d706f7365bc616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e003c456d6974732060426f6e646564602e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e1c2d204f2831292e18756e626f6e6404011476616c75656d01013042616c616e63654f663c543e00024c51015363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e64fc706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e2101543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0045014f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665bc7468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e0031014e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d6178556e6c6f636b696e674368756e6b736029410163616e20636f2d657869737473206174207468652073616d652074696d652e20496620746865726520617265206e6f20756e6c6f636b696e67206368756e6b7320736c6f747320617661696c61626c6545015b6043616c6c3a3a77697468647261775f756e626f6e646564605d2069732063616c6c656420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e00390149662061207573657220656e636f756e74657273207468652060496e73756666696369656e74426f6e6460206572726f72207768656e2063616c6c696e6720746869732065787472696e7369632c1901746865792073686f756c642063616c6c20606368696c6c6020666972737420696e206f7264657220746f206672656520757020746865697220626f6e6465642066756e64732e0044456d6974732060556e626f6e646564602e009453656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e4477697468647261775f756e626f6e6465640401486e756d5f736c617368696e675f7370616e7310010c75333200035c290152656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e0055015468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722469742077616e74732e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722e0048456d697473206057697468647261776e602e006853656520616c736f205b6043616c6c3a3a756e626f6e64605d2e0034232320506172616d65746572730051012d20606e756d5f736c617368696e675f7370616e736020696e6469636174657320746865206e756d626572206f66206d6574616461746120736c617368696e67207370616e7320746f20636c656172207768656e5501746869732063616c6c20726573756c747320696e206120636f6d706c6574652072656d6f76616c206f6620616c6c2074686520646174612072656c6174656420746f20746865207374617368206163636f756e742e3d01496e207468697320636173652c2074686520606e756d5f736c617368696e675f7370616e7360206d757374206265206c6172676572206f7220657175616c20746f20746865206e756d626572206f665d01736c617368696e67207370616e73206173736f636961746564207769746820746865207374617368206163636f756e7420696e20746865205b60536c617368696e675370616e73605d2073746f7261676520747970652c25016f7468657277697365207468652063616c6c2077696c6c206661696c2e205468652063616c6c20776569676874206973206469726563746c792070726f706f7274696f6e616c20746f54606e756d5f736c617368696e675f7370616e73602e0034232320436f6d706c6578697479d84f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f766509014e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e2076616c69646174650401147072656673f8013856616c696461746f725072656673000414e44465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e206e6f6d696e61746504011c746172676574733d0401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e0005280d014465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c65786974792d012d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e29050177686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542028543a3a4d61784e6f6d696e6174696f6e73292ed42d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e146368696c6c000628c44465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e502d20436f6e7461696e73206f6e6520726561642ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e247365745f70617965650401147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000730b42852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479182d204f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e242d2d2d2d2d2d2d2d2d387365745f636f6e74726f6c6c657200083845012852652d29736574732074686520636f6e74726f6c6c6572206f66206120737461736820746f2074686520737461736820697473656c662e20546869732066756e6374696f6e2070726576696f75736c794d01616363657074656420612060636f6e74726f6c6c65726020617267756d656e7420746f207365742074686520636f6e74726f6c6c657220746f20616e206163636f756e74206f74686572207468616e207468655901737461736820697473656c662e20546869732066756e6374696f6e616c69747920686173206e6f77206265656e2072656d6f7665642c206e6f77206f6e6c792073657474696e672074686520636f6e74726f6c6c65728c746f207468652073746173682c206966206974206973206e6f7420616c72656164792e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479104f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e4c7365745f76616c696461746f725f636f756e7404010c6e65776102010c75333200091890536574732074686520696465616c206e756d626572206f662076616c696461746f72732e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c6578697479104f28312960696e6372656173655f76616c696461746f725f636f756e740401286164646974696f6e616c6102010c753332000a1ce8496e6372656d656e74732074686520696465616c206e756d626572206f662076616c696461746f727320757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e547363616c655f76616c696461746f725f636f756e74040118666163746f72f101011c50657263656e74000b1c11015363616c652075702074686520696465616c206e756d626572206f662076616c696461746f7273206279206120666163746f7220757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e34666f7263655f6e6f5f65726173000c34ac466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e3901546875732074686520656c656374696f6e2070726f63657373206d6179206265206f6e676f696e67207768656e20746869732069732063616c6c65642e20496e2074686973206361736520746865dc656c656374696f6e2077696c6c20636f6e74696e756520756e74696c20746865206e65787420657261206973207472696767657265642e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f28312934666f7263655f6e65775f657261000d384901466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c2062659c726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f283129447365745f696e76756c6e657261626c6573040134696e76756c6e657261626c6573390201445665633c543a3a4163636f756e7449643e000e0cc8536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e34666f7263655f756e7374616b650801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c753332000f200901466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e50666f7263655f6e65775f6572615f616c776179730010240101466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e5463616e63656c5f64656665727265645f736c61736808010c657261100120457261496e646578000134736c6173685f696e6469636573410401205665633c7533323e0011149443616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e009843616e2062652063616c6c6564206279207468652060543a3a41646d696e4f726967696e602e000101506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e387061796f75745f7374616b65727308013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780012341901506179206f7574206e6578742070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e206572612e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e00490154686520726577617264207061796f757420636f756c6420626520706167656420696e20636173652074686572652061726520746f6f206d616e79206e6f6d696e61746f7273206261636b696e67207468655d016076616c696461746f725f7374617368602e20546869732063616c6c2077696c6c207061796f757420756e7061696420706167657320696e20616e20617363656e64696e67206f726465722e20546f20636c61696d2061b4737065636966696320706167652c2075736520607061796f75745f7374616b6572735f62795f70616765602e6000f0496620616c6c2070616765732061726520636c61696d65642c2069742072657475726e7320616e206572726f722060496e76616c696450616765602e187265626f6e6404011476616c75656d01013042616c616e63654f663c543e00131cdc5265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e00d4546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479d02d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73882d20426f756e64656420627920604d6178556e6c6f636b696e674368756e6b73602e28726561705f73746173680801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c7533320014485d0152656d6f766520616c6c2064617461207374727563747572657320636f6e6365726e696e672061207374616b65722f7374617368206f6e636520697420697320617420612073746174652077686572652069742063616e0501626520636f6e736964657265642060647573746020696e20746865207374616b696e672073797374656d2e2054686520726571756972656d656e7473206172653a000501312e207468652060746f74616c5f62616c616e636560206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e1101322e206f722c2074686520606c65646765722e746f74616c60206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e6101332e206f722c206578697374656e7469616c206465706f736974206973207a65726f20616e64206569746865722060746f74616c5f62616c616e636560206f7220606c65646765722e746f74616c60206973207a65726f2e00550154686520666f726d65722063616e2068617070656e20696e206361736573206c696b65206120736c6173683b20746865206c6174746572207768656e20612066756c6c7920756e626f6e646564206163636f756e7409016973207374696c6c20726563656976696e67207374616b696e67207265776172647320696e206052657761726444657374696e6174696f6e3a3a5374616b6564602e00310149742063616e2062652063616c6c656420627920616e796f6e652c206173206c6f6e672061732060737461736860206d65657473207468652061626f766520726571756972656d656e74732e00dc526566756e647320746865207472616e73616374696f6e20666565732075706f6e207375636365737366756c20657865637574696f6e2e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e106b69636b04010c77686f3d0401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e00152ce052656d6f76652074686520676976656e206e6f6d696e6174696f6e732066726f6d207468652063616c6c696e672076616c696461746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e004d012d206077686f603a2041206c697374206f66206e6f6d696e61746f72207374617368206163636f756e74732077686f20617265206e6f6d696e6174696e6720746869732076616c696461746f72207768696368c0202073686f756c64206e6f206c6f6e676572206265206e6f6d696e6174696e6720746869732076616c696461746f722e0055014e6f74653a204d616b696e6720746869732063616c6c206f6e6c79206d616b65732073656e736520696620796f7520666972737420736574207468652076616c696461746f7220707265666572656e63657320746f78626c6f636b20616e792066757274686572206e6f6d696e6174696f6e732e4c7365745f7374616b696e675f636f6e666967731c01486d696e5f6e6f6d696e61746f725f626f6e6445040158436f6e6669674f703c42616c616e63654f663c543e3e0001486d696e5f76616c696461746f725f626f6e6445040158436f6e6669674f703c42616c616e63654f663c543e3e00014c6d61785f6e6f6d696e61746f725f636f756e7449040134436f6e6669674f703c7533323e00014c6d61785f76616c696461746f725f636f756e7449040134436f6e6669674f703c7533323e00013c6368696c6c5f7468726573686f6c644d040144436f6e6669674f703c50657263656e743e0001386d696e5f636f6d6d697373696f6e51040144436f6e6669674f703c50657262696c6c3e0001486d61785f7374616b65645f726577617264734d040144436f6e6669674f703c50657263656e743e001644ac5570646174652074686520766172696f7573207374616b696e6720636f6e66696775726174696f6e73202e0025012a20606d696e5f6e6f6d696e61746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f2062652061206e6f6d696e61746f722e25012a20606d696e5f76616c696461746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f20626520612076616c696461746f722e55012a20606d61785f6e6f6d696e61746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e2062652061206e6f6d696e61746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e55012a20606d61785f76616c696461746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e20626520612076616c696461746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e59012a20606368696c6c5f7468726573686f6c64603a2054686520726174696f206f6620606d61785f6e6f6d696e61746f725f636f756e7460206f7220606d61785f76616c696461746f725f636f756e74602077686963681901202073686f756c642062652066696c6c656420696e206f7264657220666f722074686520606368696c6c5f6f7468657260207472616e73616374696f6e20746f20776f726b2e61012a20606d696e5f636f6d6d697373696f6e603a20546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e550120205468697320697320636865636b6564206f6e6c792075706f6e2063616c6c696e67206076616c6964617465602e204578697374696e672076616c696461746f727320617265206e6f742061666665637465642e00c452756e74696d654f726967696e206d75737420626520526f6f7420746f2063616c6c20746869732066756e6374696f6e2e0035014e4f54453a204578697374696e67206e6f6d696e61746f727320616e642076616c696461746f72732077696c6c206e6f742062652061666665637465642062792074686973207570646174652e1101746f206b69636b2070656f706c6520756e64657220746865206e6577206c696d6974732c20606368696c6c5f6f74686572602073686f756c642062652063616c6c65642e2c6368696c6c5f6f746865720401147374617368000130543a3a4163636f756e74496400176841014465636c61726520612060636f6e74726f6c6c65726020746f2073746f702070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e004101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2c206275742063616e2062652063616c6c656420627920616e796f6e652e0059014966207468652063616c6c6572206973207468652073616d652061732074686520636f6e74726f6c6c6572206265696e672074617267657465642c207468656e206e6f206675727468657220636865636b7320617265d8656e666f726365642c20616e6420746869732066756e6374696f6e2062656861766573206a757374206c696b6520606368696c6c602e005d014966207468652063616c6c657220697320646966666572656e74207468616e2074686520636f6e74726f6c6c6572206265696e672074617267657465642c2074686520666f6c6c6f77696e6720636f6e646974696f6e73306d757374206265206d65743a001d012a2060636f6e74726f6c6c657260206d7573742062656c6f6e6720746f2061206e6f6d696e61746f722077686f20686173206265636f6d65206e6f6e2d6465636f6461626c652c000c4f723a003d012a204120604368696c6c5468726573686f6c6460206d7573742062652073657420616e6420636865636b656420776869636820646566696e657320686f7720636c6f736520746f20746865206d6178550120206e6f6d696e61746f7273206f722076616c696461746f7273207765206d757374207265616368206265666f72652075736572732063616e207374617274206368696c6c696e67206f6e652d616e6f746865722e59012a204120604d61784e6f6d696e61746f72436f756e746020616e6420604d617856616c696461746f72436f756e7460206d75737420626520736574207768696368206973207573656420746f2064657465726d696e65902020686f7720636c6f73652077652061726520746f20746865207468726573686f6c642e5d012a204120604d696e4e6f6d696e61746f72426f6e646020616e6420604d696e56616c696461746f72426f6e6460206d7573742062652073657420616e6420636865636b65642c2077686963682064657465726d696e65735101202069662074686973206973206120706572736f6e20746861742073686f756c64206265206368696c6c6564206265636175736520746865792068617665206e6f74206d657420746865207468726573686f6c64402020626f6e642072657175697265642e005501546869732063616e2062652068656c7066756c20696620626f6e6420726571756972656d656e74732061726520757064617465642c20616e64207765206e65656420746f2072656d6f7665206f6c642075736572739877686f20646f206e6f74207361746973667920746865736520726571756972656d656e74732e68666f7263655f6170706c795f6d696e5f636f6d6d697373696f6e04013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400180c4501466f72636520612076616c696461746f7220746f2068617665206174206c6561737420746865206d696e696d756d20636f6d6d697373696f6e2e20546869732077696c6c206e6f74206166666563742061610176616c696461746f722077686f20616c726561647920686173206120636f6d6d697373696f6e2067726561746572207468616e206f7220657175616c20746f20746865206d696e696d756d2e20416e79206163636f756e743863616e2063616c6c20746869732e487365745f6d696e5f636f6d6d697373696f6e04010c6e6577f4011c50657262696c6c00191025015365747320746865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e005901546869732063616c6c20686173206c6f7765722070726976696c65676520726571756972656d656e7473207468616e20607365745f7374616b696e675f636f6e6669676020616e642063616e2062652063616c6c6564cc6279207468652060543a3a41646d696e4f726967696e602e20526f6f742063616e20616c776179732063616c6c20746869732e587061796f75745f7374616b6572735f62795f706167650c013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780001107061676510011050616765001a443101506179206f757420612070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e2065726120616e6420706167652e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e31012d2060706167656020697320746865207061676520696e646578206f66206e6f6d696e61746f727320746f20706179206f757420776974682076616c7565206265747765656e203020616e64b02020606e756d5f6e6f6d696e61746f7273202f20543a3a4d61784578706f737572655061676553697a65602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e003d01496620612076616c696461746f7220686173206d6f7265207468616e205b60436f6e6669673a3a4d61784578706f737572655061676553697a65605d206e6f6d696e61746f7273206261636b696e6729017468656d2c207468656e20746865206c697374206f66206e6f6d696e61746f72732069732070616765642c207769746820656163682070616765206265696e672063617070656420617455015b60436f6e6669673a3a4d61784578706f737572655061676553697a65602e5d20496620612076616c696461746f7220686173206d6f7265207468616e206f6e652070616765206f66206e6f6d696e61746f72732c49017468652063616c6c206e6565647320746f206265206d61646520666f72206561636820706167652073657061726174656c7920696e206f7264657220666f7220616c6c20746865206e6f6d696e61746f727355016261636b696e6720612076616c696461746f7220746f207265636569766520746865207265776172642e20546865206e6f6d696e61746f727320617265206e6f7420736f72746564206163726f73732070616765736101616e6420736f2069742073686f756c64206e6f7420626520617373756d6564207468652068696768657374207374616b657220776f756c64206265206f6e2074686520746f706d6f7374207061676520616e642076696365490176657273612e204966207265776172647320617265206e6f7420636c61696d656420696e205b60436f6e6669673a3a486973746f72794465707468605d20657261732c207468657920617265206c6f73742e307570646174655f7061796565040128636f6e74726f6c6c6572000130543a3a4163636f756e744964001b18e04d6967726174657320616e206163636f756e742773206052657761726444657374696e6174696f6e3a3a436f6e74726f6c6c65726020746fa46052657761726444657374696e6174696f6e3a3a4163636f756e7428636f6e74726f6c6c657229602e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e003101546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966207468652060706179656560206973207375636365737366756c6c79206d696772617465642e686465707265636174655f636f6e74726f6c6c65725f626174636804012c636f6e74726f6c6c657273550401f4426f756e6465645665633c543a3a4163636f756e7449642c20543a3a4d6178436f6e74726f6c6c657273496e4465707265636174696f6e42617463683e001c1c5d01557064617465732061206261746368206f6620636f6e74726f6c6c6572206163636f756e747320746f20746865697220636f72726573706f6e64696e67207374617368206163636f756e7420696620746865792061726561016e6f74207468652073616d652e2049676e6f72657320616e7920636f6e74726f6c6c6572206163636f756e7473207468617420646f206e6f742065786973742c20616e6420646f6573206e6f74206f706572617465206966b874686520737461736820616e6420636f6e74726f6c6c65722061726520616c7265616479207468652073616d652e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e00b4546865206469737061746368206f726967696e206d7573742062652060543a3a41646d696e4f726967696e602e38726573746f72655f6c65646765721001147374617368000130543a3a4163636f756e7449640001406d617962655f636f6e74726f6c6c65728801504f7074696f6e3c543a3a4163636f756e7449643e00012c6d617962655f746f74616c590401504f7074696f6e3c42616c616e63654f663c543e3e00013c6d617962655f756e6c6f636b696e675d040115014f7074696f6e3c426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a0a4d6178556e6c6f636b696e674368756e6b733e3e001d2c0501526573746f72657320746865207374617465206f662061206c656467657220776869636820697320696e20616e20696e636f6e73697374656e742073746174652e00dc54686520726571756972656d656e747320746f20726573746f72652061206c6564676572206172652074686520666f6c6c6f77696e673a642a2054686520737461736820697320626f6e6465643b206f720d012a20546865207374617368206973206e6f7420626f6e64656420627574206974206861732061207374616b696e67206c6f636b206c65667420626568696e643b206f7225012a204966207468652073746173682068617320616e206173736f636961746564206c656467657220616e642069747320737461746520697320696e636f6e73697374656e743b206f721d012a20496620746865206c6564676572206973206e6f7420636f72727570746564202a6275742a20697473207374616b696e67206c6f636b206973206f7574206f662073796e632e00610154686520606d617962655f2a6020696e70757420706172616d65746572732077696c6c206f76657277726974652074686520636f72726573706f6e64696e67206461746120616e64206d65746164617461206f662074686559016c6564676572206173736f6369617465642077697468207468652073746173682e2049662074686520696e70757420706172616d657465727320617265206e6f74207365742c20746865206c65646765722077696c6c9062652072657365742076616c7565732066726f6d206f6e2d636861696e2073746174652e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e3d04000002bd0200410400000210004504103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200004904103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200004d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f101010c104e6f6f700000000c5365740400f1010104540001001852656d6f7665000200005104103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000055040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400390201185665633c543e0000590404184f7074696f6e04045401180108104e6f6e6500000010536f6d6504001800000100005d0404184f7074696f6e0404540161040108104e6f6e6500000010536f6d6504006104000001000061040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016504045300000400690401185665633c543e00006504083870616c6c65745f7374616b696e672c556e6c6f636b4368756e6b041c42616c616e636501180008011476616c75656d01011c42616c616e636500010c65726161020120457261496e646578000069040000026504006d040c3870616c6c65745f73657373696f6e1870616c6c65741043616c6c040454000108207365745f6b6579730801106b6579737104011c543a3a4b65797300011470726f6f6638011c5665633c75383e000024e453657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e1d01416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722ec05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e00d0546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e0034232320436f6d706c657869747959012d20604f283129602e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f69647328296020776869636820697320202066697865642e2870757267655f6b657973000130c852656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e00c05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e005501546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265205369676e656420616e6420746865206163636f756e74206d757374206265206569746865722062655d01636f6e7665727469626c6520746f20612076616c696461746f72204944207573696e672074686520636861696e2773207479706963616c2061646472657373696e672073797374656d20287468697320757375616c6c7951016d65616e73206265696e67206120636f6e74726f6c6c6572206163636f756e7429206f72206469726563746c7920636f6e7665727469626c6520696e746f20612076616c696461746f722049442028776869636894757375616c6c79206d65616e73206265696e672061207374617368206163636f756e74292e0034232320436f6d706c65786974793d012d20604f2831296020696e206e756d626572206f66206b65792074797065732e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f6698202060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e71040c5874616e676c655f746573746e65745f72756e74696d65186f70617175652c53657373696f6e4b65797300000c011062616265d50201c43c42616265206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c696300011c6772616e647061a801d03c4772616e647061206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000124696d5f6f6e6c696e655d0101d43c496d4f6e6c696e65206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000075040c3c70616c6c65745f74726561737572791870616c6c65741043616c6c0804540004490001182c7370656e645f6c6f63616c080118616d6f756e746d01013c42616c616e63654f663c542c20493e00012c62656e6566696369617279bd0201504163636f756e7449644c6f6f6b75704f663c543e000344b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e0045014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c656173742060616d6f756e74602e002c2323232044657461696c7345014e4f54453a20466f72207265636f72642d6b656570696e6720707572706f7365732c207468652070726f706f736572206973206465656d656420746f206265206571756976616c656e7420746f207468653062656e65666963696172792e003823232320506172616d657465727341012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602ee82d206062656e6566696369617279603a205468652064657374696e6174696f6e206163636f756e7420666f7220746865207472616e736665722e00242323204576656e747300b4456d697473205b604576656e743a3a5370656e64417070726f766564605d206966207375636365737366756c2e3c72656d6f76655f617070726f76616c04012c70726f706f73616c5f69646102013450726f706f73616c496e6465780004542d01466f72636520612070726576696f75736c7920617070726f7665642070726f706f73616c20746f2062652072656d6f7665642066726f6d2074686520617070726f76616c2071756575652e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c7300c0546865206f726967696e616c206465706f7369742077696c6c206e6f206c6f6e6765722062652072657475726e65642e003823232320506172616d6574657273a02d206070726f706f73616c5f6964603a2054686520696e646578206f6620612070726f706f73616c003823232320436f6d706c6578697479ac2d204f2841292077686572652060416020697320746865206e756d626572206f6620617070726f76616c730028232323204572726f727345012d205b604572726f723a3a50726f706f73616c4e6f74417070726f766564605d3a20546865206070726f706f73616c5f69646020737570706c69656420776173206e6f7420666f756e6420696e2074686551012020617070726f76616c2071756575652c20692e652e2c207468652070726f706f73616c20686173206e6f74206265656e20617070726f7665642e205468697320636f756c6420616c736f206d65616e207468655901202070726f706f73616c20646f6573206e6f7420657869737420616c746f6765746865722c2074687573207468657265206973206e6f2077617920697420776f756c642068617665206265656e20617070726f766564542020696e2074686520666972737420706c6163652e147370656e6410012861737365745f6b696e64840144426f783c543a3a41737365744b696e643e000118616d6f756e746d010150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000178426f783c42656e65666963696172794c6f6f6b75704f663c542c20493e3e00012876616c69645f66726f6d790401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000568b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e001d014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c65617374550160616d6f756e7460206f66206061737365745f6b696e646020696e20746865206e61746976652061737365742e2054686520616d6f756e74206f66206061737365745f6b696e646020697320636f6e766572746564d4666f7220617373657274696f6e207573696e6720746865205b60436f6e6669673a3a42616c616e6365436f6e766572746572605d2e002823232044657461696c7300490143726561746520616e20617070726f766564207370656e6420666f72207472616e7366657272696e6720612073706563696669632060616d6f756e7460206f66206061737365745f6b696e646020746f2061610164657369676e617465642062656e65666963696172792e20546865207370656e64206d75737420626520636c61696d6564207573696e672074686520607061796f75746020646973706174636861626c652077697468696e74746865205b60436f6e6669673a3a5061796f7574506572696f64605d2e003823232320506172616d657465727315012d206061737365745f6b696e64603a20416e20696e64696361746f72206f662074686520737065636966696320617373657420636c61737320746f206265207370656e742e41012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602eb82d206062656e6566696369617279603a205468652062656e6566696369617279206f6620746865207370656e642e55012d206076616c69645f66726f6d603a2054686520626c6f636b206e756d6265722066726f6d20776869636820746865207370656e642063616e20626520636c61696d65642e2049742063616e20726566657220746f1901202074686520706173742069662074686520726573756c74696e67207370656e6420686173206e6f74207965742065787069726564206163636f7264696e6720746f20746865450120205b60436f6e6669673a3a5061796f7574506572696f64605d2e20496620604e6f6e65602c20746865207370656e642063616e20626520636c61696d656420696d6d6564696174656c792061667465722c2020617070726f76616c2e00242323204576656e747300c8456d697473205b604576656e743a3a41737365745370656e64417070726f766564605d206966207375636365737366756c2e187061796f7574040114696e6465781001285370656e64496e64657800064c38436c61696d2061207370656e642e00482323204469737061746368204f726967696e00384d757374206265207369676e6564002823232044657461696c730055015370656e6473206d75737420626520636c61696d65642077697468696e20736f6d652074656d706f72616c20626f756e64732e2041207370656e64206d617920626520636c61696d65642077697468696e206f6e65d45b60436f6e6669673a3a5061796f7574506572696f64605d2066726f6d20746865206076616c69645f66726f6d6020626c6f636b2e5501496e2063617365206f662061207061796f7574206661696c7572652c20746865207370656e6420737461747573206d75737420626520757064617465642077697468207468652060636865636b5f73746174757360dc646973706174636861626c65206265666f7265207265747279696e672077697468207468652063757272656e742066756e6374696f6e2e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e74730090456d697473205b604576656e743a3a50616964605d206966207375636365737366756c2e30636865636b5f737461747573040114696e6465781001285370656e64496e64657800074c2901436865636b2074686520737461747573206f6620746865207370656e6420616e642072656d6f76652069742066726f6d207468652073746f726167652069662070726f6365737365642e00482323204469737061746368204f726967696e003c4d757374206265207369676e65642e002823232044657461696c730001015468652073746174757320636865636b20697320612070726572657175697369746520666f72207265747279696e672061206661696c6564207061796f75742e490149662061207370656e64206861732065697468657220737563636565646564206f7220657870697265642c2069742069732072656d6f7665642066726f6d207468652073746f726167652062792074686973ec66756e6374696f6e2e20496e207375636820696e7374616e6365732c207472616e73616374696f6e20666565732061726520726566756e6465642e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300f8456d697473205b604576656e743a3a5061796d656e744661696c6564605d20696620746865207370656e64207061796f757420686173206661696c65642e0101456d697473205b604576656e743a3a5370656e6450726f636573736564605d20696620746865207370656e64207061796f75742068617320737563636565642e28766f69645f7370656e64040114696e6465781001285370656e64496e6465780008407c566f69642070726576696f75736c7920617070726f766564207370656e642e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c73001d0141207370656e6420766f6964206973206f6e6c7920706f737369626c6520696620746865207061796f757420686173206e6f74206265656e20617474656d70746564207965742e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300c0456d697473205b604576656e743a3a41737365745370656e64566f69646564605d206966207375636365737366756c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e790404184f7074696f6e04045401300108104e6f6e6500000010536f6d6504003000000100007d040c3c70616c6c65745f626f756e746965731870616c6c65741043616c6c0804540004490001243870726f706f73655f626f756e747908011476616c75656d01013c42616c616e63654f663c542c20493e00012c6465736372697074696f6e38011c5665633c75383e0000305450726f706f73652061206e657720626f756e74792e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051015061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c206173510160446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e2049742077696c6c20626520756e72657365727665642075706f6e20617070726f76616c2c646f7220736c6173686564207768656e2072656a65637465642e00f82d206063757261746f72603a205468652063757261746f72206163636f756e742077686f6d2077696c6c206d616e616765207468697320626f756e74792e642d2060666565603a205468652063757261746f72206665652e25012d206076616c7565603a2054686520746f74616c207061796d656e7420616d6f756e74206f66207468697320626f756e74792c2063757261746f722066656520696e636c756465642ec02d20606465736372697074696f6e603a20546865206465736372697074696f6e206f66207468697320626f756e74792e38617070726f76655f626f756e7479040124626f756e74795f69646102012c426f756e7479496e64657800011c5d01417070726f7665206120626f756e74792070726f706f73616c2e2041742061206c617465722074696d652c2074686520626f756e74792077696c6c2062652066756e64656420616e64206265636f6d6520616374697665a8616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e3c70726f706f73655f63757261746f720c0124626f756e74795f69646102012c426f756e7479496e64657800011c63757261746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013c42616c616e63654f663c542c20493e0002189450726f706f736520612063757261746f7220746f20612066756e64656420626f756e74792e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e40756e61737369676e5f63757261746f72040124626f756e74795f69646102012c426f756e7479496e6465780003447c556e61737369676e2063757261746f722066726f6d206120626f756e74792e001d01546869732066756e6374696f6e2063616e206f6e6c792062652063616c6c656420627920746865206052656a6563744f726967696e602061207369676e6564206f726967696e2e003d01496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e602c20776520617373756d652074686174207468652063757261746f7220697331016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c2077652077696c6c20736c617368207468652063757261746f72207768656e20706f737369626c652e006101496620746865206f726967696e206973207468652063757261746f722c2077652074616b6520746869732061732061207369676e20746865792061726520756e61626c6520746f20646f207468656972206a6f6220616e645d01746865792077696c6c696e676c7920676976652075702e20576520636f756c6420736c617368207468656d2c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f207265636f76657220746865697235016465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966206974206973206162757365642e29005d0146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e6520696620616e64206f6e6c79206966207468652063757261746f722069732022696e616374697665222e205468697320616c6c6f77736101616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f7574207468617420612063757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e64390177652073686f756c64207069636b2061206e65772063757261746f722e20496e20746869732063617365207468652063757261746f722073686f756c6420616c736f20626520736c61736865642e0034232320436f6d706c65786974791c2d204f2831292e386163636570745f63757261746f72040124626f756e74795f69646102012c426f756e7479496e64657800041c94416363657074207468652063757261746f7220726f6c6520666f72206120626f756e74792e290141206465706f7369742077696c6c2062652072657365727665642066726f6d2063757261746f7220616e6420726566756e642075706f6e207375636365737366756c207061796f75742e00904d6179206f6e6c792062652063616c6c65642066726f6d207468652063757261746f722e0034232320436f6d706c65786974791c2d204f2831292e3061776172645f626f756e7479080124626f756e74795f69646102012c426f756e7479496e64657800012c62656e6566696369617279bd0201504163636f756e7449644c6f6f6b75704f663c543e0005285901417761726420626f756e747920746f20612062656e6566696369617279206163636f756e742e205468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647338616674657220612064656c61792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f2061776172642e19012d206062656e6566696369617279603a205468652062656e6566696369617279206163636f756e742077686f6d2077696c6c207265636569766520746865207061796f75742e0034232320436f6d706c65786974791c2d204f2831292e30636c61696d5f626f756e7479040124626f756e74795f69646102012c426f756e7479496e646578000620ec436c61696d20746865207061796f75742066726f6d20616e206177617264656420626f756e7479206166746572207061796f75742064656c61792e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652062656e6566696369617279206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f20636c61696d2e0034232320436f6d706c65786974791c2d204f2831292e30636c6f73655f626f756e7479040124626f756e74795f69646102012c426f756e7479496e646578000724390143616e63656c20612070726f706f736564206f722061637469766520626f756e74792e20416c6c207468652066756e64732077696c6c2062652073656e7420746f20747265617375727920616e64cc7468652063757261746f72206465706f7369742077696c6c20626520756e726573657276656420696620706f737369626c652e00c84f6e6c792060543a3a52656a6563744f726967696e602069732061626c6520746f2063616e63656c206120626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f2063616e63656c2e0034232320436f6d706c65786974791c2d204f2831292e50657874656e645f626f756e74795f657870697279080124626f756e74795f69646102012c426f756e7479496e64657800011872656d61726b38011c5665633c75383e000824ac457874656e6420746865206578706972792074696d65206f6620616e2061637469766520626f756e74792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f20657874656e642e8c2d206072656d61726b603a206164646974696f6e616c20696e666f726d6174696f6e2e0034232320436f6d706c65786974791c2d204f2831292e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e81040c5470616c6c65745f6368696c645f626f756e746965731870616c6c65741043616c6c04045400011c406164645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800011476616c75656d01013042616c616e63654f663c543e00012c6465736372697074696f6e38011c5665633c75383e00004c5c4164642061206e6577206368696c642d626f756e74792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f6620706172656e74dc626f756e747920616e642074686520706172656e7420626f756e7479206d75737420626520696e2022616374697665222073746174652e0005014368696c642d626f756e74792067657473206164646564207375636365737366756c6c7920262066756e642067657473207472616e736665727265642066726f6d0901706172656e7420626f756e747920746f206368696c642d626f756e7479206163636f756e742c20696620706172656e7420626f756e74792068617320656e6f7567686c66756e64732c20656c7365207468652063616c6c206661696c732e000d01557070657220626f756e6420746f206d6178696d756d206e756d626572206f662061637469766520206368696c6420626f756e7469657320746861742063616e206265a8616464656420617265206d616e61676564207669612072756e74696d6520747261697420636f6e666967985b60436f6e6669673a3a4d61784163746976654368696c64426f756e7479436f756e74605d2e0001014966207468652063616c6c20697320737563636573732c2074686520737461747573206f66206368696c642d626f756e7479206973207570646174656420746f20224164646564222e004d012d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e747920666f72207768696368206368696c642d626f756e7479206973206265696e672061646465642eb02d206076616c7565603a2056616c756520666f7220657865637574696e67207468652070726f706f73616c2edc2d20606465736372697074696f6e603a2054657874206465736372697074696f6e20666f7220746865206368696c642d626f756e74792e3c70726f706f73655f63757261746f72100140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e64657800011c63757261746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013042616c616e63654f663c543e00013ca050726f706f73652063757261746f7220666f722066756e646564206368696c642d626f756e74792e000d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652063757261746f72206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e20224164646564222073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6405017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202243757261746f7250726f706f73656422206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792eb42d206063757261746f72603a2041646472657373206f66206368696c642d626f756e74792063757261746f722eec2d2060666565603a207061796d656e742066656520746f206368696c642d626f756e74792063757261746f7220666f7220657865637574696f6e2e386163636570745f63757261746f72080140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e64657800024cb4416363657074207468652063757261746f7220726f6c6520666f7220746865206368696c642d626f756e74792e00f4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f662074686973346368696c642d626f756e74792e00ec41206465706f7369742077696c6c2062652072657365727665642066726f6d207468652063757261746f7220616e6420726566756e642075706f6e887375636365737366756c207061796f7574206f722063616e63656c6c6174696f6e2e00f846656520666f722063757261746f722069732064656475637465642066726f6d2063757261746f7220666565206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e202243757261746f7250726f706f736564222073746174652c20666f722070726f63657373696e6720746865090163616c6c2e20416e64207374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202241637469766522206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e40756e61737369676e5f63757261746f72080140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e64657800038894556e61737369676e2063757261746f722066726f6d2061206368696c642d626f756e74792e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c2063616e20626520656974686572206052656a6563744f726967696e602c206f72dc7468652063757261746f72206f662074686520706172656e7420626f756e74792c206f7220616e79207369676e6564206f726967696e2e00f8466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e20616e6420746865206368696c642d626f756e7479010163757261746f722c20706172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f7220746869732063616c6c20746f0901776f726b2e20576520616c6c6f77206368696c642d626f756e74792063757261746f7220616e6420543a3a52656a6563744f726967696e20746f2065786563757465c8746869732063616c6c20697272657370656374697665206f662074686520706172656e7420626f756e74792073746174652e00dc496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e60206f72207468650501706172656e7420626f756e74792063757261746f722c20776520617373756d65207468617420746865206368696c642d626f756e74792063757261746f722069730d016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e000501496620746865206f726967696e20697320746865206368696c642d626f756e74792063757261746f722c2077652074616b6520746869732061732061207369676e09017468617420746865792061726520756e61626c6520746f20646f207468656972206a6f622c20616e64206172652077696c6c696e676c7920676976696e672075702e0901576520636f756c6420736c61736820746865206465706f7369742c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f20756e7265736572766511017468656972206465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966386974206973206162757365642e2900050146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e652069666620746865206368696c642d626f756e74792063757261746f72206973090122696e616374697665222e204578706972792075706461746520647565206f6620706172656e7420626f756e7479206973207573656420746f20657374696d6174659c696e616374697665207374617465206f66206368696c642d626f756e74792063757261746f722e000d015468697320616c6c6f777320616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f757420746861742061206368696c642d626f756e7479090163757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e642077652073686f756c64207069636b2061206e6577f86f6e652e20496e2074686973206361736520746865206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e0001015374617465206f66206368696c642d626f756e7479206973206d6f76656420746f204164646564207374617465206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e4861776172645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e64657800012c62656e6566696369617279bd0201504163636f756e7449644c6f6f6b75704f663c543e000444904177617264206368696c642d626f756e747920746f20612062656e65666963696172792e00f85468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647320616674657220612064656c61792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652074686520706172656e742063757261746f72206f727463757261746f72206f662074686973206368696c642d626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e0009014368696c642d626f756e7479206d75737420626520696e206163746976652073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6411017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202250656e64696e675061796f757422206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e942d206062656e6566696369617279603a2042656e6566696369617279206163636f756e742e48636c61696d5f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e6465780005400501436c61696d20746865207061796f75742066726f6d20616e2061776172646564206368696c642d626f756e7479206166746572207061796f75742064656c61792e00ec546865206469737061746368206f726967696e20666f7220746869732063616c6c206d617920626520616e79207369676e6564206f726967696e2e00050143616c6c20776f726b7320696e646570656e64656e74206f6620706172656e7420626f756e74792073746174652c204e6f206e65656420666f7220706172656e7474626f756e747920746f20626520696e206163746976652073746174652e0011015468652042656e65666963696172792069732070616964206f757420776974682061677265656420626f756e74792076616c75652e2043757261746f7220666565206973947061696420262063757261746f72206465706f73697420697320756e72657365727665642e0005014368696c642d626f756e7479206d75737420626520696e202250656e64696e675061796f7574222073746174652c20666f722070726f63657373696e6720746865fc63616c6c2e20416e6420696e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e6c7375636365737366756c2063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e48636c6f73655f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646102012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646102012c426f756e7479496e646578000658110143616e63656c20612070726f706f736564206f7220616374697665206368696c642d626f756e74792e204368696c642d626f756e7479206163636f756e742066756e64730901617265207472616e7366657272656420746f20706172656e7420626f756e7479206163636f756e742e20546865206368696c642d626f756e74792063757261746f72986465706f736974206d617920626520756e726573657276656420696620706f737369626c652e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652065697468657220706172656e742063757261746f72206f724860543a3a52656a6563744f726967696e602e00f0496620746865207374617465206f66206368696c642d626f756e74792069732060416374697665602c2063757261746f72206465706f7369742069732c756e72657365727665642e00f4496620746865207374617465206f66206368696c642d626f756e7479206973206050656e64696e675061796f7574602c2063616c6c206661696c7320267872657475726e73206050656e64696e675061796f757460206572726f722e000d01466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e2c20706172656e7420626f756e7479206d75737420626520696ef06163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f20776f726b2e20466f72206f726967696e90543a3a52656a6563744f726967696e20657865637574696f6e20697320666f726365642e000101496e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e85040c4070616c6c65745f626167735f6c6973741870616c6c65741043616c6c08045400044900010c1472656261670401286469736c6f6361746564bd0201504163636f756e7449644c6f6f6b75704f663c543e00002859014465636c617265207468617420736f6d6520606469736c6f636174656460206163636f756e74206861732c207468726f7567682072657761726473206f722070656e616c746965732c2073756666696369656e746c7951016368616e676564206974732073636f726520746861742069742073686f756c642070726f7065726c792066616c6c20696e746f206120646966666572656e7420626167207468616e206974732063757272656e74106f6e652e001d01416e796f6e652063616e2063616c6c20746869732066756e6374696f6e2061626f757420616e7920706f74656e7469616c6c79206469736c6f6361746564206163636f756e742e00490157696c6c20616c7761797320757064617465207468652073746f7265642073636f7265206f6620606469736c6f63617465646020746f2074686520636f72726563742073636f72652c206261736564206f6e406053636f726550726f7669646572602e00d4496620606469736c6f63617465646020646f6573206e6f74206578697374732c2069742072657475726e7320616e206572726f722e3c7075745f696e5f66726f6e745f6f6604011c6c696768746572bd0201504163636f756e7449644c6f6f6b75704f663c543e000128d04d6f7665207468652063616c6c65722773204964206469726563746c7920696e2066726f6e74206f6620606c696768746572602e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642063616e206f6e6c792062652063616c6c656420627920746865204964206f663501746865206163636f756e7420676f696e6720696e2066726f6e74206f6620606c696768746572602e2046656520697320706179656420627920746865206f726967696e20756e64657220616c6c3863697263756d7374616e6365732e00384f6e6c7920776f726b732069663a00942d20626f7468206e6f646573206172652077697468696e207468652073616d65206261672cd02d20616e6420606f726967696e602068617320612067726561746572206053636f726560207468616e20606c696768746572602e547075745f696e5f66726f6e745f6f665f6f7468657208011c68656176696572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c6c696768746572bd0201504163636f756e7449644c6f6f6b75704f663c543e00020c110153616d65206173205b6050616c6c65743a3a7075745f696e5f66726f6e745f6f66605d2c206275742069742063616e2062652063616c6c656420627920616e796f6e652e00c8466565206973207061696420627920746865206f726967696e20756e64657220616c6c2063697263756d7374616e6365732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89040c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c65741043616c6c040454000168106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002845015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f746500cc2a20416e206163636f756e742063616e206f6e6c792062652061206d656d626572206f6620612073696e676c6520706f6f6c2ed82a20416e206163636f756e742063616e6e6f74206a6f696e207468652073616d6520706f6f6c206d756c7469706c652074696d65732e41012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726104011465787472618d04015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e30636c61696d5f7061796f757400022055014120626f6e646564206d656d6265722063616e20757365207468697320746f20636c61696d207468656972207061796f7574206261736564206f6e20746865207265776172647320746861742074686520706f6f6c610168617320616363756d756c617465642073696e6365207468656972206c61737420636c61696d6564207061796f757420284f522073696e6365206a6f696e696e6720696620746869732069732074686569722066697273743d0174696d6520636c61696d696e672072657761726473292e20546865207061796f75742077696c6c206265207472616e7366657272656420746f20746865206d656d6265722773206163636f756e742e004901546865206d656d6265722077696c6c206561726e20726577617264732070726f2072617461206261736564206f6e20746865206d656d62657273207374616b65207673207468652073756d206f6620746865d06d656d6265727320696e2074686520706f6f6c73207374616b652e205265776172647320646f206e6f742022657870697265222e0041015365652060636c61696d5f7061796f75745f6f746865726020746f20636c61696d2072657761726473206f6e20626568616c66206f6620736f6d6520606f746865726020706f6f6c206d656d6265722e18756e626f6e640801386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640801386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e0001486e756d5f736c617368696e675f7370616e7310010c7533320005585501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500f42d204966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e61012d2049662074686520706f6f6c2068617320616e792070656e64696e6720736c6173682c20776520616c736f2074727920746f20736c61736820746865206d656d626572206265666f7265206c657474696e67207468656d5d0177697468647261772e20546869732063616c63756c6174696f6e206164647320736f6d6520776569676874206f7665726865616420616e64206973206f6e6c7920646566656e736976652e20496e207265616c6974792c5501706f6f6c20736c6173686573206d7573742068617665206265656e20616c7265616479206170706c69656420766961207065726d697373696f6e6c657373205b6043616c6c3a3a6170706c795f736c617368605d2e18637265617465100118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74bd0201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572bd0201504163636f756e7449644c6f6f6b75704f663c543e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f6964140118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74bd0201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f7273390201445665633c543a3a4163636f756e7449643e0008307c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e001823204e6f7465005d01496e206164646974696f6e20746f20612060726f6f7460206f7220606e6f6d696e61746f726020726f6c65206f6620606f726967696e602c20706f6f6c2773206465706f7369746f72206e6565647320746f2068617665f86174206c6561737420606465706f7369746f725f6d696e5f626f6e646020696e2074686520706f6f6c20746f207374617274206e6f6d696e6174696e672e247365745f737461746508011c706f6f6c5f6964100118506f6f6c496400011473746174651d010124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731801346d696e5f6a6f696e5f626f6e6491040158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6491040158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7395040134436f6e6669674f703c7533323e00012c6d61785f6d656d6265727395040134436f6e6669674f703c7533323e0001506d61785f6d656d626572735f7065725f706f6f6c95040134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e99040144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d757374206265605b60436f6e6669673a3a41646d696e4f726967696e605d2e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f749d040158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f729d040158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e6365729d040158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d40704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004101546865206469737061746368206f726967696e206f6620746869732063616c6c2063616e206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463683a59012a205768656e20706f6f6c206465706f7369746f7220686173206c657373207468616e20604d696e4e6f6d696e61746f72426f6e6460207374616b65642c206f74686572776973652020706f6f6c206d656d626572735c202061726520756e61626c6520746f20756e626f6e642e009c2320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463683ad82a205468652063616c6c6572206861732061206e6f6d696e61746f72206f7220726f6f7420726f6c65206f662074686520706f6f6c2e490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720801186d656d626572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011465787472618d04015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373436f6d706f756e6460206f7220605065726d697373696f6e6c657373416c6c602e507365745f636c61696d5f7065726d697373696f6e0401287065726d697373696f6ea104013c436c61696d5065726d697373696f6e000f1c4901416c6c6f7773206120706f6f6c206d656d62657220746f20736574206120636c61696d207065726d697373696f6e20746f20616c6c6f77206f7220646973616c6c6f77207065726d697373696f6e6c65737360626f6e64696e6720616e64207769746864726177696e672e002c2320417267756d656e747300782a20606f726967696e60202d204d656d626572206f66206120706f6f6c2eb82a20607065726d697373696f6e60202d20546865207065726d697373696f6e20746f206265206170706c6965642e48636c61696d5f7061796f75745f6f746865720401146f74686572000130543a3a4163636f756e7449640010100101606f726967696e602063616e20636c61696d207061796f757473206f6e20736f6d6520706f6f6c206d656d62657220606f7468657260277320626568616c662e005501506f6f6c206d656d62657220606f7468657260206d7573742068617665206120605065726d697373696f6e6c657373576974686472617760206f7220605065726d697373696f6e6c657373416c6c6020636c61696da87065726d697373696f6e20666f7220746869732063616c6c20746f206265207375636365737366756c2e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6cc869732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e2c6170706c795f736c6173680401386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e00171c884170706c7920612070656e64696e6720736c617368206f6e2061206d656d6265722e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e005501546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79206163636f756e74292e20496620746865206d656d626572206861731d01736c61736820746f206265206170706c6965642c2063616c6c6572206d61792062652072657761726465642077697468207468652070617274206f662074686520736c6173682e486d6967726174655f64656c65676174696f6e0401386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e0018241d014d696772617465732064656c6567617465642066756e64732066726f6d2074686520706f6f6c206163636f756e7420746f2074686520606d656d6265725f6163636f756e74602e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e002901546869732069732061207065726d697373696f6e2d6c6573732063616c6c20616e6420726566756e647320616e792066656520696620636c61696d206973207375636365737366756c2e005d0149662074686520706f6f6c20686173206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746865207374616b656420746f6b656e73206f6620706f6f6c206d656d62657273290163616e206265206d6f76656420616e642068656c6420696e207468656972206f776e206163636f756e742e20536565205b60616461707465723a3a44656c65676174655374616b65605d786d6967726174655f706f6f6c5f746f5f64656c65676174655f7374616b6504011c706f6f6c5f6964100118506f6f6c4964001924f44d69677261746520706f6f6c2066726f6d205b60616461707465723a3a5374616b655374726174656779547970653a3a5472616e73666572605d20746fa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e004101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792c20616e6420726566756e647320616e7920666565206966207375636365737366756c2e00490149662074686520706f6f6c2068617320616c7265616479206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746869732063616c6c2077696c6c206661696c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d04085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324426f6e644578747261041c42616c616e6365011801082c4672656542616c616e6365040018011c42616c616e63650000001c52657761726473000100009104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200009504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200009904085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f7665000200009d04085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f766500020000a104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000a5040c4070616c6c65745f7363686564756c65721870616c6c65741043616c6c040454000128207363686564756c651001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963a90401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00000470416e6f6e796d6f75736c79207363686564756c652061207461736b2e1863616e63656c0801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001049443616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e387363686564756c655f6e616d656414010869640401205461736b4e616d650001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963a90401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000204585363686564756c652061206e616d6564207461736b2e3063616e63656c5f6e616d656404010869640401205461736b4e616d650003047843616e63656c2061206e616d6564207363686564756c6564207461736b2e387363686564756c655f61667465721001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963a90401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000404a8416e6f6e796d6f75736c79207363686564756c652061207461736b20616674657220612064656c61792e507363686564756c655f6e616d65645f616674657214010869640401205461736b4e616d650001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963a90401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000504905363686564756c652061206e616d6564207461736b20616674657220612064656c61792e247365745f72657472790c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0006305901536574206120726574727920636f6e66696775726174696f6e20666f722061207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069742077696c6c5501626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c2069742473756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3c7365745f72657472795f6e616d65640c010869640401205461736b4e616d6500011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0007305d01536574206120726574727920636f6e66696775726174696f6e20666f722061206e616d6564207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069745d0177696c6c20626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c3069742073756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3063616e63656c5f72657472790401107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e000804a852656d6f7665732074686520726574727920636f6e66696775726174696f6e206f662061207461736b2e4863616e63656c5f72657472795f6e616d656404010869640401205461736b4e616d65000904bc43616e63656c2074686520726574727920636f6e66696775726174696f6e206f662061206e616d6564207461736b2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ea90404184f7074696f6e0404540139010108104e6f6e6500000010536f6d65040039010000010000ad040c3c70616c6c65745f707265696d6167651870616c6c65741043616c6c040454000114346e6f74655f707265696d616765040114627974657338011c5665633c75383e000010745265676973746572206120707265696d616765206f6e2d636861696e2e00550149662074686520707265696d616765207761732070726576696f75736c79207265717565737465642c206e6f2066656573206f72206465706f73697473206172652074616b656e20666f722070726f766964696e67550174686520707265696d6167652e204f74686572776973652c2061206465706f7369742069732074616b656e2070726f706f7274696f6e616c20746f207468652073697a65206f662074686520707265696d6167652e3c756e6e6f74655f707265696d6167650401106861736834011c543a3a48617368000118dc436c65617220616e20756e72657175657374656420707265696d6167652066726f6d207468652072756e74696d652073746f726167652e00fc496620606c656e602069732070726f76696465642c207468656e2069742077696c6c2062652061206d7563682063686561706572206f7065726174696f6e2e0001012d206068617368603a205468652068617368206f662074686520707265696d61676520746f2062652072656d6f7665642066726f6d207468652073746f72652eb82d20606c656e603a20546865206c656e677468206f662074686520707265696d616765206f66206068617368602e40726571756573745f707265696d6167650401106861736834011c543a3a48617368000210410152657175657374206120707265696d6167652062652075706c6f6164656420746f2074686520636861696e20776974686f757420706179696e6720616e792066656573206f72206465706f736974732e00550149662074686520707265696d6167652072657175657374732068617320616c7265616479206265656e2070726f7669646564206f6e2d636861696e2c20776520756e7265736572766520616e79206465706f7369743901612075736572206d6179206861766520706169642c20616e642074616b652074686520636f6e74726f6c206f662074686520707265696d616765206f7574206f662074686569722068616e64732e48756e726571756573745f707265696d6167650401106861736834011c543a3a4861736800030cbc436c65617220612070726576696f75736c79206d616465207265717565737420666f72206120707265696d6167652e002d014e4f54453a2054484953204d555354204e4f542042452043414c4c4544204f4e20606861736860204d4f52452054494d4553205448414e2060726571756573745f707265696d616765602e38656e737572655f75706461746564040118686173686573c10101305665633c543a3a486173683e00040cc4456e7375726520746861742074686520612062756c6b206f66207072652d696d616765732069732075706772616465642e003d015468652063616c6c65722070617973206e6f20666565206966206174206c6561737420393025206f66207072652d696d616765732077657265207375636365737366756c6c7920757064617465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb1040c3c70616c6c65745f74785f70617573651870616c6c65741043616c6c04045400010814706175736504012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e00001034506175736520612063616c6c2e00b843616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a50617573654f726967696e605d2ec0456d69747320616e205b604576656e743a3a43616c6c506175736564605d206576656e74206f6e20737563636573732e1c756e70617573650401146964656e745101015052756e74696d6543616c6c4e616d654f663c543e00011040556e2d706175736520612063616c6c2e00c043616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a556e70617573654f726967696e605d2ec8456d69747320616e205b604576656e743a3a43616c6c556e706175736564605d206576656e74206f6e20737563636573732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb5040c4070616c6c65745f696d5f6f6e6c696e651870616c6c65741043616c6c04045400010424686561727462656174080124686561727462656174b90401704865617274626561743c426c6f636b4e756d626572466f723c543e3e0001247369676e6174757265bd0401bc3c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000c38232320436f6d706c65786974793afc2d20604f284b2960207768657265204b206973206c656e677468206f6620604b6579736020286865617274626561742e76616c696461746f72735f6c656e298820202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b60040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb904084070616c6c65745f696d5f6f6e6c696e6524486561727462656174042c426c6f636b4e756d626572013000100130626c6f636b5f6e756d62657230012c426c6f636b4e756d62657200013473657373696f6e5f696e64657810013053657373696f6e496e64657800013c617574686f726974795f696e64657810012441757468496e64657800013876616c696461746f72735f6c656e10010c7533320000bd04104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139245369676e61747572650000040005030148737232353531393a3a5369676e61747572650000c1040c3c70616c6c65745f6964656e746974791870616c6c65741043616c6c040454000158346164645f72656769737472617204011c6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e00001c7841646420612072656769737472617220746f207468652073797374656d2e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060543a3a5265676973747261724f726967696e602e00a82d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e0094456d6974732060526567697374726172416464656460206966207375636365737366756c2e307365745f6964656e74697479040110696e666fc504016c426f783c543a3a4964656e74697479496e666f726d6174696f6e3e000128290153657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e005501496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7450666f7220746865206e6577206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e008c2d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e0088456d69747320604964656e7469747953657460206966207375636365737366756c2e207365745f73756273040110737562734d0501645665633c28543a3a4163636f756e7449642c2044617461293e0002248c53657420746865207375622d6163636f756e7473206f66207468652073656e6465722e0055015061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e65642d01616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e00b02d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e38636c6561725f6964656e746974790003203901436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e00ec5061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e0098456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e44726571756573745f6a756467656d656e740801247265675f696e64657861020138526567697374726172496e64657800011c6d61785f6665656d01013042616c616e63654f663c543e00044094526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e0055015061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7418676976656e2e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e001d012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e55012d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a00306060606e6f636f6d70696c65b853656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665650c60606000a4456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e3863616e63656c5f726571756573740401247265675f696e646578100138526567697374726172496e6465780005286843616e63656c20612070726576696f757320726571756573742e00f85061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e0045012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e00ac456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e1c7365745f666565080114696e64657861020138526567697374726172496e64657800010c6665656d01013042616c616e63654f663c543e00061c1901536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e542d2060666565603a20746865206e6577206665652e387365745f6163636f756e745f6964080114696e64657861020138526567697374726172496e64657800010c6e6577bd0201504163636f756e7449644c6f6f6b75704f663c543e00071cbc4368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e702d20606e6577603a20746865206e6577206163636f756e742049442e287365745f6669656c6473080114696e64657861020138526567697374726172496e6465780001186669656c6473300129013c543a3a4964656e74697479496e666f726d6174696f6e206173204964656e74697479496e666f726d6174696f6e50726f76696465723e3a3a0a4669656c64734964656e74696669657200081ca853657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e0d012d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e4470726f766964655f6a756467656d656e741001247265675f696e64657861020138526567697374726172496e646578000118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e0001246a756467656d656e745505015c4a756467656d656e743c42616c616e63654f663c543e3e0001206964656e7469747934011c543a3a4861736800093cb850726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74b06f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e0021012d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e55012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e49012d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e5d012d20606964656e74697479603a205468652068617368206f6620746865205b604964656e74697479496e666f726d6174696f6e50726f7669646572605d20666f72207468617420746865206a756467656d656e742069732c202070726f76696465642e00b04e6f74653a204a756467656d656e747320646f206e6f74206170706c7920746f206120757365726e616d652e0094456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e346b696c6c5f6964656e74697479040118746172676574bd0201504163636f756e7449644c6f6f6b75704f663c543e000a30410152656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e0061015061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c6564206279450160536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564806d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e00f8546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206d617463682060543a3a466f7263654f726967696e602e0055012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e0094456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e1c6164645f73756208010c737562bd0201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d104011044617461000b1cac4164642074686520676976656e206163636f756e7420746f207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656e616d655f73756208010c737562bd0201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d104011044617461000c10cc416c74657220746865206173736f636961746564206e616d65206f662074686520676976656e207375622d6163636f756e742e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656d6f76655f73756204010c737562bd0201504163636f756e7449644c6f6f6b75704f663c543e000d1cc052656d6f76652074686520676976656e206163636f756e742066726f6d207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e20717569745f737562000e288c52656d6f7665207468652073656e6465722061732061207375622d6163636f756e742e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c206265207265706174726961746564b4746f207468652073656e64657220282a6e6f742a20746865206f726967696e616c206465706f7369746f72292e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d7573742068617665206120726567697374657265643c73757065722d6964656e746974792e0045014e4f54453a20546869732073686f756c64206e6f74206e6f726d616c6c7920626520757365642c206275742069732070726f766964656420696e207468652063617365207468617420746865206e6f6e2d1101636f6e74726f6c6c6572206f6620616e206163636f756e74206973206d616c6963696f75736c7920726567697374657265642061732061207375622d6163636f756e742e586164645f757365726e616d655f617574686f726974790c0124617574686f72697479bd0201504163636f756e7449644c6f6f6b75704f663c543e00011873756666697838011c5665633c75383e000128616c6c6f636174696f6e10010c753332000f10550141646420616e20604163636f756e744964602077697468207065726d697373696f6e20746f206772616e7420757365726e616d65732077697468206120676976656e20607375666669786020617070656e6465642e00590154686520617574686f726974792063616e206772616e7420757020746f2060616c6c6f636174696f6e6020757365726e616d65732e20546f20746f7020757020746865697220616c6c6f636174696f6e2c2074686579490173686f756c64206a75737420697373756520286f7220726571756573742076696120676f7665726e616e6365292061206e657720606164645f757365726e616d655f617574686f72697479602063616c6c2e6472656d6f76655f757365726e616d655f617574686f72697479040124617574686f72697479bd0201504163636f756e7449644c6f6f6b75704f663c543e001004c452656d6f76652060617574686f72697479602066726f6d2074686520757365726e616d6520617574686f7269746965732e407365745f757365726e616d655f666f720c010c77686fbd0201504163636f756e7449644c6f6f6b75704f663c543e000120757365726e616d6538011c5665633c75383e0001247369676e6174757265590501704f7074696f6e3c543a3a4f6666636861696e5369676e61747572653e0011240d015365742074686520757365726e616d6520666f72206077686f602e204d7573742062652063616c6c6564206279206120757365726e616d6520617574686f726974792e00550154686520617574686f72697479206d757374206861766520616e2060616c6c6f636174696f6e602e2055736572732063616e20656974686572207072652d7369676e20746865697220757365726e616d6573206f7248616363657074207468656d206c617465722e003c557365726e616d6573206d7573743ad820202d204f6e6c7920636f6e7461696e206c6f776572636173652041534349492063686172616374657273206f72206469676974732e350120202d205768656e20636f6d62696e656420776974682074686520737566666978206f66207468652069737375696e6720617574686f72697479206265205f6c657373207468616e5f207468656020202020604d6178557365726e616d654c656e677468602e3c6163636570745f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0012084d01416363657074206120676976656e20757365726e616d65207468617420616e2060617574686f7269747960206772616e7465642e205468652063616c6c206d75737420696e636c756465207468652066756c6c88757365726e616d652c20617320696e2060757365726e616d652e737566666978602e5c72656d6f76655f657870697265645f617070726f76616c040120757365726e616d657d01012c557365726e616d653c543e00130c610152656d6f766520616e206578706972656420757365726e616d6520617070726f76616c2e2054686520757365726e616d652077617320617070726f76656420627920616e20617574686f7269747920627574206e657665725501616363657074656420627920746865207573657220616e64206d757374206e6f77206265206265796f6e64206974732065787069726174696f6e2e205468652063616c6c206d75737420696e636c756465207468659c66756c6c20757365726e616d652c20617320696e2060757365726e616d652e737566666978602e507365745f7072696d6172795f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0014043101536574206120676976656e20757365726e616d6520617320746865207072696d6172792e2054686520757365726e616d652073686f756c6420696e636c75646520746865207375666669782e6072656d6f76655f64616e676c696e675f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e001508550152656d6f7665206120757365726e616d65207468617420636f72726573706f6e647320746f20616e206163636f756e742077697468206e6f206964656e746974792e20457869737473207768656e20612075736572c067657473206120757365726e616d6520627574207468656e2063616c6c732060636c6561725f6964656e74697479602e04704964656e746974792070616c6c6574206465636c61726174696f6e2ec5040c3c70616c6c65745f6964656e74697479186c6567616379304964656e74697479496e666f04284669656c644c696d697400002401286164646974696f6e616cc9040190426f756e6465645665633c28446174612c2044617461292c204669656c644c696d69743e00011c646973706c6179d1040110446174610001146c6567616cd10401104461746100010c776562d10401104461746100011072696f74d104011044617461000114656d61696cd10401104461746100013c7067705f66696e6765727072696e74490501404f7074696f6e3c5b75383b2032305d3e000114696d616765d10401104461746100011c74776974746572d1040110446174610000c9040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401cd04045300000400450501185665633c543e0000cd0400000408d104d10400d1040c3c70616c6c65745f6964656e746974791474797065731044617461000198104e6f6e6500000010526177300400d5040000010010526177310400d9040000020010526177320400dd040000030010526177330400e1040000040010526177340400480000050010526177350400e5040000060010526177360400e9040000070010526177370400ed040000080010526177380400a5020000090010526177390400f10400000a001452617731300400f50400000b001452617731310400f90400000c001452617731320400fd0400000d001452617731330400010500000e001452617731340400050500000f001452617731350400090500001000145261773136040049010000110014526177313704000d0500001200145261773138040011050000130014526177313904001505000014001452617732300400950100001500145261773231040019050000160014526177323204001d0500001700145261773233040021050000180014526177323404002505000019001452617732350400290500001a0014526177323604002d0500001b001452617732370400310500001c001452617732380400350500001d001452617732390400390500001e0014526177333004003d0500001f001452617733310400410500002000145261773332040004000021002c426c616b6554776f323536040004000022001853686132353604000400002300244b656363616b323536040004000024002c53686154687265653235360400040000250000d504000003000000000800d904000003010000000800dd04000003020000000800e104000003030000000800e504000003050000000800e904000003060000000800ed04000003070000000800f104000003090000000800f5040000030a0000000800f9040000030b0000000800fd040000030c000000080001050000030d000000080005050000030e000000080009050000030f00000008000d050000031100000008001105000003120000000800150500000313000000080019050000031500000008001d050000031600000008002105000003170000000800250500000318000000080029050000031900000008002d050000031a000000080031050000031b000000080035050000031c000000080039050000031d00000008003d050000031e000000080041050000031f00000008004505000002cd0400490504184f7074696f6e0404540195010108104e6f6e6500000010536f6d650400950100000100004d0500000251050051050000040800d1040055050c3c70616c6c65745f6964656e74697479147479706573244a756467656d656e74041c42616c616e63650118011c1c556e6b6e6f776e0000001c46656550616964040018011c42616c616e636500010028526561736f6e61626c65000200244b6e6f776e476f6f64000300244f75744f6644617465000400284c6f775175616c697479000500244572726f6e656f757300060000590504184f7074696f6e040454015d050108104e6f6e6500000010536f6d6504005d0500000100005d05082873705f72756e74696d65384d756c74695369676e617475726500010c1c45643235353139040005030148656432353531393a3a5369676e61747572650000001c53723235353139040005030148737232353531393a3a5369676e617475726500010014456364736104006105014065636473613a3a5369676e617475726500020000610500000341000000080065050c3870616c6c65745f7574696c6974791870616c6c65741043616c6c04045400011814626174636804011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000487c53656e642061206261746368206f662064697370617463682063616c6c732e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e005501546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e31016576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e207468655501604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d6164654d01616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c65746564604c6576656e74206973206465706f73697465642e3461735f64657269766174697665080114696e646578e901010c75313600011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000134dc53656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e00550146696c7465722066726f6d206f726967696e206172652070617373656420616c6f6e672e205468652063616c6c2077696c6c2062652064697370617463686564207769746820616e206f726967696e207768696368bc757365207468652073616d652066696c74657220617320746865206f726967696e206f6620746869732063616c6c2e0045014e4f54453a20496620796f75206e65656420746f20656e73757265207468617420616e79206163636f756e742d62617365642066696c746572696e67206973206e6f7420686f6e6f7265642028692e652e61016265636175736520796f7520657870656374206070726f78796020746f2068617665206265656e2075736564207072696f7220696e207468652063616c6c20737461636b20616e6420796f7520646f206e6f742077616e7451017468652063616c6c207265737472696374696f6e7320746f206170706c7920746f20616e79207375622d6163636f756e7473292c207468656e20757365206061735f6d756c74695f7468726573686f6c645f31607c696e20746865204d756c74697369672070616c6c657420696e73746561642e00f44e4f54453a205072696f7220746f2076657273696f6e202a31322c2074686973207761732063616c6c6564206061735f6c696d697465645f737562602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2462617463685f616c6c04011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000234ec53656e642061206261746368206f662064697370617463682063616c6c7320616e642061746f6d6963616c6c792065786563757465207468656d2e21015468652077686f6c65207472616e73616374696f6e2077696c6c20726f6c6c6261636b20616e64206661696c20696620616e79206f66207468652063616c6c73206661696c65642e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c64697370617463685f617308012461735f6f726967696e6d050154426f783c543a3a50616c6c6574734f726967696e3e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000318c84469737061746368657320612066756e6374696f6e2063616c6c207769746820612070726f7669646564206f726967696e2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e0034232320436f6d706c65786974791c2d204f2831292e2c666f7263655f626174636804011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0004347c53656e642061206261746368206f662064697370617463682063616c6c732ed4556e6c696b6520606261746368602c20697420616c6c6f7773206572726f727320616e6420776f6e277420696e746572727570742e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e004d014966206f726967696e20697320726f6f74207468656e207468652063616c6c732061726520646973706174636820776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c776974685f77656967687408011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000518c4446973706174636820612066756e6374696f6e2063616c6c2077697468206120737065636966696564207765696768742e002d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b8526f6f74206f726967696e20746f20737065636966792074686520776569676874206f66207468652063616c6c2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e6905000002b502006d05085874616e676c655f746573746e65745f72756e74696d65304f726967696e43616c6c65720001101873797374656d0400710501746672616d655f73797374656d3a3a4f726967696e3c52756e74696d653e0001001c436f756e63696c0400750501010170616c6c65745f636f6c6c6563746976653a3a4f726967696e3c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d0020457468657265756d04007905015c70616c6c65745f657468657265756d3a3a4f726967696e00210010566f69640400190301410173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a0a5f5f707269766174653a3a566f69640003000071050c346672616d655f737570706f7274206469737061746368245261774f726967696e04244163636f756e7449640100010c10526f6f74000000185369676e656404000001244163636f756e744964000100104e6f6e65000200007505084470616c6c65745f636f6c6c656374697665245261774f726967696e08244163636f756e7449640100044900010c1c4d656d62657273080010012c4d656d626572436f756e74000010012c4d656d626572436f756e74000000184d656d62657204000001244163636f756e744964000100205f5068616e746f6d000200007905083c70616c6c65745f657468657265756d245261774f726967696e0001044c457468657265756d5472616e73616374696f6e04009101011048313630000000007d050c3c70616c6c65745f6d756c74697369671870616c6c65741043616c6c0404540001105061735f6d756c74695f7468726573686f6c645f310801446f746865725f7369676e61746f72696573390201445665633c543a3a4163636f756e7449643e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000305101496d6d6564696174656c792064697370617463682061206d756c74692d7369676e61747572652063616c6c207573696e6720612073696e676c6520617070726f76616c2066726f6d207468652063616c6c65722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e003d012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f206172652070617274206f662074686501016d756c74692d7369676e61747572652c2062757420646f206e6f7420706172746963697061746520696e2074686520617070726f76616c2070726f636573732e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e00b8526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c742e0034232320436f6d706c657869747919014f285a202b204329207768657265205a20697320746865206c656e677468206f66207468652063616c6c20616e6420432069747320657865637574696f6e207765696768742e2061735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573390201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74810501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0001286d61785f77656967687428011857656967687400019c5501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e00b049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e001d014e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f20757365190160617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e005901526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f746865727769736555016f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642cdc6d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e0034232320436f6d706c6578697479502d20604f2853202b205a202b2043616c6c29602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e21012d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e6c2d2054686520776569676874206f6620746865206063616c6c602e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e40617070726f76655f61735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573390201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74810501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00012463616c6c5f686173680401205b75383b2033325d0001286d61785f7765696768742801185765696768740002785501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0035014e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e3c63616e63656c5f61735f6d756c74691001247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573390201445665633c543a3a4163636f756e7449643e00012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e00012463616c6c5f686173680401205b75383b2033325d000354550143616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c79c4666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e5d012d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c787472616e73616374696f6e20666f7220746869732064697370617463682ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e302d204f6e65206576656e742e842d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e702d2053746f726167653a2072656d6f766573206f6e65206974656d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e810504184f7074696f6e0404540189010108104e6f6e6500000010536f6d6504008901000001000085050c3c70616c6c65745f657468657265756d1870616c6c65741043616c6c040454000104207472616e7361637404012c7472616e73616374696f6e8905012c5472616e73616374696f6e000004845472616e7361637420616e20457468657265756d207472616e73616374696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89050c20657468657265756d2c7472616e73616374696f6e345472616e73616374696f6e563200010c184c656761637904008d0501444c65676163795472616e73616374696f6e0000001c4549503239333004009d050148454950323933305472616e73616374696f6e0001001c454950313535390400a9050148454950313535395472616e73616374696f6e000200008d050c20657468657265756d2c7472616e73616374696f6e444c65676163795472616e73616374696f6e00001c01146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e70757438011442797465730001247369676e6174757265950501505472616e73616374696f6e5369676e6174757265000091050c20657468657265756d2c7472616e73616374696f6e445472616e73616374696f6e416374696f6e0001081043616c6c04009101011048313630000000184372656174650001000095050c20657468657265756d2c7472616e73616374696f6e505472616e73616374696f6e5369676e617475726500000c010476990501545472616e73616374696f6e5265636f76657279496400010472340110483235360001047334011048323536000099050c20657468657265756d2c7472616e73616374696f6e545472616e73616374696f6e5265636f7665727949640000040030010c75363400009d050c20657468657265756d2c7472616e73616374696f6e48454950323933305472616e73616374696f6e00002c0120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a10501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000a105000002a50500a5050c20657468657265756d2c7472616e73616374696f6e384163636573734c6973744974656d000008011c616464726573739101011c4164647265737300013073746f726167655f6b657973c10101245665633c483235363e0000a9050c20657468657265756d2c7472616e73616374696f6e48454950313535395472616e73616374696f6e0000300120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173c90101105532353600013c6d61785f6665655f7065725f676173c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a10501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000ad050c2870616c6c65745f65766d1870616c6c65741043616c6c04045400011020776974686472617708011c61646472657373910101104831363000011476616c756518013042616c616e63654f663c543e000004e057697468647261772062616c616e63652066726f6d2045564d20696e746f2063757272656e63792f62616c616e6365732070616c6c65742e1063616c6c240118736f7572636591010110483136300001187461726765749101011048313630000114696e70757438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0001045d01497373756520616e2045564d2063616c6c206f7065726174696f6e2e20546869732069732073696d696c617220746f2061206d6573736167652063616c6c207472616e73616374696f6e20696e20457468657265756d2e18637265617465200118736f757263659101011048313630000110696e697438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0002085101497373756520616e2045564d20637265617465206f7065726174696f6e2e20546869732069732073696d696c617220746f206120636f6e7472616374206372656174696f6e207472616e73616374696f6e20696e24457468657265756d2e1c63726561746532240118736f757263659101011048313630000110696e697438011c5665633c75383e00011073616c743401104832353600011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0003047c497373756520616e2045564d2063726561746532206f7065726174696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb10504184f7074696f6e04045401c9010108104e6f6e6500000010536f6d650400c9010000010000b505000002b90500b905000004089101c10100bd050c4870616c6c65745f64796e616d69635f6665651870616c6c65741043616c6c040454000104646e6f74655f6d696e5f6761735f70726963655f746172676574040118746172676574c901011055323536000000040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec1050c3c70616c6c65745f626173655f6665651870616c6c65741043616c6c040454000108507365745f626173655f6665655f7065725f67617304010c666565c901011055323536000000387365745f656c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000100040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5050c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c65741043616c6c04045400010478686f746669785f696e635f6163636f756e745f73756666696369656e7473040124616464726573736573c90501245665633c483136303e0000100502496e6372656d656e74206073756666696369656e74736020666f72206578697374696e67206163636f756e747320686176696e672061206e6f6e7a65726f20606e6f6e63656020627574207a65726f206073756666696369656e7473602c2060636f6e73756d6572736020616e64206070726f766964657273602076616c75652e2d0154686973207374617465207761732063617573656420627920612070726576696f75732062756720696e2045564d20637265617465206163636f756e7420646973706174636861626c652e006501416e79206163636f756e747320696e2074686520696e707574206c697374206e6f742073617469736679696e67207468652061626f766520636f6e646974696f6e2077696c6c2072656d61696e20756e61666665637465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec905000002910100cd050c5470616c6c65745f61697264726f705f636c61696d731870616c6c65741043616c6c04045400011814636c61696d0c011064657374d10501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d10501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d50501544d756c7469416464726573735369676e6174757265000060904d616b65206120636c61696d20746f20636f6c6c65637420796f757220746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a0501412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653a943e2028636f6e666967757265642070726566697820737472696e672928616464726573732900a4616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732ee057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d696e745f636c61696d10010c77686fd90101304d756c74694164647265737300011476616c756518013042616c616e63654f663c543e00014076657374696e675f7363686564756c65e1050179014f7074696f6e3c426f756e6465645665633c0a2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e292c20543a3a0a4d617856657374696e675363686564756c65733e2c3e00012473746174656d656e74f10501544f7074696f6e3c53746174656d656e744b696e643e00013ca84d696e742061206e657720636c61696d20746f20636f6c6c656374206e617469766520746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e002c506172616d65746572733af02d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2ef02d206076616c7565603a20546865206e756d626572206f66206e617469766520746f6b656e7320746861742077696c6c20626520636c61696d65642e2d012d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f72207468657365206e617469766520746f6b656e732e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e1d01576520617373756d6520776f7273742063617365207468617420626f74682076657374696e6720616e642073746174656d656e74206973206265696e6720696e7365727465642e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e30636c61696d5f61747465737410011064657374d10501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d10501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d50501544d756c7469416464726573735369676e617475726500012473746174656d656e7438011c5665633c75383e00026c09014d616b65206120636c61696d20746f20636f6c6c65637420796f7572206e617469766520746f6b656e73206279207369676e696e6720612073746174656d656e742e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a2901412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653ac03e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e7429004901616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973c06578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e39012d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e207468653020207369676e61747572652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732efc57656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d5f617474657374602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d6f76655f636c61696d08010c6f6c64d90101304d756c74694164647265737300010c6e6577d90101304d756c7469416464726573730004005c666f7263655f7365745f6578706972795f636f6e6669670801306578706972795f626c6f636b300144426c6f636b4e756d626572466f723c543e00011064657374d90101304d756c74694164647265737300050878536574207468652076616c756520666f7220657870697279636f6e6669678443616e206f6e6c792062652063616c6c656420627920466f7263654f726967696e30636c61696d5f7369676e656404011064657374d10501504f7074696f6e3c4d756c7469416464726573733e00060460436c61696d2066726f6d207369676e6564206f726967696e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed10504184f7074696f6e04045401d9010108104e6f6e6500000010536f6d650400d9010000010000d5050c5470616c6c65745f61697264726f705f636c61696d73147574696c73544d756c7469416464726573735369676e61747572650001080c45564d0400d905013845636473615369676e6174757265000000184e61746976650400dd050140537232353531395369676e617475726500010000d905105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733845636473615369676e617475726500000400610501205b75383b2036355d0000dd050c5470616c6c65745f61697264726f705f636c61696d73147574696c7340537232353531395369676e617475726500000400050301245369676e61747572650000e10504184f7074696f6e04045401e5050108104e6f6e6500000010536f6d650400e5050000010000e5050c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e905045300000400ed0501185665633c543e0000e9050000040c18183000ed05000002e90500f10504184f7074696f6e04045401f5050108104e6f6e6500000010536f6d650400f5050000010000f505085470616c6c65745f61697264726f705f636c61696d733453746174656d656e744b696e640001081c526567756c6172000000105361666500010000f9050c3070616c6c65745f70726f78791870616c6c65741043616c6c0404540001281470726f78790c01107265616cbd0201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065fd0501504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000244d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f726973656420666f72207468726f75676830606164645f70726f7879602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e246164645f70726f78790c012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e0001244501526567697374657220612070726f7879206163636f756e7420666f72207468652073656e64657220746861742069732061626c6520746f206d616b652063616c6c73206f6e2069747320626568616c662e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a11012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f206d616b6520612070726f78792efc2d206070726f78795f74797065603a20546865207065726d697373696f6e7320616c6c6f77656420666f7220746869732070726f7879206163636f756e742e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e3072656d6f76655f70726f78790c012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00021ca8556e726567697374657220612070726f7879206163636f756e7420666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a25012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f2072656d6f766520617320612070726f78792e41012d206070726f78795f74797065603a20546865207065726d697373696f6e732063757272656e746c7920656e61626c656420666f72207468652072656d6f7665642070726f7879206163636f756e742e3872656d6f76655f70726f78696573000318b4556e726567697374657220616c6c2070726f7879206163636f756e747320666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0041015741524e494e473a2054686973206d61792062652063616c6c6564206f6e206163636f756e74732063726561746564206279206070757265602c20686f776576657220696620646f6e652c207468656e590174686520756e726573657276656420666565732077696c6c20626520696e61636365737369626c652e202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a2c6372656174655f707572650c012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e000114696e646578e901010c7531360004483901537061776e2061206672657368206e6577206163636f756e7420746861742069732067756172616e7465656420746f206265206f746865727769736520696e61636365737369626c652c20616e64fc696e697469616c697a65206974207769746820612070726f7879206f66206070726f78795f747970656020666f7220606f726967696e602073656e6465722e006c5265717569726573206120605369676e656460206f726967696e2e0051012d206070726f78795f74797065603a205468652074797065206f66207468652070726f78792074686174207468652073656e6465722077696c6c2062652072656769737465726564206173206f766572207468654d016e6577206163636f756e742e20546869732077696c6c20616c6d6f737420616c7761797320626520746865206d6f7374207065726d697373697665206050726f7879547970656020706f737369626c6520746f78616c6c6f7720666f72206d6178696d756d20666c65786962696c6974792e51012d2060696e646578603a204120646973616d626967756174696f6e20696e6465782c20696e206361736520746869732069732063616c6c6564206d756c7469706c652074696d657320696e207468652073616d655d017472616e73616374696f6e2028652e672e207769746820607574696c6974793a3a626174636860292e20556e6c65737320796f75277265207573696e67206062617463686020796f752070726f6261626c79206a7573744077616e7420746f20757365206030602e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e0051014661696c73207769746820604475706c69636174656020696620746869732068617320616c7265616479206265656e2063616c6c656420696e2074686973207472616e73616374696f6e2c2066726f6d207468659873616d652073656e6465722c2077697468207468652073616d6520706172616d65746572732e00e44661696c732069662074686572652061726520696e73756666696369656e742066756e647320746f2070617920666f72206465706f7369742e246b696c6c5f7075726514011c737061776e6572bd0201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f787954797065000114696e646578e901010c7531360001186865696768742c0144426c6f636b4e756d626572466f723c543e0001246578745f696e6465786102010c753332000540a052656d6f76657320612070726576696f75736c7920737061776e656420707572652070726f78792e0049015741524e494e473a202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20416e792066756e64732068656c6420696e2069742077696c6c20626534696e61636365737369626c652e0059015265717569726573206120605369676e656460206f726967696e2c20616e64207468652073656e646572206163636f756e74206d7573742068617665206265656e206372656174656420627920612063616c6c20746f94607075726560207769746820636f72726573706f6e64696e6720706172616d65746572732e0039012d2060737061776e6572603a20546865206163636f756e742074686174206f726967696e616c6c792063616c6c65642060707572656020746f206372656174652074686973206163636f756e742e39012d2060696e646578603a2054686520646973616d626967756174696f6e20696e646578206f726967696e616c6c792070617373656420746f206070757265602e2050726f6261626c79206030602eec2d206070726f78795f74797065603a205468652070726f78792074797065206f726967696e616c6c792070617373656420746f206070757265602e29012d2060686569676874603a2054686520686569676874206f662074686520636861696e207768656e207468652063616c6c20746f20607075726560207761732070726f6365737365642e35012d20606578745f696e646578603a205468652065787472696e73696320696e64657820696e207768696368207468652063616c6c20746f20607075726560207761732070726f6365737365642e0035014661696c73207769746820604e6f5065726d697373696f6e6020696e2063617365207468652063616c6c6572206973206e6f7420612070726576696f75736c7920637265617465642070757265dc6163636f756e742077686f7365206070757265602063616c6c2068617320636f72726573706f6e64696e6720706172616d65746572732e20616e6e6f756e63650801107265616cbd0201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e00063c05015075626c697368207468652068617368206f6620612070726f78792d63616c6c20746861742077696c6c206265206d61646520696e20746865206675747572652e005d0154686973206d7573742062652063616c6c656420736f6d65206e756d626572206f6620626c6f636b73206265666f72652074686520636f72726573706f6e64696e67206070726f78796020697320617474656d7074656425016966207468652064656c6179206173736f6369617465642077697468207468652070726f78792072656c6174696f6e736869702069732067726561746572207468616e207a65726f2e0011014e6f206d6f7265207468616e20604d617850656e64696e676020616e6e6f756e63656d656e7473206d6179206265206d61646520617420616e79206f6e652074696d652e000901546869732077696c6c2074616b652061206465706f736974206f662060416e6e6f756e63656d656e744465706f736974466163746f72602061732077656c6c206173190160416e6e6f756e63656d656e744465706f736974426173656020696620746865726520617265206e6f206f746865722070656e64696e6720616e6e6f756e63656d656e74732e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420612070726f7879206f6620607265616c602e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656d6f76655f616e6e6f756e63656d656e740801107265616cbd0201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e0007287052656d6f7665206120676976656e20616e6e6f756e63656d656e742e0059014d61792062652063616c6c656420627920612070726f7879206163636f756e7420746f2072656d6f766520612063616c6c20746865792070726576696f75736c7920616e6e6f756e63656420616e642072657475726e30746865206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656a6563745f616e6e6f756e63656d656e7408012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e000828b052656d6f76652074686520676976656e20616e6e6f756e63656d656e74206f6620612064656c65676174652e0061014d61792062652063616c6c6564206279206120746172676574202870726f7869656429206163636f756e7420746f2072656d6f766520612063616c6c2074686174206f6e65206f662074686569722064656c6567617465732501286064656c656761746560292068617320616e6e6f756e63656420746865792077616e7420746f20657865637574652e20546865206465706f7369742069732072657475726e65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733af42d206064656c6567617465603a20546865206163636f756e7420746861742070726576696f75736c7920616e6e6f756e636564207468652063616c6c2ebc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652e3c70726f78795f616e6e6f756e63656410012064656c6567617465bd0201504163636f756e7449644c6f6f6b75704f663c543e0001107265616cbd0201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065fd0501504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb502017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00092c4d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f72697a656420666f72207468726f75676830606164645f70726f7879602e00a852656d6f76657320616e7920636f72726573706f6e64696e6720616e6e6f756e63656d656e742873292e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732efd0504184f7074696f6e04045401e5010108104e6f6e6500000010536f6d650400e501000001000001060c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c65741043616c6c04045400015c386a6f696e5f6f70657261746f727304012c626f6e645f616d6f756e7418013042616c616e63654f663c543e000004f8416c6c6f777320616e206163636f756e7420746f206a6f696e20617320616e206f70657261746f722062792070726f766964696e672061207374616b652e607363686564756c655f6c656176655f6f70657261746f72730001047c5363686564756c657320616e206f70657261746f7220746f206c656176652e5863616e63656c5f6c656176655f6f70657261746f7273000204a843616e63656c732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e5c657865637574655f6c656176655f6f70657261746f7273000304ac45786563757465732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e486f70657261746f725f626f6e645f6d6f726504013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e000404ac416c6c6f777320616e206f70657261746f7220746f20696e637265617365207468656972207374616b652e647363686564756c655f6f70657261746f725f756e7374616b65040138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504b85363686564756c657320616e206f70657261746f7220746f206465637265617365207468656972207374616b652e60657865637574655f6f70657261746f725f756e7374616b65000604d045786563757465732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e5c63616e63656c5f6f70657261746f725f756e7374616b65000704cc43616e63656c732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e28676f5f6f66666c696e6500080484416c6c6f777320616e206f70657261746f7220746f20676f206f66666c696e652e24676f5f6f6e6c696e6500090480416c6c6f777320616e206f70657261746f7220746f20676f206f6e6c696e652e1c6465706f73697408012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e000a0488416c6c6f77732061207573657220746f206465706f73697420616e2061737365742e447363686564756c655f776974686472617708012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e000b04785363686564756c657320616e20776974686472617720726571756573742e40657865637574655f7769746864726177000c049845786563757465732061207363686564756c656420776974686472617720726571756573742e3c63616e63656c5f776974686472617708012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e000d049443616e63656c732061207363686564756c656420776974686472617720726571756573742e2064656c65676174651001206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e00014c626c75657072696e745f73656c656374696f6e050601d844656c656761746f72426c75657072696e7453656c656374696f6e3c543a3a4d617844656c656761746f72426c75657072696e74733e000e04fc416c6c6f77732061207573657220746f2064656c656761746520616e20616d6f756e74206f6620616e20617373657420746f20616e206f70657261746f722e687363686564756c655f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e000f04c85363686564756c65732061207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e64657865637574655f64656c656761746f725f756e7374616b65001004ec45786563757465732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e6063616e63656c5f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964180128543a3a41737365744964000118616d6f756e7418013042616c616e63654f663c543e001104e843616e63656c732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e647365745f696e63656e746976655f6170795f616e645f6361700c01207661756c745f6964180128543a3a5661756c74496400010c617079f101014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e001218a853657473207468652041505920616e642063617020666f7220612073706563696669632061737365742e0101546865204150592069732074686520616e6e75616c2070657263656e74616765207969656c642074686174207468652061737365742077696c6c206561726e2e5901546865206361702069732074686520616d6f756e74206f662061737365747320726571756972656420746f206265206465706f736974656420746f20646973747269627574652074686520656e74697265204150592e110154686520415059206973206361707065642061742031302520616e642077696c6c20726571756972652072756e74696d65207570677261646520746f206368616e67652e0055015768696c652074686520636170206973206e6f74206d65742c20746865204150592064697374726962757465642077696c6c2062652060616d6f756e745f6465706f7369746564202f20636170202a20415059602e7c77686974656c6973745f626c75657072696e745f666f725f72657761726473040130626c75657072696e745f696410010c7533320013048c57686974656c69737473206120626c75657072696e7420666f7220726577617264732e546d616e6167655f61737365745f696e5f7661756c740c01207661756c745f6964180128543a3a5661756c74496400012061737365745f6964180128543a3a41737365744964000118616374696f6ef501012c4173736574416374696f6e001404804d616e61676520617373657420696420746f207661756c742072657761726473406164645f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001604bc41646473206120626c75657072696e7420494420746f20612064656c656761746f7227732073656c656374696f6e2e4c72656d6f76655f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001704d052656d6f766573206120626c75657072696e742049442066726f6d20612064656c656761746f7227732073656c656374696f6e2e04c85468652063616c6c61626c652066756e6374696f6e73202865787472696e7369637329206f66207468652070616c6c65742e0506107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f726c44656c656761746f72426c75657072696e7453656c656374696f6e04344d6178426c75657072696e7473010906010814466978656404000d060198426f756e6465645665633c426c75657072696e7449642c204d6178426c75657072696e74733e0000000c416c6c000100000906085874616e676c655f746573746e65745f72756e74696d65584d617844656c656761746f72426c75657072696e7473000000000d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540130045300000400110601185665633c543e00001106000002300015060c3c70616c6c65745f7365727669636573186d6f64756c651043616c6c040454000138406372656174655f626c75657072696e74040124626c75657072696e741906018053657276696365426c75657072696e743c543a3a436f6e73747261696e74733e0000207c4372656174652061206e6577207365727669636520626c75657072696e742e00590141205365727669636520426c75657072696e7420697320612074656d706c61746520666f722061207365727669636520746861742063616e20626520696e7374616e746961746564206c61746572206f6e206279206114757365722e00302320506172616d6574657273fc2d20606f726967696e603a20546865206163636f756e742074686174206973206372656174696e6720746865207365727669636520626c75657072696e742eb02d2060626c75657072696e74603a2054686520626c75657072696e74206f662074686520736572766963652e307072655f7265676973746572040130626c75657072696e745f69642c010c75363400012401015072652d7265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e005d015468652063616c6c65722063616e207072652d726567697374657220666f72206120626c75657072696e742c2077686963682077696c6c20656d697420612060507265526567697374726174696f6e60206576656e742e510154686973206576656e742063616e206265206c697374656e656420746f20627920746865206f70657261746f72206e6f646520746f20657865637574652074686520637573746f6d20626c75657072696e74277358726567697374726174696f6e2066756e6374696f6e2e00302320506172616d657465727329012d20606f726967696e603a20546865206163636f756e742074686174206973207072652d7265676973746572696e6720666f7220746865207365727669636520626c75657072696e742ec82d2060626c75657072696e745f6964603a20546865204944206f6620746865207365727669636520626c75657072696e742e207265676973746572100130626c75657072696e745f69642c010c75363400012c707265666572656e636573fd01014c4f70657261746f72507265666572656e636573000144726567697374726174696f6e5f61726773090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e00011476616c75656d01013042616c616e63654f663c543e000210f05265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e0059015468652063616c6c6572206d6179207265717569726520616e20617070726f76616c206669727374206265666f726520746865792063616e2061636365707420746f2070726f7669646520746865207365727669636538666f72207468652075736572732e28756e7265676973746572040130626c75657072696e745f69642c010c7536340003141901556e7265676973746572207468652063616c6c65722066726f6d206265696e6720616e206f70657261746f7220666f7220746865207365727669636520626c75657072696e744901736f20746861742c206e6f206d6f72652073657276696365732077696c6c2061737369676e656420746f207468652063616c6c657220666f72207468697320737065636966696320626c75657072696e742e39014e6f746520746861742c207468652063616c6c6572206e6565647320746f206b6565702070726f766964696e67207365727669636520666f72206f746865722061637469766520736572766963656101746861742075736573207468697320626c75657072696e742c20756e74696c2074686520656e64206f6620736572766963652074696d652c206f74686572776973652074686579206d617920676574207265706f7274656430616e6420736c61736865642e507570646174655f70726963655f74617267657473080130626c75657072696e745f69642c010c75363400013470726963655f746172676574730502013050726963655461726765747300040c250155706461746520746865207072696365207461726765747320666f72207468652063616c6c657220666f722061207370656369666963207365727669636520626c75657072696e742e00b0536565205b6053656c663a3a7265676973746572605d20666f72206d6f726520696e666f726d6174696f6e2e1c726571756573741c0130626c75657072696e745f69642c010c7536340001447065726d69747465645f63616c6c657273390201445665633c543a3a4163636f756e7449643e0001246f70657261746f7273390201445665633c543a3a4163636f756e7449643e000130726571756573745f61726773090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0001186173736574733d02013c5665633c543a3a417373657449643e00010c74746c2c0144426c6f636b4e756d626572466f723c543e00011476616c75656d01013042616c616e63654f663c543e00050c4501526571756573742061206e6577207365727669636520746f20626520696e69746961746564207573696e67207468652070726f766964656420626c75657072696e7420776974682061206c697374206f664d016f70657261746f727320746861742077696c6c2072756e20796f757220736572766963652e204f7074696f6e616c6c792c20796f752063616e2073706563696669792077686f206973207065726d6974746564490163616c6c6572206f66207468697320736572766963652c2062792064656661756c74206f6e6c79207468652063616c6c657220697320616c6c6f77656420746f2063616c6c2074686520736572766963652e1c617070726f7665080128726571756573745f69642c010c75363400014472657374616b696e675f70657263656e74dd06011c50657263656e740006100101417070726f76652061207365727669636520726571756573742c20736f20746861742074686520736572766963652063616e20626520696e697469617465642e006101546865206072657374616b696e675f70657263656e7460206973207468652070657263656e74616765206f66207468652072657374616b656420746f6b656e7320746861742077696c6c206265206578706f73656420746f3074686520736572766963652e1872656a656374040128726571756573745f69642c010c75363400070c6452656a6563742061207365727669636520726571756573742e510154686520736572766963652077696c6c206e6f7420626520696e697469617465642c20616e6420746865207265717565737465722077696c6c206e65656420746f2075706461746520746865207365727669636520726571756573742e247465726d696e617465040128736572766963655f69642c010c753634000804cc5465726d696e6174657320746865207365727669636520627920746865206f776e6572206f662074686520736572766963652e1063616c6c0c0128736572766963655f69642c010c75363400010c6a6f62e1060108753800011061726773090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0009086843616c6c2061204a6f6220696e2074686520736572766963652e1d015468652063616c6c6572206e6565647320746f20626520746865206f776e6572206f662074686520736572766963652c206f722061207065726d69747465642063616c6c65722e347375626d69745f726573756c740c0128736572766963655f69642c010c75363400011c63616c6c5f69642c010c753634000118726573756c74090201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000a04e85375626d697420746865206a6f6220726573756c74206279207573696e6720746865207365727669636520494420616e642063616c6c2049442e14736c6173680c01206f6666656e646572000130543a3a4163636f756e744964000128736572766963655f69642c010c75363400011c70657263656e74dd06011c50657263656e74000b14ad01536c61736820616e206f70657261746f7220286f6666656e6465722920666f72206120736572766963652069642077697468206120676976656e2070657263656e74206f66207468656972206578706f736564207374616b6520666f72207468617420736572766963652e000d015468652063616c6c6572206e6565647320746f20626520616e20617574686f72697a656420536c617368204f726967696e20666f72207468697320736572766963652ea9014e6f74652074686174207468697320646f6573206e6f74206170706c792074686520736c617368206469726563746c792c2062757420696e7374656164207363686564756c657320612064656665727265642063616c6c20746f206170706c792074686520736c61736848627920616e6f7468657220656e746974792e1c6469737075746508010c6572616102010c753332000114696e6465786102010c753332000c0cd84469737075746520616e205b556e6170706c696564536c6173685d20666f72206120676976656e2065726120616e6420696e6465782e0071015468652063616c6c6572206e6565647320746f20626520616e20617574686f72697a65642044697370757465204f726967696e20666f7220746865207365727669636520696e20746865205b556e6170706c696564536c6173685d2e9c7570646174655f6d61737465725f626c75657072696e745f736572766963655f6d616e6167657204011c616464726573739101011048313630000d00040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e19060c4474616e676c655f7072696d6974697665732073657276696365734053657276696365426c75657072696e7404044300001c01206d657461646174611d060148536572766963654d657461646174613c433e0001106a6f62732d0601c8426f756e6465645665633c4a6f62446566696e6974696f6e3c433e2c20433a3a4d61784a6f6273506572536572766963653e00014c726567697374726174696f6e5f706172616d733906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000138726571756573745f706172616d733906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e00011c6d616e616765725506015c426c75657072696e74536572766963654d616e6167657200015c6d61737465725f6d616e616765725f7265766973696f6e590601944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e0001186761646765745d0601244761646765743c433e00001d060c4474616e676c655f7072696d6974697665732073657276696365733c536572766963654d6574616461746104044300002001106e616d652106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000118617574686f72290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00012063617465676f7279290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00013c636f64655f7265706f7369746f7279290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e0001106c6f676f290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c77656273697465290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c6c6963656e7365290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00002106104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040025060144426f756e6465645665633c75382c20533e000025060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000290604184f7074696f6e0404540121060108104e6f6e6500000010536f6d650400210600000100002d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013106045300000400510601185665633c543e000031060c4474616e676c655f7072696d697469766573207365727669636573344a6f62446566696e6974696f6e04044300000c01206d65746164617461350601384a6f624d657461646174613c433e000118706172616d733906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000118726573756c743906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000035060c4474616e676c655f7072696d6974697665732073657276696365732c4a6f624d6574616461746104044300000801106e616d652106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e290601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000039060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013d060453000004004d0601185665633c543e00003d06104474616e676c655f7072696d697469766573207365727669636573146669656c64244669656c645479706500014410566f696400000010426f6f6c0001001455696e743800020010496e74380003001855696e74313600040014496e7431360005001855696e74333200060014496e7433320007001855696e74363400080014496e74363400090018537472696e67000a00144279746573000b00204f7074696f6e616c04003d060138426f783c4669656c64547970653e000c00144172726179080030010c75363400003d060138426f783c4669656c64547970653e000d00104c69737404003d060138426f783c4669656c64547970653e000e001853747275637408003d060138426f783c4669656c64547970653e0000410601e8426f756e6465645665633c28426f783c4669656c64547970653e2c20426f783c4669656c64547970653e292c20436f6e73745533323c33323e3e000f00244163636f756e7449640064000041060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014506045300000400490601185665633c543e00004506000004083d063d060049060000024506004d060000023d0600510600000231060055060c4474616e676c655f7072696d6974697665732073657276696365735c426c75657072696e74536572766963654d616e616765720001040c45766d04009101013473705f636f72653a3a483136300000000059060c4474616e676c655f7072696d697469766573207365727669636573944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000108184c6174657374000000205370656369666963040010010c753332000100005d060c4474616e676c655f7072696d6974697665732073657276696365731847616467657404044300010c105761736d0400610601345761736d4761646765743c433e000000184e61746976650400d506013c4e61746976654761646765743c433e00010024436f6e7461696e65720400d9060148436f6e7461696e65724761646765743c433e0002000061060c4474616e676c655f7072696d697469766573207365727669636573285761736d476164676574040443000008011c72756e74696d656506012c5761736d52756e74696d6500011c736f7572636573690601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e000065060c4474616e676c655f7072696d6974697665732073657276696365732c5761736d52756e74696d65000108205761736d74696d65000000185761736d65720001000069060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016d06045300000400d10601185665633c543e00006d060c4474616e676c655f7072696d69746976657320736572766963657330476164676574536f75726365040443000004011c6665746368657271060158476164676574536f75726365466574636865723c433e000071060c4474616e676c655f7072696d6974697665732073657276696365734c476164676574536f75726365466574636865720404430001101049504653040075060190426f756e6465645665633c75382c20433a3a4d617849706673486173684c656e6774683e00000018476974687562040079060140476974687562466574636865723c433e00010038436f6e7461696e6572496d6167650400b106015c496d6167655265676973747279466574636865723c433e0002001c54657374696e670400cd06013854657374466574636865723c433e0003000075060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000079060c4474616e676c655f7072696d697469766573207365727669636573344769746875624665746368657204044300001001146f776e65727d06018c426f756e646564537472696e673c433a3a4d61784769744f776e65724c656e6774683e0001107265706f85060188426f756e646564537472696e673c433a3a4d61784769745265706f4c656e6774683e00010c7461678d060184426f756e646564537472696e673c433a3a4d61784769745461674c656e6774683e00012062696e6172696573950601d0426f756e6465645665633c47616467657442696e6172793c433e2c20433a3a4d617842696e61726965735065724761646765743e00007d06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040081060144426f756e6465645665633c75382c20533e000081060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00008506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040089060144426f756e6465645665633c75382c20533e000089060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00008d06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040091060144426f756e6465645665633c75382c20533e000091060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000095060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019906045300000400ad0601185665633c543e000099060c4474616e676c655f7072696d6974697665732073657276696365733047616467657442696e6172790404430000100110617263689d0601304172636869746563747572650001086f73a106013c4f7065726174696e6753797374656d0001106e616d65a5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e0001187368613235360401205b75383b2033325d00009d060c4474616e676c655f7072696d69746976657320736572766963657330417263686974656374757265000128105761736d000000185761736d36340001001057617369000200185761736936340003000c416d6400040014416d6436340005000c41726d0006001441726d36340007001452697363560008001c5269736356363400090000a1060c4474616e676c655f7072696d6974697665732073657276696365733c4f7065726174696e6753797374656d0001141c556e6b6e6f776e000000144c696e75780001001c57696e646f7773000200144d61634f530003000c42534400040000a506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400a9060144426f756e6465645665633c75382c20533e0000a9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000ad06000002990600b1060c4474616e676c655f7072696d69746976657320736572766963657350496d61676552656769737472794665746368657204044300000c01207265676973747279b50601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e657252656769737472794c656e6774683e000114696d616765bd0601b4426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167654e616d654c656e6774683e00010c746167c50601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167655461674c656e6774683e0000b506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400b9060144426f756e6465645665633c75382c20533e0000b9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000bd06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c1060144426f756e6465645665633c75382c20533e0000c1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000c506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c9060144426f756e6465645665633c75382c20533e0000c9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000cd060c4474616e676c655f7072696d6974697665732073657276696365732c546573744665746368657204044300000c0134636172676f5f7061636b616765a5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124636172676f5f62696ea5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124626173655f706174682106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e0000d1060000026d0600d5060c4474616e676c655f7072696d697469766573207365727669636573304e6174697665476164676574040443000004011c736f7572636573690601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000d9060c4474616e676c655f7072696d6974697665732073657276696365733c436f6e7461696e6572476164676574040443000004011c736f7572636573690601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000dd06000006f10100e1060000060800e5060c4470616c6c65745f74616e676c655f6c73741870616c6c65741043616c6c040454000150106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002045015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f74650041012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726108011c706f6f6c5f6964100118506f6f6c49640001146578747261e906015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e18756e626f6e640c01386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640c01386d656d6265725f6163636f756e74bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c75333200054c5501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500ec4966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e18637265617465180118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74bd0201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572bd0201504163636f756e7449644c6f6f6b75704f663c543e0001106e616d65ed0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f69641c0118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74bd0201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001106e616d65ed0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f7273390201445665633c543a3a4163636f756e7449643e00081c7c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e247365745f737461746508011c706f6f6c5f6964100118506f6f6c4964000114737461746545020124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731001346d696e5f6a6f696e5f626f6e64fd060158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e64fd060158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7301070134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e05070144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d75737420626514526f6f742e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f7409070158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f7209070158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e63657209070158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d1c704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720c01186d656d626572bd0201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001146578747261e906015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373416c6c60206f7220605065726d697373696f6e6c657373436f6d706f756e64602e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654902019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e4d0201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6ccc69732061626c6520746f20636f6e6966696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ee9060c4470616c6c65745f74616e676c655f6c737414747970657324426f6e644578747261041c42616c616e6365011801042c4672656542616c616e6365040018011c42616c616e636500000000ed0604184f7074696f6e04045401f1060108104e6f6e6500000010536f6d650400f1060000010000f1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000f50604184f7074696f6e04045401f9060108104e6f6e6500000010536f6d650400f9060000010000f9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000fd060c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f76650002000001070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f76650002000005070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000009070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f7665000200000d070c2c70616c6c65745f7375646f1870616c6c6574144572726f720404540001042c526571756972655375646f0000048053656e646572206d75737420626520746865205375646f206163636f756e742e04684572726f7220666f7220746865205375646f2070616c6c65742e11070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e000015070c3470616c6c65745f61737365747314747970657330417373657444657461696c730c1c42616c616e63650118244163636f756e7449640100384465706f73697442616c616e63650118003001146f776e65720001244163636f756e7449640001186973737565720001244163636f756e74496400011461646d696e0001244163636f756e74496400011c667265657a65720001244163636f756e744964000118737570706c7918011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500012c6d696e5f62616c616e636518011c42616c616e636500013469735f73756666696369656e74200110626f6f6c0001206163636f756e747310010c75333200012c73756666696369656e747310010c753332000124617070726f76616c7310010c7533320001187374617475731907012c4173736574537461747573000019070c3470616c6c65745f6173736574731474797065732c417373657453746174757300010c104c6976650000001846726f7a656e0001002844657374726f79696e67000200001d070000040818000021070c3470616c6c65745f6173736574731474797065733041737365744163636f756e74101c42616c616e63650118384465706f73697442616c616e636501181445787472610184244163636f756e74496401000010011c62616c616e636518011c42616c616e6365000118737461747573250701344163636f756e74537461747573000118726561736f6e290701a84578697374656e6365526561736f6e3c4465706f73697442616c616e63652c204163636f756e7449643e00011465787472618401144578747261000025070c3470616c6c65745f617373657473147479706573344163636f756e7453746174757300010c184c69717569640000001846726f7a656e0001001c426c6f636b65640002000029070c3470616c6c65745f6173736574731474797065733c4578697374656e6365526561736f6e081c42616c616e63650118244163636f756e7449640100011420436f6e73756d65720000002853756666696369656e740001002c4465706f73697448656c64040018011c42616c616e63650002003c4465706f736974526566756e6465640003002c4465706f73697446726f6d08000001244163636f756e744964000018011c42616c616e6365000400002d070000040c1800000031070c3470616c6c65745f61737365747314747970657320417070726f76616c081c42616c616e63650118384465706f73697442616c616e6365011800080118616d6f756e7418011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e6365000035070c3470616c6c65745f6173736574731474797065733441737365744d6574616461746108384465706f73697442616c616e6365011834426f756e646564537472696e670139070014011c6465706f7369741801384465706f73697442616c616e63650001106e616d6539070134426f756e646564537472696e6700011873796d626f6c39070134426f756e646564537472696e67000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000039070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00003d070c3470616c6c65745f6173736574731870616c6c6574144572726f720804540004490001542842616c616e63654c6f7700000415014163636f756e742062616c616e6365206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865207472616e7366657220616d6f756e742e244e6f4163636f756e7400010490546865206163636f756e7420746f20616c74657220646f6573206e6f742065786973742e304e6f5065726d697373696f6e000204e8546865207369676e696e67206163636f756e7420686173206e6f207065726d697373696f6e20746f20646f20746865206f7065726174696f6e2e1c556e6b6e6f776e0003047854686520676976656e20617373657420494420697320756e6b6e6f776e2e1846726f7a656e00040474546865206f726967696e206163636f756e742069732066726f7a656e2e14496e5573650005047854686520617373657420494420697320616c72656164792074616b656e2e284261645769746e6573730006046c496e76616c6964207769746e657373206461746120676976656e2e384d696e42616c616e63655a65726f0007048c4d696e696d756d2062616c616e63652073686f756c64206265206e6f6e2d7a65726f2e4c556e617661696c61626c65436f6e73756d657200080c5901556e61626c6520746f20696e6372656d656e742074686520636f6e73756d6572207265666572656e636520636f756e74657273206f6e20746865206163636f756e742e20456974686572206e6f2070726f76696465724d017265666572656e63652065786973747320746f20616c6c6f772061206e6f6e2d7a65726f2062616c616e6365206f662061206e6f6e2d73656c662d73756666696369656e742061737365742c206f72206f6e65f06665776572207468656e20746865206d6178696d756d206e756d626572206f6620636f6e73756d65727320686173206265656e20726561636865642e2c4261644d657461646174610009045c496e76616c6964206d6574616461746120676976656e2e28556e617070726f766564000a04c44e6f20617070726f76616c20657869737473207468617420776f756c6420616c6c6f7720746865207472616e736665722e20576f756c64446965000b04350154686520736f75726365206163636f756e7420776f756c64206e6f74207375727669766520746865207472616e7366657220616e64206974206e6565647320746f207374617920616c6976652e34416c7265616479457869737473000c04845468652061737365742d6163636f756e7420616c7265616479206578697374732e244e6f4465706f736974000d04d45468652061737365742d6163636f756e7420646f65736e2774206861766520616e206173736f636961746564206465706f7369742e24576f756c644275726e000e04c4546865206f7065726174696f6e20776f756c6420726573756c7420696e2066756e6473206265696e67206275726e65642e244c6976654173736574000f0859015468652061737365742069732061206c69766520617373657420616e64206973206163746976656c79206265696e6720757365642e20557375616c6c7920656d697420666f72206f7065726174696f6e7320737563681d016173206073746172745f64657374726f796020776869636820726571756972652074686520617373657420746f20626520696e20612064657374726f79696e672073746174652e3041737365744e6f744c697665001004c8546865206173736574206973206e6f74206c6976652c20616e64206c696b656c79206265696e672064657374726f7965642e3c496e636f7272656374537461747573001104b054686520617373657420737461747573206973206e6f7420746865206578706563746564207374617475732e244e6f7446726f7a656e001204d85468652061737365742073686f756c642062652066726f7a656e206265666f72652074686520676976656e206f7065726174696f6e2e3843616c6c6261636b4661696c65640013048443616c6c6261636b20616374696f6e20726573756c74656420696e206572726f722842616441737365744964001404c8546865206173736574204944206d75737420626520657175616c20746f20746865205b604e65787441737365744964605d2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e41070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e6465645665630804540145070453000004004d0701185665633c543e000045070c3c70616c6c65745f62616c616e6365731474797065732c42616c616e63654c6f636b041c42616c616e63650118000c01086964a50201384c6f636b4964656e746966696572000118616d6f756e7418011c42616c616e636500011c726561736f6e734907011c526561736f6e73000049070c3c70616c6c65745f62616c616e6365731474797065731c526561736f6e7300010c0c466565000000104d6973630001000c416c6c000200004d0700000245070051070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454015507045300000400590701185665633c543e000055070c3c70616c6c65745f62616c616e6365731474797065732c52657365727665446174610844526573657276654964656e74696669657201a5021c42616c616e63650118000801086964a5020144526573657276654964656e746966696572000118616d6f756e7418011c42616c616e6365000059070000025507005d070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540161070453000004006d0701185665633c543e0000610714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e74080849640165071c42616c616e63650118000801086964650701084964000118616d6f756e7418011c42616c616e636500006507085874616e676c655f746573746e65745f72756e74696d654452756e74696d65486f6c64526561736f6e00010420507265696d61676504006907016c70616c6c65745f707265696d6167653a3a486f6c64526561736f6e001a000069070c3c70616c6c65745f707265696d6167651870616c6c657428486f6c64526561736f6e00010420507265696d616765000000006d0700000261070071070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017507045300000400850701185665633c543e0000750714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e74080849640179071c42616c616e63650118000801086964790701084964000118616d6f756e7418011c42616c616e636500007907085874616e676c655f746573746e65745f72756e74696d654c52756e74696d65467265657a65526561736f6e0001083c4e6f6d696e6174696f6e506f6f6c7304007d07019470616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a467265657a65526561736f6e0018000c4c737404008107017c70616c6c65745f74616e676c655f6c73743a3a467265657a65526561736f6e003400007d070c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e63650000000081070c4470616c6c65745f74616e676c655f6c73741870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e636500000000850700000275070089070c3c70616c6c65745f62616c616e6365731870616c6c6574144572726f720804540004490001303856657374696e6742616c616e63650000049c56657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75652e544c69717569646974795265737472696374696f6e73000104c84163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2e4c496e73756666696369656e7442616c616e63650002047842616c616e636520746f6f206c6f7720746f2073656e642076616c75652e484578697374656e7469616c4465706f736974000304ec56616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742e34457870656e646162696c697479000404905472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742e5c4578697374696e6756657374696e675363686564756c65000504cc412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e742e2c446561644163636f756e740006048c42656e6566696369617279206163636f756e74206d757374207072652d65786973742e3c546f6f4d616e795265736572766573000704b84e756d626572206f66206e616d65642072657365727665732065786365656420604d61785265736572766573602e30546f6f4d616e79486f6c6473000804f84e756d626572206f6620686f6c647320657863656564206056617269616e74436f756e744f663c543a3a52756e74696d65486f6c64526561736f6e3e602e38546f6f4d616e79467265657a6573000904984e756d626572206f6620667265657a65732065786365656420604d6178467265657a6573602e4c49737375616e63654465616374697661746564000a0401015468652069737375616e63652063616e6e6f74206265206d6f6469666965642073696e636520697420697320616c72656164792064656163746976617465642e2444656c74615a65726f000b04645468652064656c74612063616e6e6f74206265207a65726f2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e8d070c3473705f61726974686d657469632c66697865645f706f696e7424466978656455313238000004001801107531323800009107086870616c6c65745f7472616e73616374696f6e5f7061796d656e742052656c6561736573000108245631416e6369656e740000000856320001000095070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e6465645665630804540199070453000004009d0701185665633c543e0000990700000408d50230009d07000002990700a1070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540104045300000400a50701185665633c543e0000a5070000020400a90704184f7074696f6e04045401ad070108104e6f6e6500000010536f6d650400ad070000010000ad070c4473705f636f6e73656e7375735f626162651c646967657374732450726544696765737400010c1c5072696d6172790400b10701405072696d617279507265446967657374000100385365636f6e64617279506c61696e0400b907015c5365636f6e64617279506c61696e507265446967657374000200305365636f6e646172795652460400bd0701545365636f6e6461727956524650726544696765737400030000b1070c4473705f636f6e73656e7375735f626162651c64696765737473405072696d61727950726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74d9020110536c6f740001347672665f7369676e6174757265b50701305672665369676e61747572650000b507101c73705f636f72651c737232353531390c767266305672665369676e617475726500000801287072655f6f75747075740401305672665072654f757470757400011470726f6f660503012056726650726f6f660000b9070c4473705f636f6e73656e7375735f626162651c646967657374735c5365636f6e64617279506c61696e507265446967657374000008013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74d9020110536c6f740000bd070c4473705f636f6e73656e7375735f626162651c64696765737473545365636f6e6461727956524650726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74d9020110536c6f740001347672665f7369676e6174757265b50701305672665369676e61747572650000c107084473705f636f6e73656e7375735f62616265584261626545706f6368436f6e66696775726174696f6e000008010463e5020128287536342c2075363429000134616c6c6f7765645f736c6f7473e9020130416c6c6f776564536c6f74730000c5070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013901045300000400590201185665633c543e0000c9070c2c70616c6c65745f626162651870616c6c6574144572726f7204045400011060496e76616c696445717569766f636174696f6e50726f6f660000043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c69644b65794f776e65727368697050726f6f66000104310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400020415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e50496e76616c6964436f6e66696775726174696f6e0003048c5375626d697474656420636f6e66696775726174696f6e20697320696e76616c69642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ecd07083870616c6c65745f6772616e6470612c53746f726564537461746504044e01300110104c6976650000003050656e64696e6750617573650801307363686564756c65645f61743001044e00011464656c61793001044e000100185061757365640002003450656e64696e67526573756d650801307363686564756c65645f61743001044e00011464656c61793001044e00030000d107083870616c6c65745f6772616e6470614c53746f72656450656e64696e674368616e676508044e0130144c696d697400001001307363686564756c65645f61743001044e00011464656c61793001044e0001406e6578745f617574686f726974696573d507016c426f756e646564417574686f726974794c6973743c4c696d69743e000118666f72636564790401244f7074696f6e3c4e3e0000d5070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401a4045300000400a001185665633c543e0000d9070c3870616c6c65745f6772616e6470611870616c6c6574144572726f7204045400011c2c50617573654661696c65640000080501417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665a42865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e30526573756d654661696c65640001081101417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e277420706175736564a028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e344368616e676550656e64696e67000204e8417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e1c546f6f536f6f6e000304bc43616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e60496e76616c69644b65794f776e65727368697050726f6f66000404310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c696445717569766f636174696f6e50726f6f660005043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400060415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742edd070000040c00182000e1070c3870616c6c65745f696e64696365731870616c6c6574144572726f720404540001142c4e6f7441737369676e65640000048c54686520696e64657820776173206e6f7420616c72656164792061737369676e65642e204e6f744f776e6572000104a454686520696e6465782069732061737369676e656420746f20616e6f74686572206163636f756e742e14496e5573650002047054686520696e64657820776173206e6f7420617661696c61626c652e2c4e6f745472616e73666572000304c854686520736f7572636520616e642064657374696e6174696f6e206163636f756e747320617265206964656e746963616c2e245065726d616e656e74000404d054686520696e646578206973207065726d616e656e7420616e64206d6179206e6f742062652066726565642f6368616e6765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee5070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e907045300000400ed0701185665633c543e0000e9070000040c1025030000ed07000002e90700f1070000040855041800f5070c4070616c6c65745f64656d6f6372616379147479706573385265666572656e64756d496e666f0c2c426c6f636b4e756d62657201302050726f706f73616c0125031c42616c616e6365011801081c4f6e676f696e670400f90701c05265666572656e64756d5374617475733c426c6f636b4e756d6265722c2050726f706f73616c2c2042616c616e63653e0000002046696e6973686564080120617070726f766564200110626f6f6c00010c656e6430012c426c6f636b4e756d62657200010000f9070c4070616c6c65745f64656d6f6372616379147479706573405265666572656e64756d5374617475730c2c426c6f636b4e756d62657201302050726f706f73616c0125031c42616c616e636501180014010c656e6430012c426c6f636b4e756d62657200012070726f706f73616c2503012050726f706f73616c0001247468726573686f6c64b40134566f74655468726573686f6c6400011464656c617930012c426c6f636b4e756d62657200011474616c6c79fd07013854616c6c793c42616c616e63653e0000fd070c4070616c6c65745f64656d6f63726163791474797065731454616c6c79041c42616c616e63650118000c01106179657318011c42616c616e63650001106e61797318011c42616c616e636500011c7475726e6f757418011c42616c616e6365000001080c4070616c6c65745f64656d6f637261637910766f746518566f74696e67101c42616c616e63650118244163636f756e74496401002c426c6f636b4e756d6265720130204d6178566f746573000108184469726563740c0114766f746573050801f4426f756e6465645665633c285265666572656e64756d496e6465782c204163636f756e74566f74653c42616c616e63653e292c204d6178566f7465733e00012c64656c65676174696f6e731108015044656c65676174696f6e733c42616c616e63653e0001147072696f721508017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0000002844656c65676174696e6714011c62616c616e636518011c42616c616e63650001187461726765740001244163636f756e744964000128636f6e76696374696f6e31030128436f6e76696374696f6e00012c64656c65676174696f6e731108015044656c65676174696f6e733c42616c616e63653e0001147072696f721508017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0001000005080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540109080453000004000d0801185665633c543e000009080000040810b8000d0800000209080011080c4070616c6c65745f64656d6f63726163791474797065732c44656c65676174696f6e73041c42616c616e6365011800080114766f74657318011c42616c616e636500011c6361706974616c18011c42616c616e6365000015080c4070616c6c65745f64656d6f637261637910766f7465245072696f724c6f636b082c426c6f636b4e756d62657201301c42616c616e6365011800080030012c426c6f636b4e756d626572000018011c42616c616e636500001908000004082503b4001d08000004083055040021080c4070616c6c65745f64656d6f63726163791870616c6c6574144572726f720404540001602056616c75654c6f770000043456616c756520746f6f206c6f773c50726f706f73616c4d697373696e670001045c50726f706f73616c20646f6573206e6f742065786973743c416c726561647943616e63656c65640002049443616e6e6f742063616e63656c207468652073616d652070726f706f73616c207477696365444475706c696361746550726f706f73616c0003045450726f706f73616c20616c7265616479206d6164654c50726f706f73616c426c61636b6c69737465640004046850726f706f73616c207374696c6c20626c61636b6c6973746564444e6f7453696d706c654d616a6f72697479000504a84e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792c496e76616c69644861736800060430496e76616c69642068617368284e6f50726f706f73616c000704504e6f2065787465726e616c2070726f706f73616c34416c72656164795665746f6564000804984964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365445265666572656e64756d496e76616c696400090484566f746520676976656e20666f7220696e76616c6964207265666572656e64756d2c4e6f6e6557616974696e67000a04504e6f2070726f706f73616c732077616974696e67204e6f74566f746572000b04c454686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e304e6f5065726d697373696f6e000c04c8546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e44416c726561647944656c65676174696e67000d0488546865206163636f756e7420697320616c72656164792064656c65676174696e672e44496e73756666696369656e7446756e6473000e04fc546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e344e6f7444656c65676174696e67000f04a0546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e28566f74657345786973740010085501546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696ce87468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e44496e7374616e744e6f74416c6c6f776564001104d854686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e204e6f6e73656e73650012049444656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e3c57726f6e675570706572426f756e6400130450496e76616c696420757070657220626f756e642e3c4d6178566f74657352656163686564001404804d6178696d756d206e756d626572206f6620766f74657320726561636865642e1c546f6f4d616e79001504804d6178696d756d206e756d626572206f66206974656d7320726561636865642e3c566f74696e67506572696f644c6f7700160454566f74696e6720706572696f6420746f6f206c6f7740507265696d6167654e6f7445786973740017047054686520707265696d61676520646f6573206e6f742065786973742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e25080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00002908084470616c6c65745f636f6c6c65637469766514566f74657308244163636f756e74496401002c426c6f636b4e756d626572013000140114696e64657810013450726f706f73616c496e6465780001247468726573686f6c6410012c4d656d626572436f756e7400011061796573390201385665633c4163636f756e7449643e0001106e617973390201385665633c4163636f756e7449643e00010c656e6430012c426c6f636b4e756d62657200002d080c4470616c6c65745f636f6c6c6563746976651870616c6c6574144572726f7208045400044900012c244e6f744d656d6265720000045c4163636f756e74206973206e6f742061206d656d626572444475706c696361746550726f706f73616c0001047c4475706c69636174652070726f706f73616c73206e6f7420616c6c6f7765643c50726f706f73616c4d697373696e670002044c50726f706f73616c206d7573742065786973742857726f6e67496e646578000304404d69736d61746368656420696e646578344475706c6963617465566f7465000404584475706c696361746520766f74652069676e6f72656448416c7265616479496e697469616c697a6564000504804d656d626572732061726520616c726561647920696e697469616c697a65642120546f6f4561726c79000604010154686520636c6f73652063616c6c20776173206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e40546f6f4d616e7950726f706f73616c73000704fc54686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e4c57726f6e6750726f706f73616c576569676874000804d054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e4c57726f6e6750726f706f73616c4c656e677468000904d054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e545072696d654163636f756e744e6f744d656d626572000a04745072696d65206163636f756e74206973206e6f742061206d656d626572048054686520604572726f726020656e756d206f6620746869732070616c6c65742e31080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014503045300000400350801185665633c543e000035080000024503003908083870616c6c65745f76657374696e672052656c6561736573000108085630000000085631000100003d080c3870616c6c65745f76657374696e671870616c6c6574144572726f72040454000114284e6f7456657374696e6700000484546865206163636f756e7420676976656e206973206e6f742076657374696e672e5441744d617856657374696e675363686564756c65730001082501546865206163636f756e7420616c72656164792068617320604d617856657374696e675363686564756c65736020636f756e74206f66207363686564756c657320616e642074687573510163616e6e6f742061646420616e6f74686572206f6e652e20436f6e7369646572206d657267696e67206578697374696e67207363686564756c657320696e206f7264657220746f2061646420616e6f746865722e24416d6f756e744c6f770002040501416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e605363686564756c65496e6465784f75744f66426f756e6473000304d0416e20696e64657820776173206f7574206f6620626f756e6473206f66207468652076657374696e67207363686564756c65732e54496e76616c69645363686564756c65506172616d730004040d014661696c656420746f206372656174652061206e6577207363686564756c65206265636175736520736f6d6520706172616d657465722077617320696e76616c69642e04744572726f7220666f72207468652076657374696e672070616c6c65742e41080000024508004508086470616c6c65745f656c656374696f6e735f70687261676d656e2853656174486f6c64657208244163636f756e74496401001c42616c616e63650118000c010c77686f0001244163636f756e7449640001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e636500004908086470616c6c65745f656c656374696f6e735f70687261676d656e14566f74657208244163636f756e74496401001c42616c616e63650118000c0114766f746573390201385665633c4163636f756e7449643e0001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e636500004d080c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144572726f7204045400014430556e61626c65546f566f7465000004c043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e1c4e6f566f746573000104944d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e30546f6f4d616e79566f7465730002048443616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e504d6178696d756d566f74657345786365656465640003049843616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e284c6f7742616c616e6365000404c443616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e3c556e61626c65546f506179426f6e6400050478566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2c4d7573744265566f746572000604404d757374206265206120766f7465722e4c4475706c69636174656443616e646964617465000704804475706c6963617465642063616e646964617465207375626d697373696f6e2e44546f6f4d616e7943616e6469646174657300080498546f6f206d616e792063616e646964617465732068617665206265656e20637265617465642e304d656d6265725375626d6974000904884d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e3852756e6e657255705375626d6974000a048852756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e68496e73756666696369656e7443616e64696461746546756e6473000b049443616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e244e6f744d656d626572000c04344e6f742061206d656d6265722e48496e76616c69645769746e65737344617461000d04e05468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e40496e76616c6964566f7465436f756e74000e04cc5468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e44496e76616c696452656e6f756e63696e67000f04fc5468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e48496e76616c69645265706c6163656d656e74001004fc50726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e5108089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365345265616479536f6c7574696f6e08244163636f756e74496400284d617857696e6e65727300000c0120737570706f72747355080198426f756e646564537570706f7274733c4163636f756e7449642c204d617857696e6e6572733e00011473636f7265e00134456c656374696f6e53636f726500011c636f6d70757465dc013c456c656374696f6e436f6d70757465000055080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540131040453000004002d0401185665633c543e00005908089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736534526f756e64536e617073686f7408244163636f756e7449640100304461746150726f7669646572015d0800080118766f74657273650801445665633c4461746150726f76696465723e00011c74617267657473390201385665633c4163636f756e7449643e00005d080000040c003061080061080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400390201185665633c543e000065080000025d080069080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016d08045300000400710801185665633c543e00006d080000040ce030100071080000026d080075080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365187369676e6564405369676e65645375626d697373696f6e0c244163636f756e74496401001c42616c616e6365011820536f6c7574696f6e0159030010010c77686f0001244163636f756e74496400011c6465706f73697418011c42616c616e63650001307261775f736f6c7574696f6e55030154526177536f6c7574696f6e3c536f6c7574696f6e3e00012063616c6c5f66656518011c42616c616e6365000079080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144572726f7204045400013c6850726544697370617463684561726c795375626d697373696f6e000004645375626d697373696f6e2077617320746f6f206561726c792e6c507265446973706174636857726f6e6757696e6e6572436f756e740001048857726f6e67206e756d626572206f662077696e6e6572732070726573656e7465642e6450726544697370617463685765616b5375626d697373696f6e000204905375626d697373696f6e2077617320746f6f207765616b2c2073636f72652d776973652e3c5369676e6564517565756546756c6c0003044901546865207175657565207761732066756c6c2c20616e642074686520736f6c7574696f6e20776173206e6f7420626574746572207468616e20616e79206f6620746865206578697374696e67206f6e65732e585369676e656443616e6e6f745061794465706f73697400040494546865206f726967696e206661696c656420746f2070617920746865206465706f7369742e505369676e6564496e76616c69645769746e657373000504a05769746e657373206461746120746f20646973706174636861626c6520697320696e76616c69642e4c5369676e6564546f6f4d756368576569676874000604b8546865207369676e6564207375626d697373696f6e20636f6e73756d657320746f6f206d756368207765696768743c4f637743616c6c57726f6e67457261000704984f4357207375626d697474656420736f6c7574696f6e20666f722077726f6e6720726f756e645c4d697373696e67536e617073686f744d65746164617461000804a8536e617073686f74206d657461646174612073686f756c6420657869737420627574206469646e27742e58496e76616c69645375626d697373696f6e496e646578000904d06053656c663a3a696e736572745f7375626d697373696f6e602072657475726e656420616e20696e76616c696420696e6465782e3843616c6c4e6f74416c6c6f776564000a04985468652063616c6c206973206e6f7420616c6c6f776564206174207468697320706f696e742e3846616c6c6261636b4661696c6564000b044c5468652066616c6c6261636b206661696c65642c426f756e644e6f744d6574000c0448536f6d6520626f756e64206e6f74206d657438546f6f4d616e7957696e6e657273000d049c5375626d697474656420736f6c7574696f6e2068617320746f6f206d616e792077696e6e657273645072654469737061746368446966666572656e74526f756e64000e04b85375626d697373696f6e2077617320707265706172656420666f72206120646966666572656e7420726f756e642e040d014572726f72206f66207468652070616c6c657420746861742063616e2062652072657475726e656420696e20726573706f6e736520746f20646973706174636865732e7d08083870616c6c65745f7374616b696e67345374616b696e674c656467657204045400001401147374617368000130543a3a4163636f756e744964000114746f74616c6d01013042616c616e63654f663c543e0001186163746976656d01013042616c616e63654f663c543e000124756e6c6f636b696e67610401f0426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a4d6178556e6c6f636b696e674368756e6b733e0001586c65676163795f636c61696d65645f7265776172647381080194426f756e6465645665633c457261496e6465782c20543a3a486973746f727944657074683e000081080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400410401185665633c543e00008508083870616c6c65745f7374616b696e672c4e6f6d696e6174696f6e7304045400000c011c74617267657473610801b4426f756e6465645665633c543a3a4163636f756e7449642c204d61784e6f6d696e6174696f6e734f663c543e3e0001307375626d69747465645f696e100120457261496e64657800012873757070726573736564200110626f6f6c00008908083870616c6c65745f7374616b696e6734416374697665457261496e666f0000080114696e646578100120457261496e64657800011473746172747904012c4f7074696f6e3c7536343e00008d08000004081000009108082873705f7374616b696e675450616765644578706f737572654d65746164617461041c42616c616e6365011800100114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e636500013c6e6f6d696e61746f725f636f756e7410010c753332000128706167655f636f756e7410011050616765000095080000040c100010009908082873705f7374616b696e67304578706f737572655061676508244163636f756e74496401001c42616c616e6365011800080128706167655f746f74616c6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e00009d08083870616c6c65745f7374616b696e673c457261526577617264506f696e747304244163636f756e744964010000080114746f74616c10012c526577617264506f696e74000128696e646976696475616ca108018042547265654d61703c4163636f756e7449642c20526577617264506f696e743e0000a108042042547265654d617008044b010004560110000400a508000000a508000002a90800a90800000408001000ad08000002b10800b108083870616c6c65745f7374616b696e6738556e6170706c696564536c61736808244163636f756e74496401001c42616c616e636501180014012476616c696461746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f7274657273390201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000b508000002b90800b90800000408101000bd0800000408f41800c1080c3870616c6c65745f7374616b696e6720736c617368696e6734536c617368696e675370616e7300001001287370616e5f696e6465781001245370616e496e6465780001286c6173745f7374617274100120457261496e6465780001486c6173745f6e6f6e7a65726f5f736c617368100120457261496e6465780001147072696f72410401345665633c457261496e6465783e0000c5080c3870616c6c65745f7374616b696e6720736c617368696e67285370616e5265636f7264041c42616c616e636501180008011c736c617368656418011c42616c616e6365000120706169645f6f757418011c42616c616e63650000c908103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144572726f7204045400017c344e6f74436f6e74726f6c6c6572000004644e6f74206120636f6e74726f6c6c6572206163636f756e742e204e6f745374617368000104504e6f742061207374617368206163636f756e742e34416c7265616479426f6e64656400020460537461736820697320616c726561647920626f6e6465642e34416c726561647950616972656400030474436f6e74726f6c6c657220697320616c7265616479207061697265642e30456d7074795461726765747300040460546172676574732063616e6e6f7420626520656d7074792e384475706c6963617465496e646578000504404475706c696361746520696e6465782e44496e76616c6964536c617368496e64657800060484536c617368207265636f726420696e646578206f7574206f6620626f756e64732e40496e73756666696369656e74426f6e6400070c590143616e6e6f74206861766520612076616c696461746f72206f72206e6f6d696e61746f7220726f6c652c20776974682076616c7565206c657373207468616e20746865206d696e696d756d20646566696e65642062793d01676f7665726e616e6365202873656520604d696e56616c696461746f72426f6e646020616e6420604d696e4e6f6d696e61746f72426f6e6460292e20496620756e626f6e64696e67206973207468651501696e74656e74696f6e2c20606368696c6c6020666972737420746f2072656d6f7665206f6e65277320726f6c652061732076616c696461746f722f6e6f6d696e61746f722e304e6f4d6f72654368756e6b730008049043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e344e6f556e6c6f636b4368756e6b000904a043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e3046756e646564546172676574000a04c8417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e48496e76616c6964457261546f526577617264000b0458496e76616c69642065726120746f207265776172642e68496e76616c69644e756d6265724f664e6f6d696e6174696f6e73000c0478496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e484e6f74536f72746564416e64556e69717565000d04804974656d7320617265206e6f7420736f7274656420616e6420756e697175652e38416c7265616479436c61696d6564000e0409015265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e2c496e76616c696450616765000f04844e6f206e6f6d696e61746f7273206578697374206f6e207468697320706167652e54496e636f7272656374486973746f72794465707468001004c0496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e58496e636f7272656374536c617368696e675370616e73001104b0496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e2042616453746174650012043901496e7465726e616c20737461746520686173206265636f6d6520736f6d65686f7720636f7272757074656420616e6420746865206f7065726174696f6e2063616e6e6f7420636f6e74696e75652e38546f6f4d616e795461726765747300130494546f6f206d616e79206e6f6d696e6174696f6e207461726765747320737570706c6965642e244261645461726765740014043d0141206e6f6d696e6174696f6e207461726765742077617320737570706c69656420746861742077617320626c6f636b6564206f72206f7468657277697365206e6f7420612076616c696461746f722e4043616e6e6f744368696c6c4f74686572001504550154686520757365722068617320656e6f75676820626f6e6420616e6420746875732063616e6e6f74206265206368696c6c656420666f72636566756c6c7920627920616e2065787465726e616c20706572736f6e2e44546f6f4d616e794e6f6d696e61746f72730016084d0154686572652061726520746f6f206d616e79206e6f6d696e61746f727320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865207374616b696e67b473657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e44546f6f4d616e7956616c696461746f7273001708550154686572652061726520746f6f206d616e792076616c696461746f722063616e6469646174657320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865d47374616b696e672073657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e40436f6d6d697373696f6e546f6f4c6f77001804e0436f6d6d697373696f6e20697320746f6f206c6f772e204d757374206265206174206c6561737420604d696e436f6d6d697373696f6e602e2c426f756e644e6f744d657400190458536f6d6520626f756e64206973206e6f74206d65742e50436f6e74726f6c6c657244657072656361746564001a04010155736564207768656e20617474656d7074696e6720746f20757365206465707265636174656420636f6e74726f6c6c6572206163636f756e74206c6f6769632e4c43616e6e6f74526573746f72654c6564676572001b045843616e6e6f742072657365742061206c65646765722e6c52657761726444657374696e6174696f6e52657374726963746564001c04ac50726f7669646564207265776172642064657374696e6174696f6e206973206e6f7420616c6c6f7765642e384e6f74456e6f75676846756e6473001d049c4e6f7420656e6f7567682066756e647320617661696c61626c6520746f2077697468647261772e5c5669727475616c5374616b65724e6f74416c6c6f776564001e04a84f7065726174696f6e206e6f7420616c6c6f77656420666f72207669727475616c207374616b6572732e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ecd08000002d10800d1080000040800710400d50800000408d9083800d9080c1c73705f636f72651863727970746f244b65795479706549640000040048011c5b75383b20345d0000dd080c3870616c6c65745f73657373696f6e1870616c6c6574144572726f7204045400011430496e76616c696450726f6f6600000460496e76616c6964206f776e6572736869702070726f6f662e5c4e6f4173736f63696174656456616c696461746f7249640001049c4e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e344475706c6963617465644b65790002046452656769737465726564206475706c6963617465206b65792e184e6f4b657973000304a44e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e244e6f4163636f756e7400040419014b65792073657474696e67206163636f756e74206973206e6f74206c6976652c20736f206974277320696d706f737369626c6520746f206173736f6369617465206b6579732e04744572726f7220666f72207468652073657373696f6e2070616c6c65742ee10800000408341000e508083c70616c6c65745f74726561737572792050726f706f73616c08244163636f756e74496401001c42616c616e636501180010012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500012c62656e65666963696172790001244163636f756e744964000110626f6e6418011c42616c616e63650000e9080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400410401185665633c543e0000ed08083c70616c6c65745f74726561737572792c5370656e64537461747573142441737365744b696e64018430417373657442616c616e636501182c42656e656669636961727901002c426c6f636b4e756d6265720130245061796d656e74496401840018012861737365745f6b696e6484012441737365744b696e64000118616d6f756e74180130417373657442616c616e636500012c62656e656669636961727900012c42656e656669636961727900012876616c69645f66726f6d30012c426c6f636b4e756d6265720001246578706972655f617430012c426c6f636b4e756d626572000118737461747573f108015c5061796d656e7453746174653c5061796d656e7449643e0000f108083c70616c6c65745f7472656173757279305061796d656e745374617465040849640184010c1c50656e64696e6700000024417474656d7074656404010869648401084964000100184661696c656400020000f50808346672616d655f737570706f72742050616c6c6574496400000400a502011c5b75383b20385d0000f9080c3c70616c6c65745f74726561737572791870616c6c6574144572726f7208045400044900012c30496e76616c6964496e646578000004ac4e6f2070726f706f73616c2c20626f756e7479206f72207370656e64206174207468617420696e6465782e40546f6f4d616e79417070726f76616c7300010480546f6f206d616e7920617070726f76616c7320696e207468652071756575652e58496e73756666696369656e745065726d697373696f6e0002084501546865207370656e64206f726967696e2069732076616c6964206275742074686520616d6f756e7420697420697320616c6c6f77656420746f207370656e64206973206c6f776572207468616e207468654c616d6f756e7420746f206265207370656e742e4c50726f706f73616c4e6f74417070726f7665640003047c50726f706f73616c20686173206e6f74206265656e20617070726f7665642e584661696c6564546f436f6e7665727442616c616e636500040451015468652062616c616e6365206f6620746865206173736574206b696e64206973206e6f7420636f6e7665727469626c6520746f207468652062616c616e6365206f6620746865206e61746976652061737365742e305370656e6445787069726564000504b0546865207370656e6420686173206578706972656420616e642063616e6e6f7420626520636c61696d65642e2c4561726c795061796f7574000604a4546865207370656e64206973206e6f742079657420656c696769626c6520666f72207061796f75742e40416c7265616479417474656d707465640007049c546865207061796d656e742068617320616c7265616479206265656e20617474656d707465642e2c5061796f75744572726f72000804cc54686572652077617320736f6d65206973737565207769746820746865206d656368616e69736d206f66207061796d656e742e304e6f74417474656d70746564000904a4546865207061796f757420776173206e6f742079657420617474656d707465642f636c61696d65642e30496e636f6e636c7573697665000a04c4546865207061796d656e7420686173206e656974686572206661696c6564206e6f7220737563636565646564207965742e04784572726f7220666f72207468652074726561737572792070616c6c65742efd08083c70616c6c65745f626f756e7469657318426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d62657201300018012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000110626f6e6418011c42616c616e636500011873746174757301090190426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00000109083c70616c6c65745f626f756e7469657330426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001182050726f706f73656400000020417070726f7665640001001846756e6465640002003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640003001841637469766508011c63757261746f720001244163636f756e7449640001287570646174655f64756530012c426c6f636b4e756d6265720004003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d6265720005000005090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000009090c3c70616c6c65745f626f756e746965731870616c6c6574144572726f7208045400044900012c70496e73756666696369656e7450726f706f7365727342616c616e63650000047850726f706f73657227732062616c616e636520697320746f6f206c6f772e30496e76616c6964496e646578000104904e6f2070726f706f73616c206f7220626f756e7479206174207468617420696e6465782e30526561736f6e546f6f4269670002048454686520726561736f6e20676976656e206973206a75737420746f6f206269672e40556e65787065637465645374617475730003048054686520626f756e74792073746174757320697320756e65787065637465642e385265717569726543757261746f720004045c5265717569726520626f756e74792063757261746f722e30496e76616c696456616c756500050454496e76616c696420626f756e74792076616c75652e28496e76616c69644665650006044c496e76616c696420626f756e7479206665652e3450656e64696e675061796f75740007086c4120626f756e7479207061796f75742069732070656e64696e672ef8546f2063616e63656c2074686520626f756e74792c20796f75206d75737420756e61737369676e20616e6420736c617368207468652063757261746f722e245072656d6174757265000804450154686520626f756e746965732063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e504861734163746976654368696c64426f756e7479000904050154686520626f756e74792063616e6e6f7420626520636c6f73656420626563617573652069742068617320616374697665206368696c6420626f756e746965732e34546f6f4d616e79517565756564000a0498546f6f206d616e7920617070726f76616c732061726520616c7265616479207175657565642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e0d09085470616c6c65745f6368696c645f626f756e746965732c4368696c64426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d626572013000140134706172656e745f626f756e747910012c426f756e7479496e64657800011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000118737461747573110901a44368696c64426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00001109085470616c6c65745f6368696c645f626f756e74696573444368696c64426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001101441646465640000003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640001001841637469766504011c63757261746f720001244163636f756e7449640002003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d6265720003000015090c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144572726f7204045400010c54506172656e74426f756e74794e6f74416374697665000004a454686520706172656e7420626f756e7479206973206e6f7420696e206163746976652073746174652e64496e73756666696369656e74426f756e747942616c616e6365000104e454686520626f756e74792062616c616e6365206973206e6f7420656e6f75676820746f20616464206e6577206368696c642d626f756e74792e50546f6f4d616e794368696c64426f756e746965730002040d014e756d626572206f66206368696c6420626f756e746965732065786365656473206c696d697420604d61784163746976654368696c64426f756e7479436f756e74602e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e19090c4070616c6c65745f626167735f6c697374106c697374104e6f646508045400044900001401086964000130543a3a4163636f756e744964000110707265768801504f7074696f6e3c543a3a4163636f756e7449643e0001106e6578748801504f7074696f6e3c543a3a4163636f756e7449643e0001246261675f7570706572300120543a3a53636f726500011473636f7265300120543a3a53636f726500001d090c4070616c6c65745f626167735f6c697374106c6973740c4261670804540004490000080110686561648801504f7074696f6e3c543a3a4163636f756e7449643e0001107461696c8801504f7074696f6e3c543a3a4163636f756e7449643e000021090c4070616c6c65745f626167735f6c6973741870616c6c6574144572726f72080454000449000104104c6973740400250901244c6973744572726f72000004b441206572726f7220696e20746865206c69737420696e7465726661636520696d706c656d656e746174696f6e2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e25090c4070616c6c65745f626167735f6c697374106c697374244c6973744572726f72000110244475706c6963617465000000284e6f7448656176696572000100304e6f74496e53616d65426167000200304e6f64654e6f74466f756e64000300002909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328506f6f6c4d656d626572040454000010011c706f6f6c5f6964100118506f6f6c4964000118706f696e747318013042616c616e63654f663c543e0001706c6173745f7265636f726465645f7265776172645f636f756e7465728d070140543a3a526577617264436f756e746572000138756e626f6e64696e675f657261732d0901e0426f756e64656442547265654d61703c457261496e6465782c2042616c616e63654f663c543e2c20543a3a4d6178556e626f6e64696e673e00002d090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601180453000004003109013842547265654d61703c4b2c20563e00003109042042547265654d617008044b011004560118000400350900000035090000023909003909000004081018003d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c426f6e646564506f6f6c496e6e65720404540000140128636f6d6d697373696f6e41090134436f6d6d697373696f6e3c543e0001386d656d6265725f636f756e74657210010c753332000118706f696e747318013042616c616e63654f663c543e000114726f6c65734d09015c506f6f6c526f6c65733c543a3a4163636f756e7449643e00011473746174651d010124506f6f6c537461746500004109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784509013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f72617465490901bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d790401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e0000450904184f7074696f6e04045401f40108104e6f6e6500000010536f6d650400f40000010000490904184f7074696f6e0404540129010108104e6f6e6500000010536f6d650400290100000100004d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e00005109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e7465728d070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e00005509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320537562506f6f6c7304045400000801186e6f5f65726159090134556e626f6e64506f6f6c3c543e000120776974685f6572615d09010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e00005909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e00005d090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b011004560159090453000004006109013842547265654d61703c4b2c20563e00006109042042547265654d617008044b0110045601590900040065090000006509000002690900690900000408105909006d090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144572726f7204045400019030506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e644163636f756e7442656c6f6e6773546f4f74686572506f6f6c0004084d01416e206163636f756e7420697320616c72656164792064656c65676174696e6720696e20616e6f7468657220706f6f6c2e20416e206163636f756e74206d6179206f6e6c792062656c6f6e6720746f206f6e653c706f6f6c20617420612074696d652e3846756c6c79556e626f6e64696e670005083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740006040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790007044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000814290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0009042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e67000a085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000b04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000c043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000d047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000e04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000f049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e676553746174650010048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001104b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001204ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e73697665040071090138446566656e736976654572726f720013083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001404bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640015041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001604ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001704e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400180409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640019040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001a04a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001b048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001c0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001d049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001e04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001f04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e384e6f7468696e67546f536c617368002004cc4e6f20736c6173682070656e64696e6720746861742063616e206265206170706c69656420746f20746865206d656d6265722e3c416c72656164794d69677261746564002104150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e2068617320616c7265616479206d6967726174656420746f2064656c6567617465207374616b652e2c4e6f744d69677261746564002204150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e20686173206e6f74206d696772617465642079657420746f2064656c6567617465207374616b652e304e6f74537570706f72746564002304f0546869732063616c6c206973206e6f7420616c6c6f77656420696e207468652063757272656e74207374617465206f66207468652070616c6c65742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e71090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657438446566656e736976654572726f7200011c684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c790004005444656c65676174696f6e556e737570706f727465640005003c536c6173684e6f744170706c6965640006000075090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017909045300000400810901185665633c543e0000790904184f7074696f6e040454017d090108104e6f6e6500000010536f6d6504007d0900000100007d09084070616c6c65745f7363686564756c6572245363686564756c656414104e616d6501041043616c6c0125032c426c6f636b4e756d62657201303450616c6c6574734f726967696e016d05244163636f756e7449640100001401206d617962655f69643d0101304f7074696f6e3c4e616d653e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6c2503011043616c6c0001386d617962655f706572696f646963a90401944f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d6265723e3e0001186f726967696e6d05013450616c6c6574734f726967696e000081090000027909008509084070616c6c65745f7363686564756c65722c5265747279436f6e6669670418506572696f640130000c0134746f74616c5f72657472696573080108753800012472656d61696e696e670801087538000118706572696f64300118506572696f64000089090c4070616c6c65745f7363686564756c65721870616c6c6574144572726f72040454000114404661696c6564546f5363686564756c65000004644661696c656420746f207363686564756c6520612063616c6c204e6f74466f756e640001047c43616e6e6f742066696e6420746865207363686564756c65642063616c6c2e5c546172676574426c6f636b4e756d626572496e50617374000204a4476976656e2074617267657420626c6f636b206e756d62657220697320696e2074686520706173742e4852657363686564756c654e6f4368616e6765000304f052657363686564756c65206661696c6564206265636175736520697420646f6573206e6f74206368616e6765207363686564756c65642074696d652e144e616d6564000404d0417474656d707420746f207573652061206e6f6e2d6e616d65642066756e6374696f6e206f6e2061206e616d6564207461736b2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e8d09083c70616c6c65745f707265696d616765404f6c645265717565737453746174757308244163636f756e74496401001c42616c616e6365011801082c556e72657175657374656408011c6465706f736974d40150284163636f756e7449642c2042616c616e63652900010c6c656e10010c753332000000245265717565737465640c011c6465706f736974910901704f7074696f6e3c284163636f756e7449642c2042616c616e6365293e000114636f756e7410010c75333200010c6c656e3503012c4f7074696f6e3c7533323e00010000910904184f7074696f6e04045401d40108104e6f6e6500000010536f6d650400d400000100009509083c70616c6c65745f707265696d616765345265717565737453746174757308244163636f756e7449640100185469636b6574018401082c556e7265717565737465640801187469636b65749909014c284163636f756e7449642c205469636b65742900010c6c656e10010c753332000000245265717565737465640c01306d617962655f7469636b65749d09016c4f7074696f6e3c284163636f756e7449642c205469636b6574293e000114636f756e7410010c7533320001246d617962655f6c656e3503012c4f7074696f6e3c7533323e000100009909000004080084009d0904184f7074696f6e0404540199090108104e6f6e6500000010536f6d65040099090000010000a1090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000a5090c3c70616c6c65745f707265696d6167651870616c6c6574144572726f7204045400012418546f6f426967000004a0507265696d61676520697320746f6f206c6172676520746f2073746f7265206f6e2d636861696e2e30416c72656164794e6f746564000104a4507265696d6167652068617320616c7265616479206265656e206e6f746564206f6e2d636861696e2e344e6f74417574686f72697a6564000204c85468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e2e204e6f744e6f746564000304fc54686520707265696d6167652063616e6e6f742062652072656d6f7665642073696e636520697420686173206e6f7420796574206265656e206e6f7465642e2452657175657374656400040409014120707265696d616765206d6179206e6f742062652072656d6f766564207768656e20746865726520617265206f75747374616e64696e672072657175657374732e304e6f745265717565737465640005042d0154686520707265696d61676520726571756573742063616e6e6f742062652072656d6f7665642073696e6365206e6f206f75747374616e64696e672072657175657374732065786973742e1c546f6f4d616e7900060455014d6f7265207468616e20604d41585f484153485f555047524144455f42554c4b5f434f554e54602068617368657320776572652072657175657374656420746f206265207570677261646564206174206f6e63652e18546f6f466577000704e4546f6f206665772068617368657320776572652072657175657374656420746f2062652075706772616465642028692e652e207a65726f292e184e6f436f737400080459014e6f207469636b65742077697468206120636f7374207761732072657475726e6564206279205b60436f6e6669673a3a436f6e73696465726174696f6e605d20746f2073746f72652074686520707265696d6167652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ea9090c2873705f7374616b696e671c6f6666656e6365384f6666656e636544657461696c7308205265706f727465720100204f6666656e646572016501000801206f6666656e646572650101204f6666656e6465720001247265706f7274657273390201345665633c5265706f727465723e0000ad090000040849013800b1090c3c70616c6c65745f74785f70617573651870616c6c6574144572726f720404540001102049735061757365640000044c5468652063616c6c206973207061757365642e284973556e706175736564000104545468652063616c6c20697320756e7061757365642e28556e7061757361626c65000204b45468652063616c6c2069732077686974656c697374656420616e642063616e6e6f74206265207061757365642e204e6f74466f756e64000300048054686520604572726f726020656e756d206f6620746869732070616c6c65742eb5090c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454015d01045300000400b90901185665633c543e0000b9090000025d0100bd090c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144572726f7204045400010828496e76616c69644b6579000004604e6f6e206578697374656e74207075626c6963206b65792e4c4475706c696361746564486561727462656174000104544475706c696361746564206865617274626561742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ec10900000408c509d50900c5090c3c70616c6c65745f6964656e7469747914747970657330526567697374726174696f6e0c1c42616c616e63650118344d61784a756467656d656e747300304964656e74697479496e666f01c504000c01286a756467656d656e7473c90901fc426f756e6465645665633c28526567697374726172496e6465782c204a756467656d656e743c42616c616e63653e292c204d61784a756467656d656e74733e00011c6465706f73697418011c42616c616e6365000110696e666fc50401304964656e74697479496e666f0000c9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401cd09045300000400d10901185665633c543e0000cd090000040810550500d109000002cd0900d50904184f7074696f6e040454017d010108104e6f6e6500000010536f6d6504007d010000010000d9090000040818dd0900dd090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400390201185665633c543e0000e1090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e509045300000400ed0901185665633c543e0000e50904184f7074696f6e04045401e9090108104e6f6e6500000010536f6d650400e9090000010000e9090c3c70616c6c65745f6964656e7469747914747970657334526567697374726172496e666f0c1c42616c616e63650118244163636f756e74496401001c49644669656c640130000c011c6163636f756e740001244163636f756e74496400010c66656518011c42616c616e63650001186669656c647330011c49644669656c640000ed09000002e50900f1090c3c70616c6c65745f6964656e746974791474797065734c417574686f7269747950726f70657274696573041853756666697801f50900080118737566666978f5090118537566666978000128616c6c6f636174696f6e100128416c6c6f636174696f6e0000f5090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000f90900000408003000fd090c3c70616c6c65745f6964656e746974791870616c6c6574144572726f7204045400016848546f6f4d616e795375624163636f756e74730000045c546f6f206d616e7920737562732d6163636f756e74732e204e6f74466f756e64000104504163636f756e742069736e277420666f756e642e204e6f744e616d6564000204504163636f756e742069736e2774206e616d65642e28456d707479496e64657800030430456d70747920696e6465782e284665654368616e6765640004043c466565206973206368616e6765642e284e6f4964656e74697479000504484e6f206964656e7469747920666f756e642e3c537469636b794a756467656d656e7400060444537469636b79206a756467656d656e742e384a756467656d656e74476976656e000704404a756467656d656e7420676976656e2e40496e76616c69644a756467656d656e7400080448496e76616c6964206a756467656d656e742e30496e76616c6964496e6465780009045454686520696e64657820697320696e76616c69642e34496e76616c6964546172676574000a04585468652074617267657420697320696e76616c69642e44546f6f4d616e7952656769737472617273000b04e84d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e38416c7265616479436c61696d6564000c04704163636f756e7420494420697320616c7265616479206e616d65642e184e6f74537562000d047053656e646572206973206e6f742061207375622d6163636f756e742e204e6f744f776e6564000e04885375622d6163636f756e742069736e2774206f776e65642062792073656e6465722e744a756467656d656e74466f72446966666572656e744964656e74697479000f04d05468652070726f7669646564206a756467656d656e742077617320666f72206120646966666572656e74206964656e746974792e584a756467656d656e745061796d656e744661696c6564001004f84572726f722074686174206f6363757273207768656e20746865726520697320616e20697373756520706179696e6720666f72206a756467656d656e742e34496e76616c6964537566666978001104805468652070726f76696465642073756666697820697320746f6f206c6f6e672e504e6f74557365726e616d65417574686f72697479001204e05468652073656e64657220646f6573206e6f742068617665207065726d697373696f6e20746f206973737565206120757365726e616d652e304e6f416c6c6f636174696f6e001304c454686520617574686f726974792063616e6e6f7420616c6c6f6361746520616e79206d6f726520757365726e616d65732e40496e76616c69645369676e6174757265001404a8546865207369676e6174757265206f6e206120757365726e616d6520776173206e6f742076616c69642e4452657175697265735369676e6174757265001504090153657474696e67207468697320757365726e616d652072657175697265732061207369676e61747572652c20627574206e6f6e65207761732070726f76696465642e3c496e76616c6964557365726e616d65001604b054686520757365726e616d6520646f6573206e6f74206d6565742074686520726571756972656d656e74732e34557365726e616d6554616b656e0017047854686520757365726e616d6520697320616c72656164792074616b656e2e284e6f557365726e616d65001804985468652072657175657374656420757365726e616d6520646f6573206e6f742065786973742e284e6f74457870697265640019042d0154686520757365726e616d652063616e6e6f7420626520666f72636566756c6c792072656d6f76656420626563617573652069742063616e207374696c6c2062652061636365707465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e010a0c3870616c6c65745f7574696c6974791870616c6c6574144572726f7204045400010430546f6f4d616e7943616c6c730000045c546f6f206d616e792063616c6c7320626174636865642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e050a00000408000400090a083c70616c6c65745f6d756c7469736967204d756c7469736967102c426c6f636b4e756d62657201301c42616c616e63650118244163636f756e7449640100304d6178417070726f76616c7300001001107768656e8901015854696d65706f696e743c426c6f636b4e756d6265723e00011c6465706f73697418011c42616c616e63650001246465706f7369746f720001244163636f756e744964000124617070726f76616c735504018c426f756e6465645665633c4163636f756e7449642c204d6178417070726f76616c733e00000d0a0c3c70616c6c65745f6d756c74697369671870616c6c6574144572726f72040454000138404d696e696d756d5468726573686f6c640000047c5468726573686f6c64206d7573742062652032206f7220677265617465722e3c416c7265616479417070726f766564000104ac43616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e444e6f417070726f76616c734e65656465640002049c43616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e44546f6f4665775369676e61746f72696573000304a854686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e48546f6f4d616e795369676e61746f72696573000404ac54686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e545369676e61746f726965734f75744f664f726465720005040d01546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e4c53656e646572496e5369676e61746f726965730006040d015468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e204e6f74466f756e64000704dc4d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e204e6f744f776e65720008042d014f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e2c4e6f54696d65706f696e740009041d014e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e3857726f6e6754696d65706f696e74000a042d014120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e4c556e657870656374656454696d65706f696e74000b04f4412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e3c4d6178576569676874546f6f4c6f77000c04d0546865206d6178696d756d2077656967687420696e666f726d6174696f6e2070726f76696465642077617320746f6f206c6f772e34416c726561647953746f726564000d04a0546865206461746120746f2062652073746f72656420697320616c72656164792073746f7265642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e110a000002150a00150a0000040c8905190a2d0a00190a081866705f727063445472616e73616374696f6e53746174757300001c01407472616e73616374696f6e5f68617368340110483235360001447472616e73616374696f6e5f696e64657810010c75333200011066726f6d9101011c41646472657373000108746f1d0a013c4f7074696f6e3c416464726573733e000140636f6e74726163745f616464726573731d0a013c4f7074696f6e3c416464726573733e0001106c6f6773210a01205665633c4c6f673e0001286c6f67735f626c6f6f6d250a0114426c6f6f6d00001d0a04184f7074696f6e0404540191010108104e6f6e6500000010536f6d65040091010000010000210a000002bd0100250a0820657468626c6f6f6d14426c6f6f6d00000400290a01405b75383b20424c4f4f4d5f53495a455d0000290a0000030001000008002d0a0c20657468657265756d1c726563656970742452656365697074563300010c184c65676163790400310a014445495036353852656365697074446174610000001c454950323933300400310a01484549503239333052656365697074446174610001001c454950313535390400310a014845495031353539526563656970744461746100020000310a0c20657468657265756d1c72656365697074444549503635385265636569707444617461000010012c7374617475735f636f64650801087538000120757365645f676173c9010110553235360001286c6f67735f626c6f6f6d250a0114426c6f6f6d0001106c6f6773210a01205665633c4c6f673e0000350a0c20657468657265756d14626c6f636b14426c6f636b040454018905000c0118686561646572390a01184865616465720001307472616e73616374696f6e73410a01185665633c543e0001186f6d6d657273450a012c5665633c4865616465723e0000390a0c20657468657265756d186865616465721848656164657200003c012c706172656e745f686173683401104832353600012c6f6d6d6572735f686173683401104832353600012c62656e6566696369617279910101104831363000012873746174655f726f6f74340110483235360001447472616e73616374696f6e735f726f6f743401104832353600013472656365697074735f726f6f74340110483235360001286c6f67735f626c6f6f6d250a0114426c6f6f6d000128646966666963756c7479c9010110553235360001186e756d626572c9010110553235360001246761735f6c696d6974c9010110553235360001206761735f75736564c90101105532353600012474696d657374616d7030010c75363400012865787472615f6461746138011442797465730001206d69785f68617368340110483235360001146e6f6e63653d0a010c48363400003d0a0c38657468657265756d5f747970657310686173680c48363400000400a502011c5b75383b20385d0000410a000002890500450a000002390a00490a0000022d0a004d0a000002190a00510a0c3c70616c6c65745f657468657265756d1870616c6c6574144572726f7204045400010840496e76616c69645369676e6174757265000004545369676e617475726520697320696e76616c69642e305072654c6f67457869737473000104d85072652d6c6f672069732070726573656e742c207468657265666f7265207472616e73616374206973206e6f7420616c6c6f7765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e550a082870616c6c65745f65766d30436f64654d65746164617461000008011073697a6530010c75363400011068617368340110483235360000590a00000408910134005d0a0c2870616c6c65745f65766d1870616c6c6574144572726f720404540001342842616c616e63654c6f77000004904e6f7420656e6f7567682062616c616e636520746f20706572666f726d20616374696f6e2c4665654f766572666c6f770001048043616c63756c6174696e6720746f74616c20666565206f766572666c6f7765643c5061796d656e744f766572666c6f770002049043616c63756c6174696e6720746f74616c207061796d656e74206f766572666c6f7765643857697468647261774661696c65640003044c576974686472617720666565206661696c6564384761735072696365546f6f4c6f770004045447617320707269636520697320746f6f206c6f772e30496e76616c69644e6f6e6365000504404e6f6e636520697320696e76616c6964384761734c696d6974546f6f4c6f7700060454476173206c696d697420697320746f6f206c6f772e3c4761734c696d6974546f6f4869676800070458476173206c696d697420697320746f6f20686967682e38496e76616c6964436861696e49640008046054686520636861696e20696420697320696e76616c69642e40496e76616c69645369676e617475726500090464746865207369676e617475726520697320696e76616c69642e285265656e7472616e6379000a043845564d207265656e7472616e6379685472616e73616374696f6e4d757374436f6d6546726f6d454f41000b04244549502d333630372c24556e646566696e6564000c0440556e646566696e6564206572726f722e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e610a0c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c6574144572726f720404540001045c4d617841646472657373436f756e744578636565646564000004784d6178696d756d206164647265737320636f756e74206578636565646564048054686520604572726f726020656e756d206f6620746869732070616c6c65742e650a0000040830d90100690a0c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144572726f7204045400012060496e76616c6964457468657265756d5369676e61747572650000046c496e76616c696420457468657265756d207369676e61747572652e58496e76616c69644e61746976655369676e617475726500010488496e76616c6964204e617469766520287372323535313929207369676e617475726550496e76616c69644e61746976654163636f756e740002047c496e76616c6964204e6174697665206163636f756e74206465636f64696e67405369676e65724861734e6f436c61696d00030478457468657265756d206164647265737320686173206e6f20636c61696d2e4053656e6465724861734e6f436c61696d000404b04163636f756e742049442073656e64696e67207472616e73616374696f6e20686173206e6f20636c61696d2e30506f74556e646572666c6f77000508490154686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061306c6f676963206572726f722e40496e76616c696453746174656d656e740006049041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e4c56657374656442616c616e6365457869737473000704a4546865206163636f756e7420616c7265616479206861732061207665737465642062616c616e63652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e6d0a00000408710a1800710a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401750a045300000400790a01185665633c543e0000750a083070616c6c65745f70726f78793c50726f7879446566696e6974696f6e0c244163636f756e74496401002450726f78795479706501e5012c426c6f636b4e756d6265720130000c012064656c65676174650001244163636f756e74496400012870726f78795f74797065e501012450726f78795479706500011464656c617930012c426c6f636b4e756d6265720000790a000002750a007d0a00000408810a1800810a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401850a045300000400890a01185665633c543e0000850a083070616c6c65745f70726f787930416e6e6f756e63656d656e740c244163636f756e7449640100104861736801342c426c6f636b4e756d6265720130000c01107265616c0001244163636f756e74496400012463616c6c5f686173683401104861736800011868656967687430012c426c6f636b4e756d6265720000890a000002850a008d0a0c3070616c6c65745f70726f78791870616c6c6574144572726f720404540001201c546f6f4d616e79000004210154686572652061726520746f6f206d616e792070726f786965732072656769737465726564206f7220746f6f206d616e7920616e6e6f756e63656d656e74732070656e64696e672e204e6f74466f756e640001047450726f787920726567697374726174696f6e206e6f7420666f756e642e204e6f7450726f7879000204cc53656e646572206973206e6f7420612070726f7879206f6620746865206163636f756e7420746f2062652070726f786965642e2c556e70726f787961626c650003042101412063616c6c20776869636820697320696e636f6d70617469626c652077697468207468652070726f7879207479706527732066696c7465722077617320617474656d707465642e244475706c69636174650004046c4163636f756e7420697320616c726561647920612070726f78792e304e6f5065726d697373696f6e000504150143616c6c206d6179206e6f74206265206d6164652062792070726f78792062656361757365206974206d617920657363616c617465206974732070726976696c656765732e2c556e616e6e6f756e636564000604d0416e6e6f756e63656d656e742c206966206d61646520617420616c6c2c20776173206d61646520746f6f20726563656e746c792e2c4e6f53656c6650726f78790007046443616e6e6f74206164642073656c662061732070726f78792e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e910a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f724d6574616461746114244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301950a344d6178426c75657072696e747301990a001801147374616b6518011c42616c616e636500014064656c65676174696f6e5f636f756e7410010c75333200011c726571756573749d0a01a04f7074696f6e3c4f70657261746f72426f6e644c657373526571756573743c42616c616e63653e3e00012c64656c65676174696f6e73a50a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e000118737461747573b10a01384f70657261746f72537461747573000134626c75657072696e745f696473b50a0178426f756e6465645665633c7533322c204d6178426c75657072696e74733e0000950a085874616e676c655f746573746e65745f72756e74696d65384d617844656c65676174696f6e7300000000990a085874616e676c655f746573746e65745f72756e74696d65544d61784f70657261746f72426c75657072696e7473000000009d0a04184f7074696f6e04045401a10a0108104e6f6e6500000010536f6d650400a10a0000010000a10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f725c4f70657261746f72426f6e644c65737352657175657374041c42616c616e6365011800080118616d6f756e7418011c42616c616e6365000130726571756573745f74696d65100128526f756e64496e6465780000a50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401a90a045300000400ad0a01185665633c543e0000a90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f723444656c656761746f72426f6e640c244163636f756e74496401001c42616c616e636501181c417373657449640118000c012464656c656761746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f696418011c417373657449640000ad0a000002a90a00b10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72384f70657261746f7253746174757300010c1841637469766500000020496e6163746976650001001c4c656176696e670400100128526f756e64496e64657800020000b50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400410401185665633c543e0000b90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f72536e617073686f7410244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301950a000801147374616b6518011c42616c616e636500012c64656c65676174696f6e73a50a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e0000bd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f724444656c656761746f724d657461646174611c244163636f756e74496401001c42616c616e636501181c4173736574496401184c4d61785769746864726177526571756573747301c10a384d617844656c65676174696f6e7301950a484d6178556e7374616b65526571756573747301c50a344d6178426c75657072696e7473010906001401206465706f73697473c90a016842547265654d61703c417373657449642c2042616c616e63653e00014477697468647261775f7265717565737473d50a010901426f756e6465645665633c5769746864726177526571756573743c417373657449642c2042616c616e63653e2c204d6178576974686472617752657175657374733e00012c64656c65676174696f6e73e10a016901426f756e6465645665633c426f6e64496e666f44656c656761746f723c4163636f756e7449642c2042616c616e63652c20417373657449642c204d6178426c75657072696e74733e0a2c204d617844656c65676174696f6e733e00016864656c656761746f725f756e7374616b655f7265717565737473ed0a016d01426f756e6465645665633c426f6e644c657373526571756573743c4163636f756e7449642c20417373657449642c2042616c616e63652c204d6178426c75657072696e74733e2c0a4d6178556e7374616b6552657175657374733e000118737461747573f90a013c44656c656761746f725374617475730000c10a085874616e676c655f746573746e65745f72756e74696d654c4d61785769746864726177526571756573747300000000c50a085874616e676c655f746573746e65745f72756e74696d65484d6178556e7374616b65526571756573747300000000c90a042042547265654d617008044b011804560118000400cd0a000000cd0a000002d10a00d10a00000408181800d50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d90a045300000400dd0a01185665633c543e0000d90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c576974686472617752657175657374081c4173736574496401181c42616c616e63650118000c012061737365745f696418011c41737365744964000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e6465780000dd0a000002d90a00e10a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e50a045300000400e90a01185665633c543e0000e50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f7244426f6e64496e666f44656c656761746f7210244163636f756e74496401001c42616c616e636501181c417373657449640118344d6178426c75657072696e7473010906001001206f70657261746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f696418011c4173736574496400014c626c75657072696e745f73656c656374696f6e050601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000e90a000002e50a00ed0a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401f10a045300000400f50a01185665633c543e0000f10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c426f6e644c6573735265717565737410244163636f756e74496401001c4173736574496401181c42616c616e63650118344d6178426c75657072696e7473010906001401206f70657261746f720001244163636f756e74496400012061737365745f696418011c41737365744964000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e64657800014c626c75657072696e745f73656c656374696f6e050601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000f50a000002f10a00f90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c44656c656761746f7253746174757300010818416374697665000000404c656176696e675363686564756c65640400100128526f756e64496e64657800010000fd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647330526577617264436f6e666967081c5661756c74496401181c42616c616e636501180008011c636f6e66696773010b01d442547265654d61703c5661756c7449642c20526577617264436f6e666967466f7241737365745661756c743c42616c616e63653e3e00016477686974656c69737465645f626c75657072696e745f696473410401205665633c7533323e0000010b042042547265654d617008044b0118045601050b000400090b000000050b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647364526577617264436f6e666967466f7241737365745661756c74041c42616c616e636501180008010c617079f101011c50657263656e7400010c63617018011c42616c616e63650000090b0000020d0b000d0b0000040818050b00110b0c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144572726f720404540001bc3c416c72656164794f70657261746f720000048c546865206163636f756e7420697320616c726561647920616e206f70657261746f722e28426f6e64546f6f4c6f7700010470546865207374616b6520616d6f756e7420697320746f6f206c6f772e344e6f74416e4f70657261746f720002047c546865206163636f756e74206973206e6f7420616e206f70657261746f722e2843616e6e6f744578697400030460546865206163636f756e742063616e6e6f7420657869742e38416c72656164794c656176696e6700040480546865206f70657261746f7220697320616c7265616479206c656176696e672e484e6f744c656176696e674f70657261746f72000504a8546865206163636f756e74206973206e6f74206c656176696e6720617320616e206f70657261746f722e3c4e6f744c656176696e67526f756e64000604cc54686520726f756e6420646f6573206e6f74206d6174636820746865207363686564756c6564206c6561766520726f756e642e584c656176696e67526f756e644e6f7452656163686564000704644c656176696e6720726f756e64206e6f7420726561636865644c4e6f5363686564756c6564426f6e644c657373000804985468657265206973206e6f207363686564756c656420756e7374616b6520726571756573742e6c426f6e644c657373526571756573744e6f745361746973666965640009049454686520756e7374616b652072657175657374206973206e6f74207361746973666965642e444e6f744163746976654f70657261746f72000a046c546865206f70657261746f72206973206e6f74206163746976652e484e6f744f66666c696e654f70657261746f72000b0470546865206f70657261746f72206973206e6f74206f66666c696e652e40416c726561647944656c656761746f72000c048c546865206163636f756e7420697320616c726561647920612064656c656761746f722e304e6f7444656c656761746f72000d047c546865206163636f756e74206973206e6f7420612064656c656761746f722e70576974686472617752657175657374416c7265616479457869737473000e048841207769746864726177207265717565737420616c7265616479206578697374732e4c496e73756666696369656e7442616c616e6365000f0494546865206163636f756e742068617320696e73756666696369656e742062616c616e63652e444e6f576974686472617752657175657374001004745468657265206973206e6f20776974686472617720726571756573742e444e6f426f6e644c65737352657175657374001104705468657265206973206e6f20756e7374616b6520726571756573742e40426f6e644c6573734e6f7452656164790012048454686520756e7374616b652072657175657374206973206e6f742072656164792e70426f6e644c65737352657175657374416c7265616479457869737473001304844120756e7374616b65207265717565737420616c7265616479206578697374732e6041637469766553657276696365735573696e674173736574001404a854686572652061726520616374697665207365727669636573207573696e67207468652061737365742e484e6f41637469766544656c65676174696f6e001504785468657265206973206e6f74206163746976652064656c65676174696f6e4c41737365744e6f7457686974656c697374656400160470546865206173736574206973206e6f742077686974656c6973746564344e6f74417574686f72697a6564001704cc546865206f726967696e206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e544d6178426c75657072696e74734578636565646564001804944d6178696d756d206e756d626572206f6620626c75657072696e74732065786365656465643441737365744e6f74466f756e6400190464546865206173736574204944206973206e6f7420666f756e646c426c75657072696e74416c726561647957686974656c6973746564001a049c54686520626c75657072696e7420494420697320616c72656164792077686974656c6973746564484e6f77697468647261775265717565737473001b04684e6f20776974686472617720726571756573747320666f756e64644e6f4d61746368696e67776974686472617752657175657374001c04884e6f206d61746368696e67207769746864726177207265716573747320666f756e644c4173736574416c7265616479496e5661756c74001d0498417373657420616c72656164792065786973747320696e206120726577617264207661756c743c41737365744e6f74496e5661756c74001e047c4173736574206e6f7420666f756e6420696e20726577617264207661756c74345661756c744e6f74466f756e64001f047c54686520726577617264207661756c7420646f6573206e6f74206578697374504475706c6963617465426c75657072696e74496400200415014572726f722072657475726e6564207768656e20747279696e6720746f20616464206120626c75657072696e74204944207468617420616c7265616479206578697374732e4c426c75657072696e7449644e6f74466f756e640021041d014572726f722072657475726e6564207768656e20747279696e6720746f2072656d6f7665206120626c75657072696e74204944207468617420646f65736e27742065786973742e384e6f74496e46697865644d6f64650022043d014572726f722072657475726e6564207768656e20747279696e6720746f206164642f72656d6f766520626c75657072696e7420494473207768696c65206e6f7420696e204669786564206d6f64652e584d617844656c65676174696f6e73457863656564656400230409014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662064656c65676174696f6e732069732065786365656465642e684d6178556e7374616b65526571756573747345786365656465640024041d014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f6620756e7374616b652072657175657374732069732065786365656465642e6c4d617857697468647261775265717565737473457863656564656400250421014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662077697468647261772072657175657374732069732065786365656465642e3c4465706f7369744f766572666c6f770026045c4465706f73697420616d6f756e74206f766572666c6f7754556e7374616b65416d6f756e74546f6f4c6172676500270444556e7374616b6520756e646572666c6f77345374616b654f766572666c6f770028046c4f766572666c6f77207768696c6520616464696e67207374616b6568496e73756666696369656e745374616b6552656d61696e696e6700290478556e646572666c6f77207768696c65207265647563696e67207374616b6544415059457863656564734d6178696d756d002a04b04150592065786365656473206d6178696d756d20616c6c6f776564206279207468652065787472696e7369633c43617043616e6e6f7442655a65726f002b04484361702063616e6e6f74206265207a65726f5443617045786365656473546f74616c537570706c79002c0484436170206578636565647320746f74616c20737570706c79206f662061737365746c50656e64696e67556e7374616b6552657175657374457869737473002d0494416e20756e7374616b65207265717565737420697320616c72656164792070656e64696e6750426c75657072696e744e6f7453656c6563746564002e047454686520626c75657072696e74206973206e6f742073656c656374656404744572726f727320656d6974746564206279207468652070616c6c65742e150b0000040800190600190b000004083000001d0b0c4474616e676c655f7072696d69746976657320736572766963657338536572766963655265717565737410044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273210b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e000118617373657473250b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d62657200011061726773290b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0001746f70657261746f72735f776974685f617070726f76616c5f73746174652d0b010501426f756e6465645665633c284163636f756e7449642c20417070726f76616c5374617465292c20433a3a4d61784f70657261746f7273506572536572766963653e0000210b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400390201185665633c543e0000250b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401180453000004003d0201185665633c543e0000290b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010d02045300000400090201185665633c543e00002d0b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401310b045300000400390b01185665633c543e0000310b0000040800350b00350b0c4474616e676c655f7072696d69746976657320736572766963657334417070726f76616c537461746500010c1c50656e64696e6700000020417070726f76656404014472657374616b696e675f70657263656e74f101011c50657263656e740001002052656a656374656400020000390b000002310b003d0b0c4474616e676c655f7072696d6974697665732073657276696365731c5365727669636510044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0108696430010c753634000124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273210b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e0001246f70657261746f7273410b01ec426f756e6465645665633c284163636f756e7449642c2050657263656e74292c20433a3a4d61784f70657261746f7273506572536572766963653e000118617373657473250b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d6265720000410b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401450b045300000400490b01185665633c543e0000450b0000040800f10100490b000002450b004d0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400510b012c42547265655365743c543e0000510b0420425472656553657404045401300004001106000000550b0c4474616e676c655f7072696d6974697665732073657276696365731c4a6f6243616c6c08044300244163636f756e7449640100000c0128736572766963655f696430010c75363400010c6a6f62080108753800011061726773290b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0000590b0c4474616e676c655f7072696d697469766573207365727669636573344a6f6243616c6c526573756c7408044300244163636f756e7449640100000c0128736572766963655f696430010c75363400011c63616c6c5f696430010c753634000118726573756c74290b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e00005d0b0c3c70616c6c65745f736572766963657314747970657338556e6170706c696564536c61736808244163636f756e74496401001c42616c616e6365011800180128736572766963655f696430010c7536340001206f70657261746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f7274657273390201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000610b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019101045300000400c90501185665633c543e0000650b0c4474616e676c655f7072696d6974697665732073657276696365733c4f70657261746f7250726f66696c6504044300000801207365727669636573690b01bc426f756e64656442547265655365743c7536342c20433a3a4d617853657276696365735065724f70657261746f723e000128626c75657072696e74736d0b01c4426f756e64656442547265655365743c7536342c20433a3a4d6178426c75657072696e74735065724f70657261746f723e0000690b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400510b012c42547265655365743c543e00006d0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400510b012c42547265655365743c543e0000710b0c3c70616c6c65745f7365727669636573186d6f64756c65144572726f7204045400019c44426c75657072696e744e6f74466f756e6400000490546865207365727669636520626c75657072696e7420776173206e6f7420666f756e642e70426c75657072696e744372656174696f6e496e74657272757074656400010488426c75657072696e74206372656174696f6e20697320696e7465727275707465642e44416c726561647952656769737465726564000204bc5468652063616c6c657220697320616c726561647920726567697374657265642061732061206f70657261746f722e60496e76616c6964526567697374726174696f6e496e707574000304ec5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2062652061206f70657261746f722e584e6f74416c6c6f776564546f556e7265676973746572000404a8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f20756e72656769737465722e784e6f74416c6c6f776564546f557064617465507269636554617267657473000504e8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f2075706461746520746865697220707269636520746172676574732e4c496e76616c696452657175657374496e707574000604fc5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2072657175657374206120736572766963652e4c496e76616c69644a6f6243616c6c496e707574000704e05468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2063616c6c2061206a6f622e40496e76616c69644a6f62526573756c74000804a85468652063616c6c65722070726f766964656420616e20696e76616c6964206a6f6220726573756c742e344e6f7452656769737465726564000904ac5468652063616c6c6572206973206e6f7420726567697374657265642061732061206f70657261746f722e4c417070726f76616c496e746572727570746564000a0480417070726f76616c2050726f6365737320697320696e7465727275707465642e5052656a656374696f6e496e746572727570746564000b048452656a656374696f6e2050726f6365737320697320696e7465727275707465642e5853657276696365526571756573744e6f74466f756e64000c04885468652073657276696365207265717565737420776173206e6f7420666f756e642e8053657276696365496e697469616c697a6174696f6e496e746572727570746564000d048c5365727669636520496e697469616c697a6174696f6e20696e7465727275707465642e3c536572766963654e6f74466f756e64000e0468546865207365727669636520776173206e6f7420666f756e642e585465726d696e6174696f6e496e746572727570746564000f04bc546865207465726d696e6174696f6e206f662074686520736572766963652077617320696e7465727275707465642e2454797065436865636b0400750b013854797065436865636b4572726f72001004fc416e206572726f72206f63637572726564207768696c65207479706520636865636b696e67207468652070726f766964656420696e70757420696e7075742e6c4d61785065726d697474656443616c6c65727345786365656465640011041901546865206d6178696d756d206e756d626572206f66207065726d69747465642063616c6c65727320706572207365727669636520686173206265656e2065786365656465642e6c4d61785365727669636550726f7669646572734578636565646564001204f8546865206d6178696d756d206e756d626572206f66206f70657261746f727320706572207365727669636520686173206265656e2065786365656465642e684d61785365727669636573506572557365724578636565646564001304e8546865206d6178696d756d206e756d626572206f6620736572766963657320706572207573657220686173206265656e2065786365656465642e444d61784669656c64734578636565646564001404ec546865206d6178696d756d206e756d626572206f66206669656c647320706572207265717565737420686173206265656e2065786365656465642e50417070726f76616c4e6f74526571756573746564001504f054686520617070726f76616c206973206e6f742072657175657374656420666f7220746865206f70657261746f7220287468652063616c6c6572292e544a6f62446566696e6974696f6e4e6f74466f756e6400160cb054686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f742065786973742e590154686973206572726f722069732072657475726e6564207768656e2074686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f7420657869737420696e20746865207365727669636528626c75657072696e742e60536572766963654f724a6f6243616c6c4e6f74466f756e64001704c4456974686572207468652073657276696365206f7220746865206a6f622063616c6c20776173206e6f7420666f756e642e544a6f6243616c6c526573756c744e6f74466f756e64001804a454686520726573756c74206f6620746865206a6f622063616c6c20776173206e6f7420666f756e642e3045564d416269456e636f6465001904b4416e206572726f72206f63637572726564207768696c6520656e636f64696e67207468652045564d204142492e3045564d4162694465636f6465001a04b4416e206572726f72206f63637572726564207768696c65206465636f64696e67207468652045564d204142492e5c4f70657261746f7250726f66696c654e6f74466f756e64001b046c4f70657261746f722070726f66696c65206e6f7420666f756e642e784d6178536572766963657350657250726f76696465724578636565646564001c04c04d6178696d756d206e756d626572206f66207365727669636573207065722050726f766964657220726561636865642e444f70657261746f724e6f74416374697665001d045901546865206f70657261746f72206973206e6f74206163746976652c20656e73757265206f70657261746f72207374617475732069732041435449564520696e206d756c74692d61737365742d64656c65676174696f6e404e6f41737365747350726f7669646564001e040d014e6f206173736574732070726f766964656420666f722074686520736572766963652c206174206c65617374206f6e652061737365742069732072657175697265642e6c4d6178417373657473506572536572766963654578636565646564001f04ec546865206d6178696d756d206e756d626572206f662061737365747320706572207365727669636520686173206265656e2065786365656465642e4c4f6666656e6465724e6f744f70657261746f72002004984f6666656e646572206973206e6f7420612072656769737465726564206f70657261746f722e644f6666656e6465724e6f744163746976654f70657261746f720021048c4f6666656e646572206973206e6f7420616e20616374697665206f70657261746f722e404e6f536c617368696e674f726967696e0022042101546865205365727669636520426c75657072696e7420646964206e6f742072657475726e206120736c617368696e67206f726967696e20666f72207468697320736572766963652e3c4e6f446973707574654f726967696e0023041d01546865205365727669636520426c75657072696e7420646964206e6f742072657475726e20612064697370757465206f726967696e20666f72207468697320736572766963652e58556e6170706c696564536c6173684e6f74466f756e640024048854686520556e6170706c69656420536c61736820617265206e6f7420666f756e642eb44d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64002504110154686520537570706c696564204d617374657220426c75657072696e742053657276696365204d616e61676572205265766973696f6e206973206e6f7420666f756e642ec04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e73457863656564656400260415014d6178696d756d206e756d626572206f66204d617374657220426c75657072696e742053657276696365204d616e61676572207265766973696f6e7320726561636865642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e750b0c4474616e676c655f7072696d6974697665732073657276696365733854797065436865636b4572726f7200010c50417267756d656e74547970654d69736d617463680c0114696e646578080108753800012065787065637465643d0601244669656c645479706500011861637475616c3d0601244669656c6454797065000000484e6f74456e6f756768417267756d656e74730801206578706563746564080108753800011861637475616c080108753800010048526573756c74547970654d69736d617463680c0114696e646578080108753800012065787065637465643d0601244669656c645479706500011861637475616c3d0601244669656c645479706500020000790b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c3c426f6e646564506f6f6c496e6e65720404540000100128636f6d6d697373696f6e7d0b0134436f6d6d697373696f6e3c543e000114726f6c6573850b015c506f6f6c526f6c65733c543a3a4163636f756e7449643e000114737461746545020124506f6f6c53746174650001206d65746164617461890b013c506f6f6c4d657461646174613c543e00007d0b104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e28436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784509013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f72617465810b01bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d790401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e4d0201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e0000810b04184f7074696f6e0404540149020108104e6f6e6500000010536f6d65040049020000010000850b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e0000890b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c30506f6f6c4d6574616461746104045400000801106e616d65ed0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e00008d0b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e7465728d070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e0000910b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7320537562506f6f6c7304045400000801186e6f5f657261950b0134556e626f6e64506f6f6c3c543e000120776974685f657261990b010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e0000950b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e0000990b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601950b0453000004009d0b013842547265654d61703c4b2c20563e00009d0b042042547265654d617008044b0110045601950b000400a10b000000a10b000002a50b00a50b0000040810950b00a90b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000ad0b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7328506f6f6c4d656d6265720404540000040138756e626f6e64696e675f65726173b10b010901426f756e64656442547265654d61703c457261496e6465782c2028506f6f6c49642c2042616c616e63654f663c543e292c20543a3a4d6178556e626f6e64696e673e0000b10b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b01100456013909045300000400b50b013842547265654d61703c4b2c20563e0000b50b042042547265654d617008044b01100456013909000400b90b000000b90b000002bd0b00bd0b0000040810390900c10b0c4470616c6c65745f74616e676c655f6c73741474797065733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000c50b0c4470616c6c65745f74616e676c655f6c73741870616c6c6574144572726f7204045400018430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e3846756c6c79556e626f6e64696e670004083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740005040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790006044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000714290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0008042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e670009085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000a04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000b043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000c047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000d04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000e049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e67655374617465000f048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001004b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001104ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e736976650400c90b0138446566656e736976654572726f720012083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001304bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640014041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001504ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001604e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400170409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640018040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001904a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001a048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001b0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001c049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001d04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001e04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e5c506f6f6c546f6b656e4372656174696f6e4661696c6564001f046c506f6f6c20746f6b656e206372656174696f6e206661696c65642e444e6f42616c616e6365546f556e626f6e64002004544e6f2062616c616e636520746f20756e626f6e642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ec90b0c4470616c6c65745f74616e676c655f6c73741870616c6c657438446566656e736976654572726f72000114684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c7900040000cd0b0c4466705f73656c665f636f6e7461696e65644c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301bd021043616c6c01b502245369676e6174757265015d0514457874726101d10b000400010c01250173705f72756e74696d653a3a67656e657269633a3a556e636865636b656445787472696e7369633c416464726573732c2043616c6c2c205369676e61747572652c2045787472610a3e0000d10b00000424d50bd90bdd0be10be50bed0bf10bf50bf90b00d50b10306672616d655f73797374656d28657874656e73696f6e7354636865636b5f6e6f6e5f7a65726f5f73656e64657248436865636b4e6f6e5a65726f53656e64657204045400000000d90b10306672616d655f73797374656d28657874656e73696f6e7348636865636b5f737065635f76657273696f6e40436865636b5370656356657273696f6e04045400000000dd0b10306672616d655f73797374656d28657874656e73696f6e7340636865636b5f74785f76657273696f6e38436865636b547856657273696f6e04045400000000e10b10306672616d655f73797374656d28657874656e73696f6e7334636865636b5f67656e6573697330436865636b47656e6573697304045400000000e50b10306672616d655f73797374656d28657874656e73696f6e733c636865636b5f6d6f7274616c69747938436865636b4d6f7274616c69747904045400000400e90b010c4572610000e90b102873705f72756e74696d651c67656e657269630c6572610c4572610001010420496d6d6f7274616c0000001c4d6f7274616c31040008000001001c4d6f7274616c32040008000002001c4d6f7274616c33040008000003001c4d6f7274616c34040008000004001c4d6f7274616c35040008000005001c4d6f7274616c36040008000006001c4d6f7274616c37040008000007001c4d6f7274616c38040008000008001c4d6f7274616c3904000800000900204d6f7274616c313004000800000a00204d6f7274616c313104000800000b00204d6f7274616c313204000800000c00204d6f7274616c313304000800000d00204d6f7274616c313404000800000e00204d6f7274616c313504000800000f00204d6f7274616c313604000800001000204d6f7274616c313704000800001100204d6f7274616c313804000800001200204d6f7274616c313904000800001300204d6f7274616c323004000800001400204d6f7274616c323104000800001500204d6f7274616c323204000800001600204d6f7274616c323304000800001700204d6f7274616c323404000800001800204d6f7274616c323504000800001900204d6f7274616c323604000800001a00204d6f7274616c323704000800001b00204d6f7274616c323804000800001c00204d6f7274616c323904000800001d00204d6f7274616c333004000800001e00204d6f7274616c333104000800001f00204d6f7274616c333204000800002000204d6f7274616c333304000800002100204d6f7274616c333404000800002200204d6f7274616c333504000800002300204d6f7274616c333604000800002400204d6f7274616c333704000800002500204d6f7274616c333804000800002600204d6f7274616c333904000800002700204d6f7274616c343004000800002800204d6f7274616c343104000800002900204d6f7274616c343204000800002a00204d6f7274616c343304000800002b00204d6f7274616c343404000800002c00204d6f7274616c343504000800002d00204d6f7274616c343604000800002e00204d6f7274616c343704000800002f00204d6f7274616c343804000800003000204d6f7274616c343904000800003100204d6f7274616c353004000800003200204d6f7274616c353104000800003300204d6f7274616c353204000800003400204d6f7274616c353304000800003500204d6f7274616c353404000800003600204d6f7274616c353504000800003700204d6f7274616c353604000800003800204d6f7274616c353704000800003900204d6f7274616c353804000800003a00204d6f7274616c353904000800003b00204d6f7274616c363004000800003c00204d6f7274616c363104000800003d00204d6f7274616c363204000800003e00204d6f7274616c363304000800003f00204d6f7274616c363404000800004000204d6f7274616c363504000800004100204d6f7274616c363604000800004200204d6f7274616c363704000800004300204d6f7274616c363804000800004400204d6f7274616c363904000800004500204d6f7274616c373004000800004600204d6f7274616c373104000800004700204d6f7274616c373204000800004800204d6f7274616c373304000800004900204d6f7274616c373404000800004a00204d6f7274616c373504000800004b00204d6f7274616c373604000800004c00204d6f7274616c373704000800004d00204d6f7274616c373804000800004e00204d6f7274616c373904000800004f00204d6f7274616c383004000800005000204d6f7274616c383104000800005100204d6f7274616c383204000800005200204d6f7274616c383304000800005300204d6f7274616c383404000800005400204d6f7274616c383504000800005500204d6f7274616c383604000800005600204d6f7274616c383704000800005700204d6f7274616c383804000800005800204d6f7274616c383904000800005900204d6f7274616c393004000800005a00204d6f7274616c393104000800005b00204d6f7274616c393204000800005c00204d6f7274616c393304000800005d00204d6f7274616c393404000800005e00204d6f7274616c393504000800005f00204d6f7274616c393604000800006000204d6f7274616c393704000800006100204d6f7274616c393804000800006200204d6f7274616c393904000800006300244d6f7274616c31303004000800006400244d6f7274616c31303104000800006500244d6f7274616c31303204000800006600244d6f7274616c31303304000800006700244d6f7274616c31303404000800006800244d6f7274616c31303504000800006900244d6f7274616c31303604000800006a00244d6f7274616c31303704000800006b00244d6f7274616c31303804000800006c00244d6f7274616c31303904000800006d00244d6f7274616c31313004000800006e00244d6f7274616c31313104000800006f00244d6f7274616c31313204000800007000244d6f7274616c31313304000800007100244d6f7274616c31313404000800007200244d6f7274616c31313504000800007300244d6f7274616c31313604000800007400244d6f7274616c31313704000800007500244d6f7274616c31313804000800007600244d6f7274616c31313904000800007700244d6f7274616c31323004000800007800244d6f7274616c31323104000800007900244d6f7274616c31323204000800007a00244d6f7274616c31323304000800007b00244d6f7274616c31323404000800007c00244d6f7274616c31323504000800007d00244d6f7274616c31323604000800007e00244d6f7274616c31323704000800007f00244d6f7274616c31323804000800008000244d6f7274616c31323904000800008100244d6f7274616c31333004000800008200244d6f7274616c31333104000800008300244d6f7274616c31333204000800008400244d6f7274616c31333304000800008500244d6f7274616c31333404000800008600244d6f7274616c31333504000800008700244d6f7274616c31333604000800008800244d6f7274616c31333704000800008900244d6f7274616c31333804000800008a00244d6f7274616c31333904000800008b00244d6f7274616c31343004000800008c00244d6f7274616c31343104000800008d00244d6f7274616c31343204000800008e00244d6f7274616c31343304000800008f00244d6f7274616c31343404000800009000244d6f7274616c31343504000800009100244d6f7274616c31343604000800009200244d6f7274616c31343704000800009300244d6f7274616c31343804000800009400244d6f7274616c31343904000800009500244d6f7274616c31353004000800009600244d6f7274616c31353104000800009700244d6f7274616c31353204000800009800244d6f7274616c31353304000800009900244d6f7274616c31353404000800009a00244d6f7274616c31353504000800009b00244d6f7274616c31353604000800009c00244d6f7274616c31353704000800009d00244d6f7274616c31353804000800009e00244d6f7274616c31353904000800009f00244d6f7274616c3136300400080000a000244d6f7274616c3136310400080000a100244d6f7274616c3136320400080000a200244d6f7274616c3136330400080000a300244d6f7274616c3136340400080000a400244d6f7274616c3136350400080000a500244d6f7274616c3136360400080000a600244d6f7274616c3136370400080000a700244d6f7274616c3136380400080000a800244d6f7274616c3136390400080000a900244d6f7274616c3137300400080000aa00244d6f7274616c3137310400080000ab00244d6f7274616c3137320400080000ac00244d6f7274616c3137330400080000ad00244d6f7274616c3137340400080000ae00244d6f7274616c3137350400080000af00244d6f7274616c3137360400080000b000244d6f7274616c3137370400080000b100244d6f7274616c3137380400080000b200244d6f7274616c3137390400080000b300244d6f7274616c3138300400080000b400244d6f7274616c3138310400080000b500244d6f7274616c3138320400080000b600244d6f7274616c3138330400080000b700244d6f7274616c3138340400080000b800244d6f7274616c3138350400080000b900244d6f7274616c3138360400080000ba00244d6f7274616c3138370400080000bb00244d6f7274616c3138380400080000bc00244d6f7274616c3138390400080000bd00244d6f7274616c3139300400080000be00244d6f7274616c3139310400080000bf00244d6f7274616c3139320400080000c000244d6f7274616c3139330400080000c100244d6f7274616c3139340400080000c200244d6f7274616c3139350400080000c300244d6f7274616c3139360400080000c400244d6f7274616c3139370400080000c500244d6f7274616c3139380400080000c600244d6f7274616c3139390400080000c700244d6f7274616c3230300400080000c800244d6f7274616c3230310400080000c900244d6f7274616c3230320400080000ca00244d6f7274616c3230330400080000cb00244d6f7274616c3230340400080000cc00244d6f7274616c3230350400080000cd00244d6f7274616c3230360400080000ce00244d6f7274616c3230370400080000cf00244d6f7274616c3230380400080000d000244d6f7274616c3230390400080000d100244d6f7274616c3231300400080000d200244d6f7274616c3231310400080000d300244d6f7274616c3231320400080000d400244d6f7274616c3231330400080000d500244d6f7274616c3231340400080000d600244d6f7274616c3231350400080000d700244d6f7274616c3231360400080000d800244d6f7274616c3231370400080000d900244d6f7274616c3231380400080000da00244d6f7274616c3231390400080000db00244d6f7274616c3232300400080000dc00244d6f7274616c3232310400080000dd00244d6f7274616c3232320400080000de00244d6f7274616c3232330400080000df00244d6f7274616c3232340400080000e000244d6f7274616c3232350400080000e100244d6f7274616c3232360400080000e200244d6f7274616c3232370400080000e300244d6f7274616c3232380400080000e400244d6f7274616c3232390400080000e500244d6f7274616c3233300400080000e600244d6f7274616c3233310400080000e700244d6f7274616c3233320400080000e800244d6f7274616c3233330400080000e900244d6f7274616c3233340400080000ea00244d6f7274616c3233350400080000eb00244d6f7274616c3233360400080000ec00244d6f7274616c3233370400080000ed00244d6f7274616c3233380400080000ee00244d6f7274616c3233390400080000ef00244d6f7274616c3234300400080000f000244d6f7274616c3234310400080000f100244d6f7274616c3234320400080000f200244d6f7274616c3234330400080000f300244d6f7274616c3234340400080000f400244d6f7274616c3234350400080000f500244d6f7274616c3234360400080000f600244d6f7274616c3234370400080000f700244d6f7274616c3234380400080000f800244d6f7274616c3234390400080000f900244d6f7274616c3235300400080000fa00244d6f7274616c3235310400080000fb00244d6f7274616c3235320400080000fc00244d6f7274616c3235330400080000fd00244d6f7274616c3235340400080000fe00244d6f7274616c3235350400080000ff0000ed0b10306672616d655f73797374656d28657874656e73696f6e732c636865636b5f6e6f6e636528436865636b4e6f6e63650404540000040061020120543a3a4e6f6e63650000f10b10306672616d655f73797374656d28657874656e73696f6e7330636865636b5f7765696768742c436865636b57656967687404045400000000f50b086870616c6c65745f7472616e73616374696f6e5f7061796d656e74604368617267655472616e73616374696f6e5061796d656e74040454000004006d01013042616c616e63654f663c543e0000f90b08746672616d655f6d657461646174615f686173685f657874656e73696f6e44436865636b4d657461646174614861736804045400000401106d6f6465fd0b01104d6f64650000fd0b08746672616d655f6d657461646174615f686173685f657874656e73696f6e104d6f64650001082044697361626c65640000001c456e61626c656400010000010c102873705f72756e74696d651c67656e657269634c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301bd021043616c6c01b502245369676e6174757265015d0514457874726101d10b00040038000000050c085874616e676c655f746573746e65745f72756e74696d651c52756e74696d6500000000ac1853797374656d011853797374656d481c4163636f756e7401010402000c4101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008004e8205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e3845787472696e736963436f756e74000010040004b820546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e40496e686572656e74734170706c696564010020040004a4205768657468657220616c6c20696e686572656e74732068617665206265656e206170706c6965642e2c426c6f636b576569676874010024180000000000000488205468652063757272656e742077656967687420666f722074686520626c6f636b2e40416c6c45787472696e736963734c656e000010040004410120546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e24426c6f636b486173680101040530348000000000000000000000000000000000000000000000000000000000000000000498204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e3445787472696e736963446174610101040510380400043d012045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e184e756d626572010030200000000000000000040901205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e28506172656e744861736801003480000000000000000000000000000000000000000000000000000000000000000004702048617368206f66207468652070726576696f757320626c6f636b2e1844696765737401003c040004f020446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e184576656e747301004c04001ca0204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e001d01204e4f54453a20546865206974656d20697320756e626f756e6420616e642073686f756c64207468657265666f7265206e657665722062652072656164206f6e20636861696e2ed020497420636f756c64206f746865727769736520696e666c6174652074686520506f562073697a65206f66206120626c6f636b2e002d01204576656e747320686176652061206c6172676520696e2d6d656d6f72792073697a652e20426f7820746865206576656e747320746f206e6f7420676f206f75742d6f662d6d656d6f7279fc206a75737420696e206361736520736f6d656f6e65207374696c6c207265616473207468656d2066726f6d2077697468696e207468652072756e74696d652e284576656e74436f756e74010010100000000004b820546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e2c4576656e74546f70696373010104023459020400282501204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e646578657394206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e00510120416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e2054686973450120616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e64e420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e005901205468652076616c756520686173207468652074797065206028426c6f636b4e756d626572466f723c543e2c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573744d012074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b0101206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e484c61737452756e74696d655570677261646500005d0204000455012053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e545570677261646564546f553332526566436f756e740100200400044d012054727565206966207765206861766520757067726164656420736f207468617420607479706520526566436f756e74602069732060753332602e2046616c7365202864656661756c7429206966206e6f742e605570677261646564546f547269706c65526566436f756e740100200400085d012054727565206966207765206861766520757067726164656420736f2074686174204163636f756e74496e666f20636f6e7461696e73207468726565207479706573206f662060526566436f756e74602e2046616c736548202864656661756c7429206966206e6f742e38457865637574696f6e506861736500005502040004882054686520657865637574696f6e207068617365206f662074686520626c6f636b2e44417574686f72697a65645570677261646500006502040004b82060536f6d6560206966206120636f6465207570677261646520686173206265656e20617574686f72697a65642e01690201581830426c6f636b576569676874737902f901624d186c000b00204aa9d10113ffffffffffffffff4247871900010b30f6a7a72e011366666666666666a6010b0098f73e5d0113ffffffffffffffbf0100004247871900010b307efa11a3011366666666666666e6010b00204aa9d10113ffffffffffffffff01070088526a74130000000000000040424787190000000004d020426c6f636b20262065787472696e7369637320776569676874733a20626173652076616c75657320616e64206c696d6974732e2c426c6f636b4c656e67746889023000003c00000050000000500004a820546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e38426c6f636b48617368436f756e7430200001000000000000045501204d6178696d756d206e756d626572206f6620626c6f636b206e756d62657220746f20626c6f636b2068617368206d617070696e677320746f206b65657020286f6c64657374207072756e6564206669727374292e20446257656967687491024040787d010000000000e1f505000000000409012054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e1c56657273696f6e9502c1033874616e676c652d746573746e65743874616e676c652d746573746e657401000000b30400000100000040df6acb689907609b0500000037e397fc7c91f5e40200000040fe3ad401f8959a060000009bbaa777b4c15fc401000000582211f65bb14b8905000000e65b00e46cedd0aa02000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000cbca25e39f14238702000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000ed99c5acb25eedf503000000bd78255d4feeea1f06000000a33d43f58731ad8402000000fbc577b9d747efd60100000001000000000484204765742074686520636861696e277320696e2d636f64652076657273696f6e2e2853533538507265666978e901082a0014a8205468652064657369676e61746564205353353820707265666978206f66207468697320636861696e2e0039012054686973207265706c6163657320746865202273733538466f726d6174222070726f7065727479206465636c6172656420696e2074686520636861696e20737065632e20526561736f6e20697331012074686174207468652072756e74696d652073686f756c64206b6e6f772061626f7574207468652070726566697820696e206f7264657220746f206d616b6520757365206f662069742061737020616e206964656e746966696572206f662074686520636861696e2e01a902012454696d657374616d70012454696d657374616d70080c4e6f7701003020000000000000000004a0205468652063757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e24446964557064617465010020040010d82057686574686572207468652074696d657374616d7020686173206265656e207570646174656420696e207468697320626c6f636b2e00550120546869732076616c7565206973207570646174656420746f206074727565602075706f6e207375636365737366756c207375626d697373696f6e206f6620612074696d657374616d702062792061206e6f64652e4501204974206973207468656e20636865636b65642061742074686520656e64206f66206561636820626c6f636b20657865637574696f6e20696e2074686520606f6e5f66696e616c697a656020686f6f6b2e01ad020004344d696e696d756d506572696f643020b80b000000000000188c20546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e004d012042652061776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e4901206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f61012064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20466f72206578616d706c652c20696e2074686520417572612070616c6c65742069742077696c6c20626520646f75626c6520746869737020706572696f64206f6e2064656661756c742073657474696e67732e0002105375646f01105375646f040c4b6579000000040004842054686520604163636f756e74496460206f6620746865207375646f206b65792e01b102017c00010d07036052616e646f6d6e657373436f6c6c656374697665466c6970016052616e646f6d6e657373436f6c6c656374697665466c6970043852616e646f6d4d6174657269616c0100110704000c610120536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e2054686973610120697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f664420746865206f6c6465737420686173682e00000000041841737365747301184173736574731414417373657400010402181507040004542044657461696c73206f6620616e2061737365742e1c4163636f756e7400010802021d072107040004e42054686520686f6c64696e6773206f662061207370656369666963206163636f756e7420666f7220612073706563696669632061737365742e24417070726f76616c7300010c0202022d07310704000c590120417070726f7665642062616c616e6365207472616e73666572732e2046697273742062616c616e63652069732074686520616d6f756e7420617070726f76656420666f72207472616e736665722e205365636f6e64e82069732074686520616d6f756e74206f662060543a3a43757272656e63796020726573657276656420666f722073746f72696e6720746869732e4901204669727374206b6579206973207468652061737365742049442c207365636f6e64206b657920697320746865206f776e657220616e64207468697264206b6579206973207468652064656c65676174652e204d65746164617461010104021835075000000000000000000000000000000000000000000458204d65746164617461206f6620616e2061737365742e2c4e657874417373657449640000180400246d012054686520617373657420494420656e666f7263656420666f7220746865206e657874206173736574206372656174696f6e2c20696620616e792070726573656e742e204f74686572776973652c20746869732073746f7261676550206974656d20686173206e6f206566666563742e00650120546869732063616e2062652075736566756c20666f722073657474696e6720757020636f6e73747261696e747320666f7220494473206f6620746865206e6577206173736574732e20466f72206578616d706c652c20627969012070726f766964696e6720616e20696e697469616c205b604e65787441737365744964605d20616e64207573696e6720746865205b6063726174653a3a4175746f496e6341737365744964605d2063616c6c6261636b2c20616ee8206175746f2d696e6372656d656e74206d6f64656c2063616e206265206170706c69656420746f20616c6c206e6577206173736574204944732e0021012054686520696e697469616c206e6578742061737365742049442063616e20626520736574207573696e6720746865205b6047656e65736973436f6e666967605d206f72207468652101205b5365744e657874417373657449645d28606d6967726174696f6e3a3a6e6578745f61737365745f69643a3a5365744e657874417373657449646029206d6967726174696f6e2e01b902018c1c4052656d6f76654974656d734c696d69741010e80300000c5101204d6178206e756d626572206f66206974656d7320746f2064657374726f7920706572206064657374726f795f6163636f756e74736020616e64206064657374726f795f617070726f76616c73602063616c6c2e003901204d75737420626520636f6e6669677572656420746f20726573756c7420696e2061207765696768742074686174206d616b657320656163682063616c6c2066697420696e206120626c6f636b2e3041737365744465706f73697418400000e8890423c78a000000000000000004f82054686520626173696320616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f7220616e2061737365742e4c41737365744163636f756e744465706f73697418400000e8890423c78a00000000000000000845012054686520616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f722061206e6f6e2d70726f7669646572206173736574206163636f756e7420746f20626530206d61696e7461696e65642e4c4d657461646174614465706f736974426173651840000054129336377505000000000000000451012054686520626173696320616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e20616464696e67206d6574616461746120746f20796f75722061737365742e584d657461646174614465706f7369745065724279746518400000c16ff2862300000000000000000008550120546865206164646974696f6e616c2066756e64732074686174206d75737420626520726573657276656420666f7220746865206e756d626572206f6620627974657320796f752073746f726520696e20796f757228206d657461646174612e3c417070726f76616c4465706f736974184000e40b540200000000000000000000000421012054686520616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e206372656174696e672061206e657720617070726f76616c2e2c537472696e674c696d697410103200000004e020546865206d6178696d756d206c656e677468206f662061206e616d65206f722073796d626f6c2073746f726564206f6e2d636861696e2e013d07052042616c616e636573012042616c616e6365731c34546f74616c49737375616e6365010018400000000000000000000000000000000004982054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e40496e61637469766549737375616e636501001840000000000000000000000000000000000409012054686520746f74616c20756e697473206f66206f75747374616e64696e672064656163746976617465642062616c616e636520696e207468652073797374656d2e1c4163636f756e74010104020014010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080600901205468652042616c616e6365732070616c6c6574206578616d706c65206f662073746f72696e67207468652062616c616e6365206f6620616e206163636f756e742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b19022020202074797065204163636f756e7453746f7265203d2053746f726167654d61705368696d3c53656c663a3a4163636f756e743c52756e74696d653e2c206672616d655f73797374656d3a3a50726f76696465723c52756e74696d653e2c204163636f756e7449642c2053656c663a3a4163636f756e74446174613c42616c616e63653e3e0c20207d102060606000150120596f752063616e20616c736f2073746f7265207468652062616c616e6365206f6620616e206163636f756e7420696e20746865206053797374656d602070616c6c65742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b7420202074797065204163636f756e7453746f7265203d2053797374656d0c20207d102060606000510120427574207468697320636f6d657320776974682074726164656f6666732c2073746f72696e67206163636f756e742062616c616e63657320696e207468652073797374656d2070616c6c65742073746f7265736d0120606672616d655f73797374656d60206461746120616c6f6e677369646520746865206163636f756e74206461746120636f6e747261727920746f2073746f72696e67206163636f756e742062616c616e63657320696e207468652901206042616c616e636573602070616c6c65742c20776869636820757365732061206053746f726167654d61706020746f2073746f72652062616c616e6365732064617461206f6e6c792e4101204e4f54453a2054686973206973206f6e6c79207573656420696e207468652063617365207468617420746869732070616c6c6574206973207573656420746f2073746f72652062616c616e6365732e144c6f636b7301010402004107040010b820416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2501204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602052657365727665730101040200510704000ca4204e616d6564207265736572766573206f6e20736f6d65206163636f756e742062616c616e6365732e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f6014486f6c647301010402005d070400046c20486f6c6473206f6e206163636f756e742062616c616e6365732e1c467265657a6573010104020071070400048820467265657a65206c6f636b73206f6e206163636f756e742062616c616e6365732e01c102019010484578697374656e7469616c4465706f736974184000e40b5402000000000000000000000020410120546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e204d5553542042452047524541544552205448414e205a45524f2100590120496620796f75202a7265616c6c792a206e65656420697420746f206265207a65726f2c20796f752063616e20656e61626c652074686520666561747572652060696e7365637572655f7a65726f5f65646020666f72610120746869732070616c6c65742e20486f77657665722c20796f7520646f20736f20617420796f7572206f776e207269736b3a20746869732077696c6c206f70656e2075702061206d616a6f7220446f5320766563746f722e590120496e206361736520796f752068617665206d756c7469706c6520736f7572636573206f662070726f7669646572207265666572656e6365732c20796f75206d617920616c736f2067657420756e65787065637465648c206265686176696f757220696620796f7520736574207468697320746f207a65726f2e00f020426f74746f6d206c696e653a20446f20796f757273656c662061206661766f757220616e64206d616b65206974206174206c65617374206f6e6521204d61784c6f636b7310103200000010f420546865206d6178696d756d206e756d626572206f66206c6f636b7320746861742073686f756c64206578697374206f6e20616e206163636f756e742edc204e6f74207374726963746c7920656e666f726365642c20627574207573656420666f722077656967687420657374696d6174696f6e2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602c4d617852657365727665731010320000000c0d0120546865206d6178696d756d206e756d626572206f66206e616d656420726573657276657320746861742063616e206578697374206f6e20616e206163636f756e742e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f60284d6178467265657a657310103200000004610120546865206d6178696d756d206e756d626572206f6620696e646976696475616c20667265657a65206c6f636b7320746861742063616e206578697374206f6e20616e206163636f756e7420617420616e792074696d652e01890706485472616e73616374696f6e5061796d656e7401485472616e73616374696f6e5061796d656e7408444e6578744665654d756c7469706c69657201008d0740000064a7b3b6e00d0000000000000000003853746f7261676556657273696f6e0100910704000000019804604f7065726174696f6e616c4665654d756c7469706c696572080405545901204120666565206d756c7469706c69657220666f7220604f7065726174696f6e616c602065787472696e7369637320746f20636f6d7075746520227669727475616c207469702220746f20626f6f73742074686569722c20607072696f726974796000510120546869732076616c7565206973206d756c7469706c69656420627920746865206066696e616c5f6665656020746f206f627461696e206120227669727475616c20746970222074686174206973206c61746572f420616464656420746f20612074697020636f6d706f6e656e7420696e20726567756c617220607072696f72697479602063616c63756c6174696f6e732e4d01204974206d65616e732074686174206120604e6f726d616c60207472616e73616374696f6e2063616e2066726f6e742d72756e20612073696d696c61726c792d73697a656420604f7065726174696f6e616c6041012065787472696e736963202877697468206e6f20746970292c20627920696e636c7564696e672061207469702076616c75652067726561746572207468616e20746865207669727475616c207469702e003c20606060727573742c69676e6f726540202f2f20466f7220604e6f726d616c608c206c6574207072696f72697479203d207072696f726974795f63616c6328746970293b0054202f2f20466f7220604f7065726174696f6e616c601101206c6574207669727475616c5f746970203d2028696e636c7573696f6e5f666565202b2074697029202a204f7065726174696f6e616c4665654d756c7469706c6965723bc4206c6574207072696f72697479203d207072696f726974795f63616c6328746970202b207669727475616c5f746970293b1020606060005101204e6f746520746861742073696e636520776520757365206066696e616c5f6665656020746865206d756c7469706c696572206170706c69657320616c736f20746f2074686520726567756c61722060746970605d012073656e74207769746820746865207472616e73616374696f6e2e20536f2c206e6f74206f6e6c7920646f657320746865207472616e73616374696f6e206765742061207072696f726974792062756d702062617365646101206f6e207468652060696e636c7573696f6e5f666565602c2062757420776520616c736f20616d706c6966792074686520696d70616374206f662074697073206170706c69656420746f20604f7065726174696f6e616c6038207472616e73616374696f6e732e000728417574686f72736869700128417574686f72736869700418417574686f720000000400046420417574686f72206f662063757272656e7420626c6f636b2e00000000081042616265011042616265442845706f6368496e64657801003020000000000000000004542043757272656e742065706f636820696e6465782e2c417574686f726974696573010095070400046c2043757272656e742065706f636820617574686f7269746965732e2c47656e65736973536c6f740100d90220000000000000000008f82054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e205468697320697320309020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2c43757272656e74536c6f740100d90220000000000000000004542043757272656e7420736c6f74206e756d6265722e2852616e646f6d6e65737301000480000000000000000000000000000000000000000000000000000000000000000028b8205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e002c20232053656375726974790005012054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061f8206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e7915012063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d6265727320746861742074686973150120286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e206265050120757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e0d01206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e6050656e64696e6745706f6368436f6e6669674368616e67650000e10204000461012050656e64696e672065706f636820636f6e66696775726174696f6e206368616e676520746861742077696c6c206265206170706c696564207768656e20746865206e6578742065706f636820697320656e61637465642e384e65787452616e646f6d6e657373010004800000000000000000000000000000000000000000000000000000000000000000045c204e6578742065706f63682072616e646f6d6e6573732e3c4e657874417574686f7269746965730100950704000460204e6578742065706f636820617574686f7269746965732e305365676d656e74496e6465780100101000000000247c2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e00f8205765206d616b6520612074726164652d6f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e01012057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f942060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e00ec204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e090120576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572791c2065706f63682e44556e646572436f6e737472756374696f6e0101040510a10704000415012054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2c496e697469616c697a65640000a90704000801012054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d65601d01206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e4c417574686f7256726652616e646f6d6e65737301003d0104001015012054686973206669656c642073686f756c6420616c7761797320626520706f70756c6174656420647572696e6720626c6f636b2070726f63657373696e6720756e6c6573731901207365636f6e6461727920706c61696e20736c6f74732061726520656e61626c65642028776869636820646f6e277420636f6e7461696e206120565246206f7574707574292e0049012049742069732073657420696e20606f6e5f66696e616c697a65602c206265666f72652069742077696c6c20636f6e7461696e207468652076616c75652066726f6d20746865206c61737420626c6f636b2e2845706f636853746172740100e5024000000000000000000000000000000000145d012054686520626c6f636b206e756d62657273207768656e20746865206c61737420616e642063757272656e742065706f6368206861766520737461727465642c20726573706563746976656c7920604e2d316020616e641420604e602e4901204e4f54453a20576520747261636b207468697320697320696e206f7264657220746f20616e6e6f746174652074686520626c6f636b206e756d626572207768656e206120676976656e20706f6f6c206f66590120656e74726f7079207761732066697865642028692e652e20697420776173206b6e6f776e20746f20636861696e206f6273657276657273292e2053696e63652065706f6368732061726520646566696e656420696e590120736c6f74732c207768696368206d617920626520736b69707065642c2074686520626c6f636b206e756d62657273206d6179206e6f74206c696e6520757020776974682074686520736c6f74206e756d626572732e204c6174656e65737301003020000000000000000014d820486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e001501205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e65642075701101206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636bb020657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2c45706f6368436f6e6669670000c10704000861012054686520636f6e66696775726174696f6e20666f72207468652063757272656e742065706f63682e2053686f756c64206e6576657220626520604e6f6e656020617320697420697320696e697469616c697a656420696e242067656e657369732e3c4e65787445706f6368436f6e6669670000c1070400082d012054686520636f6e66696775726174696f6e20666f7220746865206e6578742065706f63682c20604e6f6e65602069662074686520636f6e6669672077696c6c206e6f74206368616e6765e82028796f752063616e2066616c6c6261636b20746f206045706f6368436f6e6669676020696e737465616420696e20746861742063617365292e34536b697070656445706f6368730100c50704002029012041206c697374206f6620746865206c6173742031303020736b69707065642065706f63687320616e642074686520636f72726573706f6e64696e672073657373696f6e20696e64657870207768656e207468652065706f63682077617320736b69707065642e0031012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f663501206d75737420636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e656564206139012077617920746f2074696520746f6765746865722073657373696f6e7320616e642065706f636820696e64696365732c20692e652e207765206e65656420746f2076616c69646174652074686174290120612076616c696461746f722077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e64207768617420746865b0206163746976652065706f636820696e6465782077617320647572696e6720746861742073657373696f6e2e01c90200103445706f63684475726174696f6e3020b0040000000000000cec2054686520616d6f756e74206f662074696d652c20696e20736c6f74732c207468617420656163682065706f63682073686f756c64206c6173742e1901204e4f54453a2043757272656e746c79206974206973206e6f7420706f737369626c6520746f206368616e6765207468652065706f6368206475726174696f6e20616674657221012074686520636861696e2068617320737461727465642e20417474656d7074696e6720746f20646f20736f2077696c6c20627269636b20626c6f636b2070726f64756374696f6e2e444578706563746564426c6f636b54696d653020701700000000000014050120546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e67110120626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f75740501207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f740901206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473a0207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e384d6178417574686f7269746965731010e80300000488204d6178206e756d626572206f6620617574686f72697469657320616c6c6f776564344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e01c907091c4772616e647061011c4772616e6470611c1453746174650100cd0704000490205374617465206f66207468652063757272656e7420617574686f72697479207365742e3450656e64696e674368616e67650000d107040004c42050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e284e657874466f72636564000030040004bc206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e1c5374616c6c65640000e5020400049020607472756560206966207765206172652063757272656e746c79207374616c6c65642e3043757272656e745365744964010030200000000000000000085d0120546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c697469657329c420696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e30536574496453657373696f6e00010405301004002859012041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f722077686963682069747368206d656d62657273207765726520726573706f6e7369626c652e0045012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f66206d7573744d0120636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e65656420612077617920746f20746965450120746f6765746865722073657373696f6e7320616e64204752414e44504120736574206964732c20692e652e207765206e65656420746f2076616c6964617465207468617420612076616c696461746f7241012077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e642077686174207468652061637469766520736574204944207761735420647572696e6720746861742073657373696f6e2e00b82054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e2c417574686f7269746965730100d50704000484205468652063757272656e74206c697374206f6620617574686f7269746965732e01ed02019c0c384d6178417574686f7269746965731010e8030000045c204d617820417574686f72697469657320696e20757365344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e584d6178536574496453657373696f6e456e74726965733020000000000000000018390120546865206d6178696d756d206e756d626572206f6620656e747269657320746f206b65657020696e207468652073657420696420746f2073657373696f6e20696e646578206d617070696e672e0031012053696e6365207468652060536574496453657373696f6e60206d6170206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e73207468697329012076616c75652073686f756c642072656c61746520746f2074686520626f6e64696e67206475726174696f6e206f66207768617465766572207374616b696e672073797374656d2069733501206265696e6720757365642028696620616e79292e2049662065717569766f636174696f6e2068616e646c696e67206973206e6f7420656e61626c6564207468656e20746869732076616c7565342063616e206265207a65726f2e01d9070a1c496e6469636573011c496e646963657304204163636f756e74730001040210dd070400048820546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e011d0301ac041c4465706f7369741840000064a7b3b6e00d000000000000000004ac20546865206465706f736974206e656564656420666f7220726573657276696e6720616e20696e6465782e01e1070b2444656d6f6372616379012444656d6f6372616379303c5075626c696350726f70436f756e74010010100000000004f420546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e2c5075626c696350726f70730100e507040004050120546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c2e244465706f7369744f660001040510f10704000c842054686f73652077686f2068617665206c6f636b65642061206465706f7369742e00d82054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e3c5265666572656e64756d436f756e74010010100000000004310120546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e344c6f77657374556e62616b6564010010100000000008250120546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746fdc20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e405265666572656e64756d496e666f4f660001040510f50704000cb420496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e0009012054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20566f74696e674f6601010405000108e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105d0120416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077655d012068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e00e82054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e544c6173745461626c656457617345787465726e616c0100200400085901205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c6963282070726f706f73616c2e304e65787445787465726e616c00001908040010590120546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e550120546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743aa4202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f7268202d20605075626c696350726f70736020697320656d7074792e24426c61636b6c69737400010406341d0804000851012041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d626572e82028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e3443616e63656c6c6174696f6e730101040634200400042901205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e284d657461646174614f6600010402c034040018ec2047656e6572616c20696e666f726d6174696f6e20636f6e6365726e696e6720616e792070726f706f73616c206f72207265666572656e64756d2e490120546865206048617368602072656665727320746f2074686520707265696d616765206f66207468652060507265696d61676573602070726f76696465722077686963682063616e2062652061204a534f4e882064756d70206f7220495046532068617368206f662061204a534f4e2066696c652e00750120436f6e73696465722061206761726261676520636f6c6c656374696f6e20666f722061206d65746164617461206f662066696e6973686564207265666572656e64756d7320746f2060756e7265717565737460202872656d6f76652944206c6172676520707265696d616765732e01210301b0303c456e6163746d656e74506572696f643020c0a800000000000014e82054686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e0031012049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e737572652074686174510120766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365b4207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e304c61756e6368506572696f643020201c00000000000004e420486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e30566f74696e67506572696f643020c08901000000000004b820486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e44566f74654c6f636b696e67506572696f643020c0a8000000000000109020546865206d696e696d756d20706572696f64206f6620766f7465206c6f636b696e672e0065012049742073686f756c64206265206e6f2073686f72746572207468616e20656e6163746d656e7420706572696f6420746f20656e73757265207468617420696e207468652063617365206f6620616e20617070726f76616c2c49012074686f7365207375636365737366756c20766f7465727320617265206c6f636b656420696e746f2074686520636f6e73657175656e636573207468617420746865697220766f74657320656e7461696c2e384d696e696d756d4465706f73697418400000a0dec5adc935360000000000000004350120546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e38496e7374616e74416c6c6f7765642004010c550120496e64696361746f7220666f72207768657468657220616e20656d657267656e6379206f726967696e206973206576656e20616c6c6f77656420746f2068617070656e2e20536f6d6520636861696e73206d617961012077616e7420746f207365742074686973207065726d616e656e746c7920746f206066616c7365602c206f7468657273206d61792077616e7420746f20636f6e646974696f6e206974206f6e207468696e67732073756368a020617320616e207570677261646520686176696e672068617070656e656420726563656e746c792e5446617374547261636b566f74696e67506572696f643020807000000000000004ec204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f72206120666173742d747261636b207265666572656e64756d2e34436f6f6c6f6666506572696f643020c0a800000000000004610120506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d6178566f74657310106400000010b020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e00d420416c736f207573656420746f20636f6d70757465207765696768742c20616e206f7665726c79206269672076616c75652063616e1501206c65616420746f2065787472696e7369632077697468207665727920626967207765696768743a20736565206064656c65676174656020666f7220696e7374616e63652e304d617850726f706f73616c73101064000000040d0120546865206d6178696d756d206e756d626572206f66207075626c69632070726f706f73616c7320746861742063616e20657869737420617420616e792074696d652e2c4d61784465706f73697473101064000000041d0120546865206d6178696d756d206e756d626572206f66206465706f736974732061207075626c69632070726f706f73616c206d6179206861766520617420616e792074696d652e384d6178426c61636b6c697374656410106400000004d820546865206d6178696d756d206e756d626572206f66206974656d732077686963682063616e20626520626c61636b6c69737465642e0121080c1c436f756e63696c011c436f756e63696c182450726f706f73616c7301002508040004902054686520686173686573206f6620746865206163746976652070726f706f73616c732e2850726f706f73616c4f660001040634b502040004cc2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e18566f74696e6700010406342908040004b420566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e3450726f706f73616c436f756e74010010100000000004482050726f706f73616c7320736f206661722e1c4d656d62657273010039020400043901205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e145072696d65000000040004610120546865207072696d65206d656d62657220746861742068656c70732064657465726d696e65207468652064656661756c7420766f7465206265686176696f7220696e2063617365206f662061627374656e74696f6e732e013d0301c404444d617850726f706f73616c576569676874283c070010a5d4e813ffffffffffffff7f04250120546865206d6178696d756d20776569676874206f6620612064697370617463682063616c6c20746861742063616e2062652070726f706f73656420616e642065786563757465642e012d080d1c56657374696e67011c56657374696e67081c56657374696e6700010402003108040004d820496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e3853746f7261676556657273696f6e0100390804000c7c2053746f726167652076657273696f6e206f66207468652070616c6c65742e003101204e6577206e6574776f726b732073746172742077697468206c61746573742076657273696f6e2c2061732064657465726d696e6564206279207468652067656e65736973206275696c642e01410301c808444d696e5665737465645472616e736665721840000010632d5ec76b050000000000000004e820546865206d696e696d756d20616d6f756e74207472616e7366657272656420746f2063616c6c20607665737465645f7472616e73666572602e4c4d617856657374696e675363686564756c657310101c00000000013d080e24456c656374696f6e730124456c656374696f6e73141c4d656d626572730100410804000c74205468652063757272656e7420656c6563746564206d656d626572732e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e2452756e6e65727355700100410804001084205468652063757272656e742072657365727665642072756e6e6572732d75702e00590120496e76617269616e743a20416c7761797320736f72746564206261736564206f6e2072616e6b2028776f72736520746f2062657374292e2055706f6e2072656d6f76616c206f662061206d656d6265722c20746865bc206c6173742028692e652e205f626573745f292072756e6e65722d75702077696c6c206265207265706c616365642e2843616e646964617465730100d00400185901205468652070726573656e742063616e646964617465206c6973742e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f72d020616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e007c205365636f6e6420656c656d656e7420697320746865206465706f7369742e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e38456c656374696f6e526f756e647301001010000000000441012054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e18566f74696e6701010405004908840000000000000000000000000000000000000000000000000000000000000000000cb820566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e00c42054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682e01490301cc282050616c6c65744964a50220706872656c65637404d0204964656e74696669657220666f722074686520656c656374696f6e732d70687261676d656e2070616c6c65742773206c6f636b3443616e646964616379426f6e6418400000a0dec5adc935360000000000000004050120486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e38566f74696e67426f6e6442617365184000005053c91aa974050000000000000010942042617365206465706f736974206173736f636961746564207769746820766f74696e672e00550120546869732073686f756c642062652073656e7369626c79206869676820746f2065636f6e6f6d6963616c6c7920656e73757265207468652070616c6c65742063616e6e6f742062652061747461636b656420627994206372656174696e67206120676967616e746963206e756d626572206f6620766f7465732e40566f74696e67426f6e64466163746f721840000020f84dde700400000000000000000411012054686520616d6f756e74206f6620626f6e642074686174206e65656420746f206265206c6f636b656420666f72206561636820766f746520283332206279746573292e38446573697265644d656d626572731010050000000470204e756d626572206f66206d656d6265727320746f20656c6563742e404465736972656452756e6e65727355701010030000000478204e756d626572206f662072756e6e6572735f757020746f206b6565702e305465726d4475726174696f6e3020c0890100000000000c510120486f77206c6f6e6720656163682073656174206973206b6570742e205468697320646566696e657320746865206e65787420626c6f636b206e756d62657220617420776869636820616e20656c656374696f6e5d0120726f756e642077696c6c2068617070656e2e2049662073657420746f207a65726f2c206e6f20656c656374696f6e732061726520657665722074726967676572656420616e6420746865206d6f64756c652077696c6c5020626520696e2070617373697665206d6f64652e344d617843616e6469646174657310104000000018e420546865206d6178696d756d206e756d626572206f662063616e6469646174657320696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e003101205768656e2074686973206c696d69742069732072656163686564206e6f206d6f72652063616e646964617465732061726520616363657074656420696e2074686520656c656374696f6e2e244d6178566f7465727310100002000018f820546865206d6178696d756d206e756d626572206f6620766f7465727320746f20616c6c6f7720696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e00d8205768656e20746865206c696d6974206973207265616368656420746865206e657720766f74657273206172652069676e6f7265642e404d6178566f746573506572566f7465721010640000001090204d6178696d756d206e756d62657273206f6620766f7465732070657220766f7465722e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e014d080f68456c656374696f6e50726f76696465724d756c746950686173650168456c656374696f6e50726f76696465724d756c746950686173652814526f756e64010010100100000018ac20496e7465726e616c20636f756e74657220666f7220746865206e756d626572206f6620726f756e64732e00550120546869732069732075736566756c20666f722064652d6475706c69636174696f6e206f66207472616e73616374696f6e73207375626d697474656420746f2074686520706f6f6c2c20616e642067656e6572616c6c20646961676e6f7374696373206f66207468652070616c6c65742e004d012054686973206973206d6572656c7920696e6372656d656e746564206f6e6365207065722065766572792074696d65207468617420616e20757073747265616d2060656c656374602069732063616c6c65642e3043757272656e7450686173650100e40400043c2043757272656e742070686173652e38517565756564536f6c7574696f6e0000510804000c3d012043757272656e74206265737420736f6c7574696f6e2c207369676e6564206f7220756e7369676e65642c2071756575656420746f2062652072657475726e65642075706f6e2060656c656374602e006020416c7761797320736f727465642062792073636f72652e20536e617073686f74000059080400107020536e617073686f742064617461206f662074686520726f756e642e005d01205468697320697320637265617465642061742074686520626567696e6e696e67206f6620746865207369676e656420706861736520616e6420636c65617265642075706f6e2063616c6c696e672060656c656374602e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e384465736972656454617267657473000010040010cc2044657369726564206e756d626572206f66207461726765747320746f20656c65637420666f72207468697320726f756e642e00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e40536e617073686f744d65746164617461000025040400109820546865206d65746164617461206f6620746865205b60526f756e64536e617073686f74605d00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e645369676e65645375626d697373696f6e4e657874496e646578010010100000000024010120546865206e65787420696e64657820746f2062652061737369676e656420746f20616e20696e636f6d696e67207369676e6564207375626d697373696f6e2e007501204576657279206163636570746564207375626d697373696f6e2069732061737369676e6564206120756e6971756520696e6465783b207468617420696e64657820697320626f756e6420746f207468617420706172746963756c61726501207375626d697373696f6e20666f7220746865206475726174696f6e206f662074686520656c656374696f6e2e204f6e20656c656374696f6e2066696e616c697a6174696f6e2c20746865206e65787420696e6465782069733020726573657420746f20302e0069012057652063616e2774206a7573742075736520605369676e65645375626d697373696f6e496e64696365732e6c656e2829602c206265636175736520746861742773206120626f756e646564207365743b20706173742069747359012063617061636974792c2069742077696c6c2073696d706c792073617475726174652e2057652063616e2774206a7573742069746572617465206f76657220605369676e65645375626d697373696f6e734d6170602cf4206265636175736520697465726174696f6e20697320736c6f772e20496e73746561642c2077652073746f7265207468652076616c756520686572652e5c5369676e65645375626d697373696f6e496e6469636573010069080400186d01204120736f727465642c20626f756e64656420766563746f72206f6620602873636f72652c20626c6f636b5f6e756d6265722c20696e64657829602c20776865726520656163682060696e6465786020706f696e747320746f2061782076616c756520696e20605369676e65645375626d697373696f6e73602e007101205765206e65766572206e65656420746f2070726f63657373206d6f7265207468616e20612073696e676c65207369676e6564207375626d697373696f6e20617420612074696d652e205369676e6564207375626d697373696f6e7375012063616e206265207175697465206c617267652c20736f2077652772652077696c6c696e6720746f207061792074686520636f7374206f66206d756c7469706c6520646174616261736520616363657373657320746f206163636573732101207468656d206f6e6520617420612074696d6520696e7374656164206f662072656164696e6720616e64206465636f64696e6720616c6c206f66207468656d206174206f6e63652e505369676e65645375626d697373696f6e734d61700001040510750804001c7420556e636865636b65642c207369676e656420736f6c7574696f6e732e00690120546f676574686572207769746820605375626d697373696f6e496e6469636573602c20746869732073746f726573206120626f756e64656420736574206f6620605369676e65645375626d697373696f6e7360207768696c65ec20616c6c6f77696e6720757320746f206b656570206f6e6c7920612073696e676c65206f6e6520696e206d656d6f727920617420612074696d652e0069012054776f78206e6f74653a20746865206b6579206f6620746865206d617020697320616e206175746f2d696e6372656d656e74696e6720696e6465782077686963682075736572732063616e6e6f7420696e7370656374206f72f4206166666563743b2077652073686f756c646e2774206e65656420612063727970746f67726170686963616c6c7920736563757265206861736865722e544d696e696d756d556e7472757374656453636f72650000e00400105d0120546865206d696e696d756d2073636f7265207468617420656163682027756e747275737465642720736f6c7574696f6e206d7573742061747461696e20696e206f7264657220746f20626520636f6e7369646572656428206665617369626c652e00b82043616e206265207365742076696120607365745f6d696e696d756d5f756e747275737465645f73636f7265602e01510301d838544265747465725369676e65645468726573686f6c64f41000000000084d0120546865206d696e696d756d20616d6f756e74206f6620696d70726f76656d656e7420746f2074686520736f6c7574696f6e2073636f7265207468617420646566696e6573206120736f6c7574696f6e2061737820226265747465722220696e20746865205369676e65642070686173652e384f6666636861696e5265706561743020050000000000000010b42054686520726570656174207468726573686f6c64206f6620746865206f6666636861696e20776f726b65722e00610120466f72206578616d706c652c20696620697420697320352c2074686174206d65616e732074686174206174206c65617374203520626c6f636b732077696c6c20656c61707365206265747765656e20617474656d7074738420746f207375626d69742074686520776f726b6572277320736f6c7574696f6e2e3c4d696e657254785072696f726974793020feffffffffffff7f04250120546865207072696f72697479206f662074686520756e7369676e6564207472616e73616374696f6e207375626d697474656420696e2074686520756e7369676e65642d7068617365505369676e65644d61785375626d697373696f6e7310100a0000001ce4204d6178696d756d206e756d626572206f66207369676e6564207375626d697373696f6e7320746861742063616e206265207175657565642e005501204974206973206265737420746f2061766f69642061646a757374696e67207468697320647572696e6720616e20656c656374696f6e2c20617320697420696d706163747320646f776e73747265616d2064617461650120737472756374757265732e20496e20706172746963756c61722c20605369676e65645375626d697373696f6e496e64696365733c543e6020697320626f756e646564206f6e20746869732076616c75652e20496620796f75f42075706461746520746869732076616c756520647572696e6720616e20656c656374696f6e2c20796f75205f6d7573745f20656e7375726520746861744d0120605369676e65645375626d697373696f6e496e64696365732e6c656e282960206973206c657373207468616e206f7220657175616c20746f20746865206e65772076616c75652e204f74686572776973652cf020617474656d70747320746f207375626d6974206e657720736f6c7574696f6e73206d617920636175736520612072756e74696d652070616e69632e3c5369676e65644d617857656967687428400bd8e2a18c2e011366666666666666a61494204d6178696d756d20776569676874206f662061207369676e656420736f6c7574696f6e2e005d01204966205b60436f6e6669673a3a4d696e6572436f6e666967605d206973206265696e6720696d706c656d656e74656420746f207375626d6974207369676e656420736f6c7574696f6e7320286f757473696465206f663d0120746869732070616c6c6574292c207468656e205b604d696e6572436f6e6669673a3a736f6c7574696f6e5f776569676874605d206973207573656420746f20636f6d7061726520616761696e73743020746869732076616c75652e405369676e65644d6178526566756e647310100300000004190120546865206d6178696d756d20616d6f756e74206f6620756e636865636b656420736f6c7574696f6e7320746f20726566756e64207468652063616c6c2066656520666f722e405369676e6564526577617264426173651840000064a7b3b6e00d0000000000000000048820426173652072657761726420666f722061207369676e656420736f6c7574696f6e445369676e65644465706f73697442797465184000008a5d78456301000000000000000004a0205065722d62797465206465706f73697420666f722061207369676e656420736f6c7574696f6e2e4c5369676e65644465706f73697457656967687418400000000000000000000000000000000004a8205065722d776569676874206465706f73697420666f722061207369676e656420736f6c7574696f6e2e284d617857696e6e6572731010e803000010350120546865206d6178696d756d206e756d626572206f662077696e6e65727320746861742063616e20626520656c656374656420627920746869732060456c656374696f6e50726f7669646572604020696d706c656d656e746174696f6e2e005101204e6f74653a2054686973206d75737420616c776179732062652067726561746572206f7220657175616c20746f2060543a3a4461746150726f76696465723a3a646573697265645f746172676574732829602e384d696e65724d61784c656e67746810100000360000384d696e65724d617857656967687428400bd8e2a18c2e011366666666666666a600544d696e65724d6178566f746573506572566f746572101010000000003c4d696e65724d617857696e6e6572731010e803000000017908101c5374616b696e67011c5374616b696e67ac3856616c696461746f72436f756e740100101000000000049c2054686520696465616c206e756d626572206f66206163746976652076616c696461746f72732e544d696e696d756d56616c696461746f72436f756e740100101000000000044101204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e34496e76756c6e657261626c65730100390204000c590120416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e636520746865792772654d01206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f7572ac20696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e18426f6e64656400010405000004000c0101204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e404d696e4e6f6d696e61746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f662061206e6f6d696e61746f722e404d696e56616c696461746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f6620612076616c696461746f722e484d696e696d756d4163746976655374616b65010018400000000000000000000000000000000004110120546865206d696e696d756d20616374697665206e6f6d696e61746f72207374616b65206f6620746865206c617374207375636365737366756c20656c656374696f6e2e344d696e436f6d6d697373696f6e0100f410000000000ce820546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e20746861742076616c696461746f72732063616e207365742e00802049662073657420746f206030602c206e6f206c696d6974206578697374732e184c656467657200010402007d080400104501204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e007501204e6f74653a20416c6c2074686520726561647320616e64206d75746174696f6e7320746f20746869732073746f72616765202a4d5553542a20626520646f6e65207468726f75676820746865206d6574686f6473206578706f736564e8206279205b605374616b696e674c6564676572605d20746f20656e73757265206461746120616e64206c6f636b20636f6e73697374656e63792e1450617965650001040500f004000ce42057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e2856616c696461746f72730101040500f80800000c450120546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f7256616c696461746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d617856616c696461746f7273436f756e7400001004000c310120546865206d6178696d756d2076616c696461746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e284e6f6d696e61746f72730001040500850804004c750120546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f207468656972206e6f6d696e6174696f6e20707265666572656e6365732c206e616d656c79207468652076616c696461746f72732074686174582074686579207769736820746f20737570706f72742e003901204e6f7465207468617420746865206b657973206f6620746869732073746f72616765206d6170206d69676874206265636f6d65206e6f6e2d6465636f6461626c6520696e2063617365207468652d01206163636f756e742773205b604e6f6d696e6174696f6e7351756f74613a3a4d61784e6f6d696e6174696f6e73605d20636f6e66696775726174696f6e206973206465637265617365642e9020496e2074686973207261726520636173652c207468657365206e6f6d696e61746f7273650120617265207374696c6c206578697374656e7420696e2073746f726167652c207468656972206b657920697320636f727265637420616e64207265747269657661626c652028692e652e2060636f6e7461696e735f6b657960710120696e6469636174657320746861742074686579206578697374292c206275742074686569722076616c75652063616e6e6f74206265206465636f6465642e205468657265666f72652c20746865206e6f6e2d6465636f6461626c656d01206e6f6d696e61746f72732077696c6c206566666563746976656c79206e6f742d65786973742c20756e74696c20746865792072652d7375626d697420746865697220707265666572656e6365732073756368207468617420697401012069732077697468696e2074686520626f756e6473206f6620746865206e65776c79207365742060436f6e6669673a3a4d61784e6f6d696e6174696f6e73602e006101205468697320696d706c696573207468617420603a3a697465725f6b65797328292e636f756e7428296020616e6420603a3a6974657228292e636f756e74282960206d696768742072657475726e20646966666572656e746d012076616c75657320666f722074686973206d61702e204d6f72656f7665722c20746865206d61696e20603a3a636f756e7428296020697320616c69676e656420776974682074686520666f726d65722c206e616d656c79207468656c206e756d626572206f66206b65797320746861742065786973742e006d01204c6173746c792c20696620616e79206f6620746865206e6f6d696e61746f7273206265636f6d65206e6f6e2d6465636f6461626c652c20746865792063616e206265206368696c6c656420696d6d6564696174656c7920766961b8205b6043616c6c3a3a6368696c6c5f6f74686572605d20646973706174636861626c6520627920616e796f6e652e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f724e6f6d696e61746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170385669727475616c5374616b657273000104050084040018c8205374616b6572732077686f73652066756e647320617265206d616e61676564206279206f746865722070616c6c6574732e00750120546869732070616c6c657420646f6573206e6f74206170706c7920616e79206c6f636b73206f6e207468656d2c207468657265666f7265207468657920617265206f6e6c79207669727475616c6c7920626f6e6465642e20546865796d012061726520657870656374656420746f206265206b65796c657373206163636f756e747320616e642068656e63652073686f756c64206e6f7420626520616c6c6f77656420746f206d7574617465207468656972206c65646765727101206469726563746c792076696120746869732070616c6c65742e20496e73746561642c207468657365206163636f756e747320617265206d616e61676564206279206f746865722070616c6c65747320616e64206163636573736564290120766961206c6f77206c6576656c20617069732e205765206b65657020747261636b206f66207468656d20746f20646f206d696e696d616c20696e7465677269747920636865636b732e60436f756e746572466f725669727475616c5374616b657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d61784e6f6d696e61746f7273436f756e7400001004000c310120546865206d6178696d756d206e6f6d696e61746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e2843757272656e744572610000100400105c205468652063757272656e742065726120696e6465782e006501205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f7280207365742c206974206d6967687420626520616374697665206f72206e6f742e2441637469766545726100008908040010d820546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e0059012054686520616374697665206572612069732074686520657261206265696e672063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d757374206265ac20657175616c20746f205b6053657373696f6e496e746572666163653a3a76616c696461746f7273605d2e5445726173537461727453657373696f6e496e6465780001040510100400105501205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e006101204e6f74653a205468697320747261636b7320746865207374617274696e672073657373696f6e2028692e652e2073657373696f6e20696e646578207768656e20657261207374617274206265696e672061637469766529f020666f7220746865206572617320696e20605b43757272656e74457261202d20484953544f52595f44455054482c2043757272656e744572615d602e2c457261735374616b65727301010805058d0869010c0000002078204578706f73757265206f662076616c696461746f72206174206572612e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e4c457261735374616b6572734f7665727669657700010805058d089108040030b82053756d6d617279206f662076616c696461746f72206578706f73757265206174206120676976656e206572612e007101205468697320636f6e7461696e732074686520746f74616c207374616b6520696e20737570706f7274206f66207468652076616c696461746f7220616e64207468656972206f776e207374616b652e20496e206164646974696f6e2c75012069742063616e20616c736f206265207573656420746f2067657420746865206e756d626572206f66206e6f6d696e61746f7273206261636b696e6720746869732076616c696461746f7220616e6420746865206e756d626572206f666901206578706f73757265207061676573207468657920617265206469766964656420696e746f2e20546865207061676520636f756e742069732075736566756c20746f2064657465726d696e6520746865206e756d626572206f66ac207061676573206f6620726577617264732074686174206e6565647320746f20626520636c61696d65642e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742eac2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206f766572766965772069732072657475726e65642e48457261735374616b657273436c697070656401010805058d0869010c000000409820436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e006501204e6f74653a205468697320697320646570726563617465642c2073686f756c64206265207573656420617320726561642d6f6e6c7920616e642077696c6c2062652072656d6f76656420696e20746865206675747572652e3101204e657720604578706f737572656073206172652073746f72656420696e2061207061676564206d616e6e657220696e2060457261735374616b65727350616765646020696e73746561642e00590120546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f20746865a82060543a3a4d61784578706f737572655061676553697a65602062696767657374207374616b6572732e1d0120284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292ef42054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e005d012054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e40457261735374616b657273506167656400010c05050595089908040018c020506167696e61746564206578706f73757265206f6620612076616c696461746f7220617420676976656e206572612e0071012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e2c207468656e207374617368206163636f756e7420616e642066696e616c6c79d42074686520706167652e2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00d4205468697320697320636c6561726564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e38436c61696d65645265776172647301010805058d084104040018dc20486973746f7279206f6620636c61696d656420706167656420726577617264732062792065726120616e642076616c696461746f722e0069012054686973206973206b657965642062792065726120616e642076616c696461746f72207374617368207768696368206d61707320746f2074686520736574206f66207061676520696e6465786573207768696368206861766538206265656e20636c61696d65642e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e484572617356616c696461746f72507265667301010805058d08f80800001411012053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4c4572617356616c696461746f7252657761726400010405101804000c2d012054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e0021012045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e4045726173526577617264506f696e747301010405109d0814000000000008d0205265776172647320666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e250120496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e3845726173546f74616c5374616b6501010405101840000000000000000000000000000000000811012054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e1d0120496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e20466f7263654572610100010104000454204d6f6465206f662065726120666f7263696e672e404d61785374616b6564526577617264730000f10104000c1901204d6178696d756d207374616b656420726577617264732c20692e652e207468652070657263656e74616765206f66207468652065726120696e666c6174696f6e20746861746c206973207573656420666f72207374616b6520726577617264732eac20536565205b457261207061796f75745d282e2f696e6465782e68746d6c236572612d7061796f7574292e4c536c6173685265776172644672616374696f6e0100f410000000000cf8205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e00e4205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e4c43616e63656c6564536c6173685061796f757401001840000000000000000000000000000000000815012054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e7420776869636820776173ec2063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e40556e6170706c696564536c61736865730101040510ad08040004c420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e28426f6e646564457261730100b50804001025012041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e00c8204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653abc20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d604c56616c696461746f72536c617368496e45726100010805058d08bd08040008450120416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e7020616e6420736c6173682076616c7565206f6620746865206572612e4c4e6f6d696e61746f72536c617368496e45726100010805058d0818040004610120416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e34536c617368696e675370616e730001040500c1080400048c20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e245370616e536c61736801010405a908c508800000000000000000000000000000000000000000000000000000000000000000083d01205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2cb82061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e5443757272656e74506c616e6e656453657373696f6e01001010000000000ce820546865206c61737420706c616e6e65642073657373696f6e207363686564756c6564206279207468652073657373696f6e2070616c6c65742e0071012054686973206973206261736963616c6c7920696e2073796e632077697468207468652063616c6c20746f205b6070616c6c65745f73657373696f6e3a3a53657373696f6e4d616e616765723a3a6e65775f73657373696f6e605d2e4844697361626c656456616c696461746f72730100410404001c750120496e6469636573206f662076616c696461746f727320746861742068617665206f6666656e64656420696e2074686520616374697665206572612e20546865206f6666656e64657273206172652064697361626c656420666f72206169012077686f6c65206572612e20466f72207468697320726561736f6e207468657920617265206b6570742068657265202d206f6e6c79207374616b696e672070616c6c6574206b6e6f77732061626f757420657261732e20546865550120696d706c656d656e746f72206f66205b6044697361626c696e675374726174656779605d20646566696e657320696620612076616c696461746f722073686f756c642062652064697361626c65642077686963686d0120696d706c696369746c79206d65616e7320746861742074686520696d706c656d656e746f7220616c736f20636f6e74726f6c7320746865206d6178206e756d626572206f662064697361626c65642076616c696461746f72732e006d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f72206861732070726576696f75736c7978206f6666656e646564207573696e672062696e617279207365617263682e384368696c6c5468726573686f6c640000f10104000c510120546865207468726573686f6c6420666f72207768656e2075736572732063616e2073746172742063616c6c696e6720606368696c6c5f6f746865726020666f72206f746865722076616c696461746f7273202f5901206e6f6d696e61746f72732e20546865207468726573686f6c6420697320636f6d706172656420746f207468652061637475616c206e756d626572206f662076616c696461746f7273202f206e6f6d696e61746f72732901202860436f756e74466f722a602920696e207468652073797374656d20636f6d706172656420746f2074686520636f6e66696775726564206d61782028604d61782a436f756e7460292e01390401ec1830486973746f72794465707468101050000000508c204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e00e820466f6c6c6f77696e6720696e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d090120486973746f727944657074682c2063757272656e745f6572615d603a2060457261735374616b657273602c2060457261735374616b657273436c6970706564602c050120604572617356616c696461746f725072656673602c20604572617356616c696461746f72526577617264602c206045726173526577617264506f696e7473602c4501206045726173546f74616c5374616b65602c206045726173537461727453657373696f6e496e646578602c2060436c61696d656452657761726473602c2060457261735374616b6572735061676564602c5c2060457261735374616b6572734f76657276696577602e00e4204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e2ef820492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203ec42063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e001101204966206d6967726174696e6720616e206578697374696e672070616c6c65742066726f6d2073746f726167652076616c756520746f20636f6e6669672076616c75652cec20746869732073686f756c642062652073657420746f2073616d652076616c7565206f72206772656174657220617320696e2073746f726167652e001501204e6f74653a2060486973746f727944657074686020697320757365642061732074686520757070657220626f756e6420666f72207468652060426f756e646564566563602d01206974656d20605374616b696e674c65646765722e6c65676163795f636c61696d65645f72657761726473602e2053657474696e6720746869732076616c7565206c6f776572207468616ed820746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865150120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e2061206d6967726174696f6e2ef020546865207465737420607265647563696e675f686973746f72795f64657074685f616272757074602073686f77732074686973206566666563742e3853657373696f6e735065724572611010030000000470204e756d626572206f662073657373696f6e7320706572206572612e3c426f6e64696e674475726174696f6e10100e00000004e4204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e48536c61736844656665724475726174696f6e10100a000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e4c4d61784578706f737572655061676553697a651010400000002cb020546865206d6178696d756d2073697a65206f6620656163682060543a3a4578706f7375726550616765602e00290120416e20604578706f737572655061676560206973207765616b6c7920626f756e64656420746f2061206d6178696d756d206f6620604d61784578706f737572655061676553697a656030206e6f6d696e61746f72732e00210120466f72206f6c646572206e6f6e2d7061676564206578706f737572652c206120726577617264207061796f757420776173207265737472696374656420746f2074686520746f70210120604d61784578706f737572655061676553697a6560206e6f6d696e61746f72732e205468697320697320746f206c696d69742074686520692f6f20636f737420666f722074686548206e6f6d696e61746f72207061796f75742e005901204e6f74653a20604d61784578706f737572655061676553697a6560206973207573656420746f20626f756e642060436c61696d6564526577617264736020616e6420697320756e7361666520746f207265647563659020776974686f75742068616e646c696e6720697420696e2061206d6967726174696f6e2e484d6178556e6c6f636b696e674368756e6b7310102000000028050120546865206d6178696d756d206e756d626572206f662060756e6c6f636b696e6760206368756e6b732061205b605374616b696e674c6564676572605d2063616e090120686176652e204566666563746976656c792064657465726d696e657320686f77206d616e7920756e6971756520657261732061207374616b6572206d61792062653820756e626f6e64696e6720696e2e00f8204e6f74653a20604d6178556e6c6f636b696e674368756e6b736020697320757365642061732074686520757070657220626f756e6420666f722074686501012060426f756e64656456656360206974656d20605374616b696e674c65646765722e756e6c6f636b696e67602e2053657474696e6720746869732076616c75650501206c6f776572207468616e20746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865090120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e20612072756e74696d650501206d6967726174696f6e2e20546865207465737420607265647563696e675f6d61785f756e6c6f636b696e675f6368756e6b735f616272757074602073686f7773342074686973206566666563742e01c908111c53657373696f6e011c53657373696f6e1c2856616c696461746f7273010039020400047c205468652063757272656e7420736574206f662076616c696461746f72732e3043757272656e74496e646578010010100000000004782043757272656e7420696e646578206f66207468652073657373696f6e2e345175657565644368616e676564010020040008390120547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f7273a420686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e285175657565644b6579730100cd080400083d012054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b657973e02077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e4844697361626c656456616c696461746f7273010041040400148020496e6469636573206f662064697361626c65642076616c696461746f72732e003d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f722069733d012064697361626c6564207573696e672062696e617279207365617263682e204974206765747320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e73642061206e657720736574206f66206964656e7469746965732e204e6578744b657973000104050071040400049c20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e204b65794f776e657200010405d50800040004090120546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e016d040105010001dd081228486973746f726963616c0128486973746f726963616c0848486973746f726963616c53657373696f6e730001040510e1080400045d01204d617070696e672066726f6d20686973746f726963616c2073657373696f6e20696e646963657320746f2073657373696f6e2d6461746120726f6f74206861736820616e642076616c696461746f7220636f756e742e2c53746f72656452616e67650000b908040004e4205468652072616e6765206f6620686973746f726963616c2073657373696f6e732077652073746f72652e205b66697273742c206c61737429000000001320547265617375727901205472656173757279183450726f706f73616c436f756e74010010100000000004a4204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e2450726f706f73616c730001040510e5080400047c2050726f706f73616c7320746861742068617665206265656e206d6164652e2c4465616374697661746564010018400000000000000000000000000000000004f02054686520616d6f756e7420776869636820686173206265656e207265706f7274656420617320696e61637469766520746f2043757272656e63792e24417070726f76616c730100e908040004f82050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e285370656e64436f756e74010010100000000004a42054686520636f756e74206f66207370656e647320746861742068617665206265656e206d6164652e185370656e64730001040510ed08040004d0205370656e647320746861742068617665206265656e20617070726f76656420616e64206265696e672070726f6365737365642e017504010901142c5370656e64506572696f6430204038000000000000048820506572696f64206265747765656e2073756363657373697665207370656e64732e104275726ed10110000000000411012050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e2050616c6c65744964f5082070792f74727372790419012054686520747265617375727927732070616c6c65742069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e304d6178417070726f76616c731010640000000c150120546865206d6178696d756d206e756d626572206f6620617070726f76616c7320746861742063616e207761697420696e20746865207370656e64696e672071756575652e004d01204e4f54453a205468697320706172616d6574657220697320616c736f20757365642077697468696e2074686520426f756e746965732050616c6c657420657874656e73696f6e20696620656e61626c65642e305061796f7574506572696f6430200a000000000000000419012054686520706572696f6420647572696e6720776869636820616e20617070726f766564207472656173757279207370656e642068617320746f20626520636c61696d65642e01f9081420426f756e746965730120426f756e74696573102c426f756e7479436f756e74010010100000000004c0204e756d626572206f6620626f756e74792070726f706f73616c7320746861742068617665206265656e206d6164652e20426f756e746965730001040510fd080400047820426f756e7469657320746861742068617665206265656e206d6164652e48426f756e74794465736372697074696f6e73000104051005090400048020546865206465736372697074696f6e206f66206561636820626f756e74792e3c426f756e7479417070726f76616c730100e908040004ec20426f756e747920696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f74207965742066756e6465642e017d04010d012444426f756e74794465706f736974426173651840000064a7b3b6e00d000000000000000004e82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120626f756e74792070726f706f73616c2e60426f756e74794465706f7369745061796f757444656c617930204038000000000000045901205468652064656c617920706572696f6420666f72207768696368206120626f756e74792062656e6566696369617279206e65656420746f2077616974206265666f726520636c61696d20746865207061796f75742e48426f756e7479557064617465506572696f6430208013030000000000046c20426f756e7479206475726174696f6e20696e20626c6f636b732e6043757261746f724465706f7369744d756c7469706c696572d1011020a10700101901205468652063757261746f72206465706f7369742069732063616c63756c6174656420617320612070657263656e74616765206f66207468652063757261746f72206665652e0039012054686973206465706f73697420686173206f7074696f6e616c20757070657220616e64206c6f77657220626f756e64732077697468206043757261746f724465706f7369744d61786020616e6454206043757261746f724465706f7369744d696e602e4443757261746f724465706f7369744d617859044401000010632d5ec76b0500000000000000044901204d6178696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e4443757261746f724465706f7369744d696e59044401000064a7b3b6e00d0000000000000000044901204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e48426f756e747956616c75654d696e696d756d18400000f4448291634500000000000000000470204d696e696d756d2076616c756520666f72206120626f756e74792e48446174614465706f73697450657242797465184000008a5d7845630100000000000000000461012054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e206f7220626f756e7479206465736372697074696f6e2e4c4d6178696d756d526561736f6e4c656e67746810102c0100000c88204d6178696d756d2061636365707461626c6520726561736f6e206c656e6774682e0065012042656e63686d61726b7320646570656e64206f6e20746869732076616c75652c206265207375726520746f2075706461746520776569676874732066696c65207768656e206368616e67696e6720746869732076616c756501090915344368696c64426f756e7469657301344368696c64426f756e7469657314404368696c64426f756e7479436f756e7401001010000000000480204e756d626572206f6620746f74616c206368696c6420626f756e746965732e4c506172656e744368696c64426f756e74696573010104051010100000000008b0204e756d626572206f66206368696c6420626f756e746965732070657220706172656e7420626f756e74792ee0204d6170206f6620706172656e7420626f756e747920696e64657820746f206e756d626572206f66206368696c6420626f756e746965732e344368696c64426f756e746965730001080505b9080d0904000494204368696c6420626f756e7469657320746861742068617665206265656e2061646465642e5c4368696c64426f756e74794465736372697074696f6e73000104051005090400049820546865206465736372697074696f6e206f662065616368206368696c642d626f756e74792e4c4368696c6472656e43757261746f72466565730101040510184000000000000000000000000000000000040101205468652063756d756c6174697665206368696c642d626f756e74792063757261746f722066656520666f72206561636820706172656e7420626f756e74792e01810401110108644d61784163746976654368696c64426f756e7479436f756e74101005000000041d01204d6178696d756d206e756d626572206f66206368696c6420626f756e7469657320746861742063616e20626520616464656420746f206120706172656e7420626f756e74792e5c4368696c64426f756e747956616c75654d696e696d756d1840000064a7b3b6e00d00000000000000000488204d696e696d756d2076616c756520666f722061206368696c642d626f756e74792e0115091620426167734c6973740120426167734c6973740c244c6973744e6f6465730001040500190904000c8020412073696e676c65206e6f64652c2077697468696e20736f6d65206261672e000501204e6f6465732073746f7265206c696e6b7320666f727761726420616e64206261636b2077697468696e207468656972207265737065637469766520626167732e4c436f756e746572466f724c6973744e6f646573010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204c6973744261677300010405301d0904000c642041206261672073746f72656420696e2073746f726167652e0019012053746f7265732061206042616760207374727563742c2077686963682073746f726573206865616420616e64207461696c20706f696e7465727320746f20697473656c662e01850401150104344261675468726573686f6c647311060919210300407a10f35a00006a70ccd4a96000009ef3397fbc660000a907ccd5306d00003d9a67fb0c740000a9bfa275577b0000a6fdf73217830000034f5d91538b0000132445651494000078081001629d00000302f63c45a70000392e6f7fc7b10000f59c23c6f2bc00004ae76aafd1c80000598a64846fd50000129fb243d8e200003f22e1ac18f1000033a4844c3e000100e2e51b895710010076a2c0b0732101006789b407a3330100793ed8d7f646010078131b81815b01000c1cf38a567101004437eeb68a8801009eb56d1434a10100335e9f156abb010067c3c7a545d701003218f340e1f40100de0b230d59140200699c11f5ca350200ad50a2c4565902009ae41c471e7f0200d0244e6745a70200f984ad51f2d10200ace7a7984dff0200a118325b822f0300ffa4c76dbe620300580bfd8532990300a9afce6812d30300109ad81b95100400d9caa519f551040038df488970970400bee1727949e10400cc73401fc62f0500b304f91831830500828bffb4d9db05001235383d143a0600a5b42a473a9e060036662d09ab080700f73aeab4cb790700b87e93d707f20700ffec23c0d1710800b84b0beca2f90800c9dcae7afc89090091752ba867230a0064f1cd4f76c60a003609be76c3730b0078655fdff32b0c00a407f5a5b6ef0c0052f61be7c5bf0d00da71bb70e79c0e000de9127eed870f001477987fb7811000ebee65ef328b11001269fe325ca5120033f8428b3fd113008ba57a13fa0f15001b2b60d0ba6216000d1d37d0c3ca17006c64fa5c6b4919002622c7411de01a00045bb9245c901c00233d83f6c25b1e00c8771c79064420003013fddef64a2200aa8b6e848172240082c096c4b2bc260016a3faebb72b29008296524ae1c12b00a636a865a4812e00d0e2d4509e6d31009c0a9a2796883400e4faafb27fd53700e6e64d367e573b000e4bd66de7113f0088b17db746084300b07def72603e470034de249635b84b00d48bd57b077a5000d0bd20ef5b885500b8f0467801e85a0010f88aee139e60003892925301b066009c95e4fc8e236d00b4126d10dffe730028b43e5976487b00a08a1c7a42078300b09ab083a0428b002846b2f463029400c861a42ade4e9d0050d23d4ae630a700805101a7e1b1b10038e501b2ccdbbc002016527844b9c800388924ba9055d50070ca35a4aebce200805fb1355cfbf0008035685d241f0001a0c3dcd96b361001d07862e87e50210160e852d09f7d330190662c5816cf460110274c3340575b01804be277a22971013082b92dfc5a880180d276075a01a101b0f511592b34bb014031745f580cd701802f6cee59a4f40140ff799b521814026075607d2986350260fde999a60d590200e5e71c91d07e02c0df2575cff2a602a07fd975899ad102a067009d4cf0fe0220dc29a1321f2f0320ff526b0a5562038088caa383c29803e05683fb5c9bd203401dd75d9516100400317e39a06e5104c0b071129de1960480b48c9192b1e00480e8124aad242f05c007ca7082858205007c13c45623db0540836fe869523906c0700f81466c9d0640f09c5017d00707c0e624b301e37807c0332ac78510f10780074ca1e4ca700800d5a9eb8c8bf80800a849588ed3880900804254142c220a80a25170e826c50a00e8d5fafc5e720b801df64e00792a0c80d4fe64f923ee0c006dd038ee19be0d001e90a494209b0e0010bf570e0a860f00da6a9db0b57f1000bf64afd810891100bb5b60cd17a31200f963f3aed6ce1300d5f004766a0d1500e099770202601600103d663bdfc71700de3e2d4158461900ecdbadb2d8dc1a0045c70007e38c1c00b8bde0fc11581e00ba5c2a211a402000407de46dcb462200dea55b03136e2400aaf1f3fcfcb7260014226f63b62629006492803e8fbc2b008486a6c7fc7b2e002cf05fc09b673100da63f7ed32823400f0b13fbdb5ce3700f291c41047503b00422a1a3c3c0a3f002c24212f20004300ac9342d4b6354700cc6ed7a400af4b00c4d022773e70500020017d89f57d5500f86387cef3dc5a008c4c7f7e54926000206207f284a36600cc1e05cb49166d00b42a7a70c4f07300d43a90e278397b0038f461ec53f78200a07264b9b1318b0048c9b3d464f09300007fe998bd3b9d0010058f17921ca70000dfaf7f469cb100e80c880bd6c4bc0058bdcb7ddca0c80038d18d37a03bd50030d55bf01ca1e200704ac01a0fdef0ffffffffffffffffacd020546865206c697374206f66207468726573686f6c64732073657061726174696e672074686520766172696f757320626167732e00490120496473206172652073657061726174656420696e746f20756e736f727465642062616773206163636f7264696e6720746f2074686569722073636f72652e205468697320737065636966696573207468656101207468726573686f6c64732073657061726174696e672074686520626167732e20416e20696427732062616720697320746865206c6172676573742062616720666f722077686963682074686520696427732073636f7265b8206973206c657373207468616e206f7220657175616c20746f20697473207570706572207468726573686f6c642e006501205768656e20696473206172652069746572617465642c2068696768657220626167732061726520697465726174656420636f6d706c6574656c79206265666f7265206c6f77657220626167732e2054686973206d65616e735901207468617420697465726174696f6e206973205f73656d692d736f727465645f3a20696473206f66206869676865722073636f72652074656e6420746f20636f6d65206265666f726520696473206f66206c6f7765722d012073636f72652c206275742070656572206964732077697468696e206120706172746963756c6172206261672061726520736f7274656420696e20696e73657274696f6e206f726465722e006820232045787072657373696e672074686520636f6e7374616e74004d01205468697320636f6e7374616e74206d75737420626520736f7274656420696e207374726963746c7920696e6372656173696e67206f726465722e204475706c6963617465206974656d7320617265206e6f742c207065726d69747465642e00410120546865726520697320616e20696d706c696564207570706572206c696d6974206f66206053636f72653a3a4d4158603b20746861742076616c756520646f6573206e6f74206e65656420746f2062652101207370656369666965642077697468696e20746865206261672e20466f7220616e792074776f207468726573686f6c64206c697374732c206966206f6e6520656e647320776974683101206053636f72653a3a4d4158602c20746865206f74686572206f6e6520646f6573206e6f742c20616e64207468657920617265206f746865727769736520657175616c2c207468652074776f7c206c697374732077696c6c20626568617665206964656e746963616c6c792e003820232043616c63756c6174696f6e005501204974206973207265636f6d6d656e64656420746f2067656e65726174652074686520736574206f66207468726573686f6c647320696e20612067656f6d6574726963207365726965732c2073756368207468617441012074686572652065786973747320736f6d6520636f6e7374616e7420726174696f2073756368207468617420607468726573686f6c645b6b202b20315d203d3d20287468726573686f6c645b6b5d202ad020636f6e7374616e745f726174696f292e6d6178287468726573686f6c645b6b5d202b2031296020666f7220616c6c20606b602e005901205468652068656c7065727320696e2074686520602f7574696c732f6672616d652f67656e65726174652d6261677360206d6f64756c652063616e2073696d706c69667920746869732063616c63756c6174696f6e2e002c2023204578616d706c6573005101202d20496620604261675468726573686f6c64733a3a67657428292e69735f656d7074792829602c207468656e20616c6c20696473206172652070757420696e746f207468652073616d65206261672c20616e64b0202020697465726174696f6e206973207374726963746c7920696e20696e73657274696f6e206f726465722e6101202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d203634602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f11012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320657175616c20746f20322e6501202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d20323030602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f59012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320617070726f78696d6174656c7920657175616c20746f20312e3234382e6101202d20496620746865207468726573686f6c64206c69737420626567696e7320605b312c20322c20332c202e2e2e5d602c207468656e20616e20696420776974682073636f72652030206f7220312077696c6c2066616c6cf0202020696e746f2062616720302c20616e20696420776974682073636f726520322077696c6c2066616c6c20696e746f2062616720312c206574632e00302023204d6967726174696f6e00610120496e20746865206576656e7420746861742074686973206c6973742065766572206368616e6765732c206120636f7079206f6620746865206f6c642062616773206c697374206d7573742062652072657461696e65642e5d012057697468207468617420604c6973743a3a6d696772617465602063616e2062652063616c6c65642c2077686963682077696c6c20706572666f726d2074686520617070726f707269617465206d6967726174696f6e2e012109173c4e6f6d696e6174696f6e506f6f6c73013c4e6f6d696e6174696f6e506f6f6c735440546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e384d6178506f6f6c4d656d626572730000100400084901204d6178696d756d206e756d626572206f66206d656d6265727320746861742063616e20657869737420696e207468652073797374656d2e20496620604e6f6e65602c207468656e2074686520636f756e74b8206d656d6265727320617265206e6f7420626f756e64206f6e20612073797374656d20776964652062617369732e544d6178506f6f6c4d656d62657273506572506f6f6c0000100400084101204d6178696d756d206e756d626572206f66206d656d626572732074686174206d61792062656c6f6e6720746f20706f6f6c2e20496620604e6f6e65602c207468656e2074686520636f756e74206f66a8206d656d62657273206973206e6f7420626f756e64206f6e20612070657220706f6f6c2062617369732e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c506f6f6c4d656d626572730001040500290904000c4020416374697665206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e54436f756e746572466f72506f6f6c4d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c426f6e646564506f6f6c7300010405103d09040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510510904000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f7574206f66207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f726167650001040510550904000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d65746164617461010104051055010400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e4c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0075012054686973206973206f6e6c79207573656420666f7220736c617368696e6720616e64206f6e206175746f6d61746963207769746864726177207570646174652e20496e20616c6c206f7468657220696e7374616e6365732c20746865250120706f6f6c20696420697320757365642c20616e6420746865206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500a1040402040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e0189040119010c2050616c6c65744964f5082070792f6e6f706c73048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101008000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e016d0918245363686564756c657201245363686564756c6572103c496e636f6d706c65746553696e6365000030040000184167656e6461010104053075090400044d01204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e1c526574726965730001040239018509040004210120526574727920636f6e66696775726174696f6e7320666f72206974656d7320746f2062652065786563757465642c20696e6465786564206279207461736b20616464726573732e184c6f6f6b757000010405043901040010f8204c6f6f6b75702066726f6d2061206e616d6520746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e00590120466f72207633202d3e207634207468652070726576696f75736c7920756e626f756e646564206964656e7469746965732061726520426c616b65322d3235362068617368656420746f20666f726d2074686520763430206964656e7469746965732e01a50401350108344d6178696d756d57656967687428400b00806e87740113cccccccccccccccc04290120546865206d6178696d756d207765696768742074686174206d6179206265207363686564756c65642070657220626c6f636b20666f7220616e7920646973706174636861626c65732e504d61785363686564756c6564506572426c6f636b101000020000141d0120546865206d6178696d756d206e756d626572206f66207363686564756c65642063616c6c7320696e2074686520717565756520666f7220612073696e676c6520626c6f636b2e0018204e4f54453a5101202b20446570656e64656e742070616c6c657473272062656e63686d61726b73206d696768742072657175697265206120686967686572206c696d697420666f72207468652073657474696e672e205365742061c420686967686572206c696d697420756e646572206072756e74696d652d62656e63686d61726b736020666561747572652e0189091920507265696d6167650120507265696d6167650c24537461747573466f7200010406348d090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e4052657175657374537461747573466f72000104063495090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e2c507265696d616765466f7200010406e108a10904000001ad040141010001a5091a204f6666656e63657301204f6666656e636573081c5265706f7274730001040534a909040004490120546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e58436f6e63757272656e745265706f727473496e6465780101080505ad09c1010400042901204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e0001450100001b1c54785061757365011c54785061757365042c50617573656443616c6c7300010402510184040004b42054686520736574206f662063616c6c73207468617420617265206578706c696369746c79207061757365642e01b104014d0104284d61784e616d654c656e1010000100000c2501204d6178696d756d206c656e67746820666f722070616c6c6574206e616d6520616e642063616c6c206e616d65205343414c4520656e636f64656420737472696e67206e616d65732e00a820544f4f204c4f4e47204e414d45532057494c4c2042452054524541544544204153205041555345442e01b1091c20496d4f6e6c696e650120496d4f6e6c696e65103848656172746265617441667465720100302000000000000000002c1d012054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e207468652063757272656e74242073657373696f6e2e0025012041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c350120726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f721901207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f207468617420746865a820686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00390120546869732076616c75652077696c6c206f6e6c79206265207573656420617320612066616c6c6261636b206966207765206661696c20746f2067657420612070726f7065722073657373696f6e2d012070726f677265737320657374696d6174652066726f6d20604e65787453657373696f6e526f746174696f6e602c2061732074686f736520657374696d617465732073686f756c642062650101206d6f7265206163637572617465207468656e207468652076616c75652077652063616c63756c61746520666f7220604865617274626561744166746572602e104b6579730100b509040004d0205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e485265636569766564486561727462656174730001080505b90820040004350120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206053657373696f6e496e6465786020616e64206041757468496e646578602e38417574686f726564426c6f636b7301010805058d0810100000000008150120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206056616c696461746f7249643c543e6020746f20746865c8206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e01b5040159010440556e7369676e65645072696f726974793020ffffffffffffffff10f0204120636f6e66696775726174696f6e20666f722062617365207072696f72697479206f6620756e7369676e6564207472616e73616374696f6e732e0015012054686973206973206578706f73656420736f20746861742069742063616e2062652074756e656420666f7220706172746963756c61722072756e74696d652c207768656eb4206d756c7469706c652070616c6c6574732073656e6420756e7369676e6564207472616e73616374696f6e732e01bd091d204964656e7469747901204964656e746974791c284964656e746974794f660001040500c109040010690120496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e204669727374206974656d20697320746865e020726567697374726174696f6e2c207365636f6e6420697320746865206163636f756e742773207072696d61727920757365726e616d652e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e1c53757065724f66000104020051050400086101205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e2074686174510120636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e18537562734f660101040500d90944000000000000000000000000000000000014b820416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e001d0120546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e28526567697374726172730100e1090400104d012054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061a8207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e0029012054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e4c557365726e616d65417574686f7269746965730001040500f109040004f42041206d6170206f6620746865206163636f756e74732077686f2061726520617574686f72697a656420746f206772616e7420757365726e616d65732e444163636f756e744f66557365726e616d65000104027d01000400146d012052657665727365206c6f6f6b75702066726f6d2060757365726e616d656020746f2074686520604163636f756e7449646020746861742068617320726567697374657265642069742e205468652076616c75652073686f756c6465012062652061206b657920696e2074686520604964656e746974794f6660206d61702c20627574206974206d6179206e6f742069662074686520757365722068617320636c6561726564207468656972206964656e746974792e006901204d756c7469706c6520757365726e616d6573206d6179206d617020746f207468652073616d6520604163636f756e744964602c2062757420604964656e746974794f66602077696c6c206f6e6c79206d617020746f206f6e6548207072696d61727920757365726e616d652e4050656e64696e67557365726e616d6573000104027d01f9090400186d0120557365726e616d6573207468617420616e20617574686f7269747920686173206772616e7465642c20627574207468617420746865206163636f756e7420636f6e74726f6c6c657220686173206e6f7420636f6e6669726d65647101207468617420746865792077616e742069742e2055736564207072696d6172696c7920696e2063617365732077686572652074686520604163636f756e744964602063616e6e6f742070726f766964652061207369676e61747572655d012062656361757365207468657920617265206120707572652070726f78792c206d756c74697369672c206574632e20496e206f7264657220746f20636f6e6669726d2069742c20746865792073686f756c642063616c6c6c205b6043616c6c3a3a6163636570745f757365726e616d65605d2e001d01204669727374207475706c65206974656d20697320746865206163636f756e7420616e64207365636f6e642069732074686520616363657074616e636520646561646c696e652e01c104017901203042617369634465706f7369741840000064a7b3b6e00d000000000000000004d82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e2c427974654465706f7369741840000064a7b3b6e00d0000000000000000041d012054686520616d6f756e742068656c64206f6e206465706f7369742070657220656e636f646564206279746520666f7220612072656769737465726564206964656e746974792e445375624163636f756e744465706f73697418400000d1d21fe5ea6b05000000000000000c65012054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f7220746865206661637465012074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c350120626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e384d61785375624163636f756e7473101064000000040d0120546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e344d617852656769737472617273101014000000084d01204d6178696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c65786974797c206f662c20652e672e2c207570646174696e67206a756467656d656e74732e6450656e64696e67557365726e616d6545787069726174696f6e3020c08901000000000004150120546865206e756d626572206f6620626c6f636b732077697468696e207768696368206120757365726e616d65206772616e74206d7573742062652061636365707465642e3c4d61785375666669784c656e677468101007000000048020546865206d6178696d756d206c656e677468206f662061207375666669782e444d6178557365726e616d654c656e67746810102000000004610120546865206d6178696d756d206c656e677468206f66206120757365726e616d652c20696e636c7564696e67206974732073756666697820616e6420616e792073797374656d2d61646465642064656c696d69746572732e01fd091e1c5574696c69747900016505018101044c626174636865645f63616c6c735f6c696d69741010aa2a000004a820546865206c696d6974206f6e20746865206e756d626572206f6620626174636865642063616c6c732e01010a1f204d756c746973696701204d756c746973696704244d756c7469736967730001080502050a090a040004942054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e017d050185010c2c4465706f736974426173651840000068cd83c1fd77050000000000000018590120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e672061206d756c746973696720657865637574696f6e206f7220746f842073746f726520612064697370617463682063616c6c20666f72206c617465722e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069733101206034202b2073697a656f662828426c6f636b4e756d6265722c2042616c616e63652c204163636f756e74496429296020627974657320616e642077686f7365206b65792073697a652069738020603332202b2073697a656f66284163636f756e74496429602062797465732e344465706f736974466163746f721840000020f84dde700400000000000000000c55012054686520616d6f756e74206f662063757272656e6379206e65656465642070657220756e6974207468726573686f6c64207768656e206372656174696e672061206d756c746973696720657865637574696f6e2e00250120546869732069732068656c6420666f7220616464696e67203332206279746573206d6f726520696e746f2061207072652d6578697374696e672073746f726167652076616c75652e384d61785369676e61746f7269657310106400000004ec20546865206d6178696d756d20616d6f756e74206f66207369676e61746f7269657320616c6c6f77656420696e20746865206d756c74697369672e010d0a2020457468657265756d0120457468657265756d141c50656e64696e670100110a040004d02043757272656e74206275696c64696e6720626c6f636b2773207472616e73616374696f6e7320616e642072656365697074732e3043757272656e74426c6f636b0000350a04000470205468652063757272656e7420457468657265756d20626c6f636b2e3c43757272656e7452656365697074730000490a0400047c205468652063757272656e7420457468657265756d2072656365697074732e6843757272656e745472616e73616374696f6e537461747573657300004d0a04000488205468652063757272656e74207472616e73616374696f6e2073746174757365732e24426c6f636b4861736801010405c9013480000000000000000000000000000000000000000000000000000000000000000000018505018d010001510a210c45564d010c45564d10304163636f756e74436f64657301010402910138040000504163636f756e74436f6465734d65746164617461000104029101550a0400003c4163636f756e7453746f72616765730101080202590a34800000000000000000000000000000000000000000000000000000000000000000002053756963696465640001040291018404000001ad0501b90100015d0a222845564d436861696e4964012845564d436861696e4964041c436861696e49640100302000000000000000000448205468652045564d20636861696e2049442e00000000232844796e616d6963466565012844796e616d6963466565082c4d696e47617350726963650100c90180000000000000000000000000000000000000000000000000000000000000000000445461726765744d696e47617350726963650000c90104000001bd05000000241c42617365466565011c426173654665650834426173654665655065724761730100c9018040420f00000000000000000000000000000000000000000000000000000000000028456c61737469636974790100d1011048e801000001c10501c50100002544486f7466697853756666696369656e74730001c505000001610a2618436c61696d730118436c61696d731418436c61696d7300010406d9011804000014546f74616c01001840000000000000000000000000000000000030457870697279436f6e6669670000650a040004c82045787069727920626c6f636b20616e64206163636f756e7420746f206465706f73697420657870697265642066756e64731c56657374696e6700010406d901e505040010782056657374696e67207363686564756c6520666f72206120636c61696d2e0d012046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672ee4205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2ecc2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e1c5369676e696e6700010406d901f505040004c0205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e01cd0501d5010418507265666978386c68436c61696d20544e547320746f20746865206163636f756e743a0001690a271450726f7879011450726f7879081c50726f7869657301010405006d0a4400000000000000000000000000000000000845012054686520736574206f66206163636f756e742070726f786965732e204d61707320746865206163636f756e74207768696368206861732064656c65676174656420746f20746865206163636f756e7473210120776869636820617265206265696e672064656c65676174656420746f2c20746f67657468657220776974682074686520616d6f756e742068656c64206f6e206465706f7369742e34416e6e6f756e63656d656e747301010405007d0a44000000000000000000000000000000000004ac2054686520616e6e6f756e63656d656e7473206d616465206279207468652070726f787920286b6579292e01f90501e101184050726f78794465706f736974426173651840000018e1c095e36c050000000000000010110120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720612070726f78792e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069732501206073697a656f662842616c616e6365296020627974657320616e642077686f7365206b65792073697a65206973206073697a656f66284163636f756e74496429602062797465732e4850726f78794465706f736974466163746f7218400000e16740659404000000000000000014bc2054686520616d6f756e74206f662063757272656e6379206e6565646564207065722070726f78792061646465642e00350120546869732069732068656c6420666f7220616464696e6720333220627974657320706c757320616e20696e7374616e6365206f66206050726f78795479706560206d6f726520696e746f20616101207072652d6578697374696e672073746f726167652076616c75652e20546875732c207768656e20636f6e6669677572696e67206050726f78794465706f736974466163746f7260206f6e652073686f756c642074616b65f420696e746f206163636f756e7420603332202b2070726f78795f747970652e656e636f646528292e6c656e282960206279746573206f6620646174612e284d617850726f7869657310102000000004f020546865206d6178696d756d20616d6f756e74206f662070726f7869657320616c6c6f77656420666f7220612073696e676c65206163636f756e742e284d617850656e64696e6710102000000004450120546865206d6178696d756d20616d6f756e74206f662074696d652d64656c6179656420616e6e6f756e63656d656e747320746861742061726520616c6c6f77656420746f2062652070656e64696e672e5c416e6e6f756e63656d656e744465706f736974426173651840000018e1c095e36c050000000000000010310120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720616e20616e6e6f756e63656d656e742e00490120546869732069732068656c64207768656e2061206e65772073746f72616765206974656d20686f6c64696e672061206042616c616e636560206973206372656174656420287479706963616c6c7920313620206279746573292e64416e6e6f756e63656d656e744465706f736974466163746f7218400000c2cf80ca2809000000000000000010d42054686520616d6f756e74206f662063757272656e6379206e65656465642070657220616e6e6f756e63656d656e74206d6164652e00590120546869732069732068656c6420666f7220616464696e6720616e20604163636f756e744964602c2060486173686020616e642060426c6f636b4e756d6265726020287479706963616c6c79203638206279746573298c20696e746f2061207072652d6578697374696e672073746f726167652076616c75652e018d0a2c504d756c7469417373657444656c65676174696f6e01504d756c7469417373657444656c65676174696f6e1c244f70657261746f72730001040200910a040004882053746f7261676520666f72206f70657261746f7220696e666f726d6174696f6e2e3043757272656e74526f756e640100101000000000047c2053746f7261676520666f72207468652063757272656e7420726f756e642e1c41745374616b6500010802028d08b90a040004050120536e617073686f74206f6620636f6c6c61746f722064656c65676174696f6e207374616b6520617420746865207374617274206f662074686520726f756e642e2844656c656761746f72730001040200bd0a0400048c2053746f7261676520666f722064656c656761746f7220696e666f726d6174696f6e2e305265776172645661756c747300010402183d02040004782053746f7261676520666f722074686520726577617264207661756c74735c41737365744c6f6f6b75705265776172645661756c7473000104021818040004782053746f7261676520666f722074686520726577617264207661756c74734c526577617264436f6e66696753746f726167650000fd0a04000869012053746f7261676520666f72207468652072657761726420636f6e66696775726174696f6e2c20776869636820696e636c75646573204150592c2063617020666f72206173736574732c20616e642077686974656c69737465643020626c75657072696e74732e01010601ed0130584d617844656c656761746f72426c75657072696e747310103200000004150120546865206d6178696d756d206e756d626572206f6620626c75657072696e747320612064656c656761746f722063616e206861766520696e204669786564206d6f64652e544d61784f70657261746f72426c75657072696e747310103200000004e820546865206d6178696d756d206e756d626572206f6620626c75657072696e747320616e206f70657261746f722063616e20737570706f72742e4c4d61785769746864726177526571756573747310100500000004f820546865206d6178696d756d206e756d626572206f6620776974686472617720726571756573747320612064656c656761746f722063616e20686176652e384d617844656c65676174696f6e7310103200000004e020546865206d6178696d756d206e756d626572206f662064656c65676174696f6e7320612064656c656761746f722063616e20686176652e484d6178556e7374616b65526571756573747310100500000004f420546865206d6178696d756d206e756d626572206f6620756e7374616b6520726571756573747320612064656c656761746f722063616e20686176652e544d696e4f70657261746f72426f6e64416d6f756e7418401027000000000000000000000000000004d820546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220616e206f70657261746f722e444d696e44656c6567617465416d6f756e741840e803000000000000000000000000000004d420546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220612064656c65676174652e30426f6e644475726174696f6e10100a00000004b020546865206475726174696f6e20666f7220776869636820746865207374616b65206973206c6f636b65642e4c4c656176654f70657261746f727344656c617910100a000000045501204e756d626572206f6620726f756e64732074686174206f70657261746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e544f70657261746f72426f6e644c65737344656c6179101001000000045901204e756d626572206f6620726f756e6473206f70657261746f7220726571756573747320746f2064656372656173652073656c662d7374616b65206d757374207761697420746f2062652065786563757461626c652e504c6561766544656c656761746f727344656c6179101001000000045901204e756d626572206f6620726f756e647320746861742064656c656761746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e5c44656c65676174696f6e426f6e644c65737344656c6179101005000000045501204e756d626572206f6620726f756e647320746861742064656c65676174696f6e20756e7374616b65207265717565737473206d7573742077616974206265666f7265206265696e672065786563757461626c652e01110b2d205365727669636573012053657276696365733c3c4e657874426c75657072696e74496401003020000000000000000004a820546865206e657874206672656520494420666f722061207365727669636520626c75657072696e742e504e6578745365727669636552657175657374496401003020000000000000000004a020546865206e657874206672656520494420666f722061207365727669636520726571756573742e384e657874496e7374616e6365496401003020000000000000000004a420546865206e657874206672656520494420666f722061207365727669636520496e7374616e63652e344e6578744a6f6243616c6c4964010030200000000000000000049420546865206e657874206672656520494420666f72206120736572766963652063616c6c2e5c4e657874556e6170706c696564536c617368496e646578010010100000000004a020546865206e657874206672656520494420666f72206120756e6170706c69656420736c6173682e28426c75657072696e74730001040630150b08010004bc20546865207365727669636520626c75657072696e747320616c6f6e672077697468207468656972206f776e65722e244f70657261746f72730001080606190bfd0108010908c020546865206f70657261746f727320666f722061207370656369666963207365727669636520626c75657072696e742ec420426c75657072696e74204944202d3e204f70657261746f72202d3e204f70657261746f7220507265666572656e6365733c53657276696365526571756573747300010406301d0b08010c08b420546865207365727669636520726571756573747320616c6f6e672077697468207468656972206f776e65722e782052657175657374204944202d3e2053657276696365205265717565737424496e7374616e63657300010406303d0b08010e085c2054686520536572766963657320496e7374616e636573582053657276696365204944202d3e20536572766963653055736572536572766963657301010406004d0b0400085c2055736572205365727669636520496e7374616e636573782055736572204163636f756e74204944202d3e2053657276696365204944204a6f6243616c6c730001080606e502550b0801170858205468652053657276696365204a6f622043616c6c73882053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c284a6f62526573756c74730001080606e502590b0801170874205468652053657276696365204a6f622043616c6c20526573756c7473a42053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c20526573756c7440556e6170706c696564536c61736865730001080606b9085d0b0801240cc420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e009020457261496e646578202d3e20496e646578202d3e20556e6170706c696564536c617368984d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e730100610b04000cd420416c6c20746865204d617374657220426c75657072696e742053657276696365204d616e6167657273207265766973696f6e732e00a02057686572652074686520696e64657820697320746865207265766973696f6e206e756d6265722e404f70657261746f727350726f66696c650001040600650b08011b0001150601f9015c4050616c6c657445564d4164647265737391015011111111111111111111111111111111111111110458206050616c6c6574602045564d20416464726573732e244d61784669656c647310100001000004a0204d6178696d756d206e756d626572206f66206669656c647320696e2061206a6f622063616c6c2e344d61784669656c647353697a65101000040000049c204d6178696d756d2073697a65206f662061206669656c6420696e2061206a6f622063616c6c2e444d61784d657461646174614c656e67746810100004000004a8204d6178696d756d206c656e677468206f66206d6574616461746120737472696e67206c656e6774682e444d61784a6f6273506572536572766963651010000400000490204d6178696d756d206e756d626572206f66206a6f62732070657220736572766963652e584d61784f70657261746f72735065725365727669636510100004000004a4204d6178696d756d206e756d626572206f66204f70657261746f72732070657220736572766963652e4c4d61785065726d697474656443616c6c65727310100001000004c4204d6178696d756d206e756d626572206f66207065726d69747465642063616c6c6572732070657220736572766963652e584d617853657276696365735065724f70657261746f7210100004000004a4204d6178696d756d206e756d626572206f6620736572766963657320706572206f70657261746f722e604d6178426c75657072696e74735065724f70657261746f7210100004000004ac204d6178696d756d206e756d626572206f6620626c75657072696e747320706572206f70657261746f722e484d61785365727669636573506572557365721010000400000494204d6178696d756d206e756d626572206f662073657276696365732070657220757365722e504d617842696e6172696573506572476164676574101040000000049c204d6178696d756d206e756d626572206f662062696e617269657320706572206761646765742e4c4d6178536f75726365735065724761646765741010400000000498204d6178696d756d206e756d626572206f6620736f757263657320706572206761646765742e444d61784769744f776e65724c656e677468101000040000046820476974206f776e6572206d6178696d756d206c656e6774682e404d61784769745265706f4c656e677468101000040000047c20476974207265706f7369746f7279206d6178696d756d206c656e6774682e3c4d61784769745461674c656e67746810100004000004602047697420746167206d6178696d756d206c656e6774682e4c4d617842696e6172794e616d654c656e67746810100004000004702062696e617279206e616d65206d6178696d756d206c656e6774682e444d617849706673486173684c656e67746810102e000000046820495046532068617368206d6178696d756d206c656e6774682e684d6178436f6e7461696e657252656769737472794c656e677468101000040000048c20436f6e7461696e6572207265676973747279206d6178696d756d206c656e6774682e6c4d6178436f6e7461696e6572496d6167654e616d654c656e677468101000040000049420436f6e7461696e657220696d616765206e616d65206d6178696d756d206c656e6774682e684d6178436f6e7461696e6572496d6167655461674c656e677468101000040000049020436f6e7461696e657220696d61676520746167206d6178696d756d206c656e6774682e4c4d6178417373657473506572536572766963651010400000000498204d6178696d756d206e756d626572206f66206173736574732070657220736572766963652ea04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e731010ffffffff042101204d6178696d756d206e756d626572206f662076657273696f6e73206f66204d617374657220426c75657072696e742053657276696365204d616e6167657220616c6c6f7765642e48536c61736844656665724475726174696f6e101007000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e01710b330c4c7374010c4c73744c40546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c426f6e646564506f6f6c730001040510790b040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c7300010405108d0b04000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f757420666f207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f726167650001040510910b04000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d657461646174610101040510a90b0400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e40556e626f6e64696e674d656d626572730001040500ad0b04000c4c20556e626f6e64696e67206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e68436f756e746572466f72556e626f6e64696e674d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61704c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0055012054686973206973206f6e6c79207573656420666f7220736c617368696e672e20496e20616c6c206f7468657220696e7374616e6365732c2074686520706f6f6c20696420697320757365642c20616e6420746865c0206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500c10b0400040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e01e506014102142050616c6c65744964f5082070792f746e6c7374048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101020000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e344d61784e616d654c656e677468101032000000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c206e616d652e344d617849636f6e4c656e6774681010f4010000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c2069636f6e2e01c50b34cd0b042448436865636b4e6f6e5a65726f53656e646572d50b8440436865636b5370656356657273696f6ed90b1038436865636b547856657273696f6edd0b1030436865636b47656e65736973e10b3438436865636b4d6f7274616c697479e50b3428436865636b4e6f6e6365ed0b842c436865636b576569676874f10b84604368617267655472616e73616374696f6e5061796d656e74f50b8444436865636b4d6574616461746148617368f90b3d01050c","id":"1"} \ No newline at end of file +{"jsonrpc":"2.0","result":"0x6d6574610e190c000c1c73705f636f72651863727970746f2c4163636f756e7449643332000004000401205b75383b2033325d0000040000032000000008000800000503000c08306672616d655f73797374656d2c4163636f756e74496e666f08144e6f6e636501102c4163636f756e74446174610114001401146e6f6e63651001144e6f6e6365000124636f6e73756d657273100120526566436f756e7400012470726f766964657273100120526566436f756e7400012c73756666696369656e7473100120526566436f756e740001106461746114012c4163636f756e74446174610000100000050500140c3c70616c6c65745f62616c616e6365731474797065732c4163636f756e7444617461041c42616c616e63650118001001106672656518011c42616c616e6365000120726573657276656418011c42616c616e636500011866726f7a656e18011c42616c616e6365000114666c6167731c01284578747261466c61677300001800000507001c0c3c70616c6c65745f62616c616e636573147479706573284578747261466c61677300000400180110753132380000200000050000240c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540128000c01186e6f726d616c2801045400012c6f7065726174696f6e616c280104540001246d616e6461746f7279280104540000280c2873705f77656967687473247765696768745f76321857656967687400000801207265665f74696d652c010c75363400012870726f6f665f73697a652c010c75363400002c000006300030000005060034083c7072696d69746976655f74797065731048323536000004000401205b75383b2033325d00003800000208003c102873705f72756e74696d651c67656e65726963186469676573741844696765737400000401106c6f677340013c5665633c4469676573744974656d3e000040000002440044102873705f72756e74696d651c67656e6572696318646967657374284469676573744974656d0001142850726552756e74696d650800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e00060024436f6e73656e7375730800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000400105365616c0800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000500144f74686572040038011c5665633c75383e0000006452756e74696d65456e7669726f6e6d656e745570646174656400080000480000030400000008004c00000250005008306672616d655f73797374656d2c4576656e745265636f7264080445015404540134000c011470686173655902011450686173650001146576656e7454010445000118746f70696373c10101185665633c543e000054085874616e676c655f746573746e65745f72756e74696d653052756e74696d654576656e7400018c1853797374656d04005801706672616d655f73797374656d3a3a4576656e743c52756e74696d653e000100105375646f04007c016c70616c6c65745f7375646f3a3a4576656e743c52756e74696d653e0003001841737365747304008c017470616c6c65745f6173736574733a3a4576656e743c52756e74696d653e0005002042616c616e636573040090017c70616c6c65745f62616c616e6365733a3a4576656e743c52756e74696d653e000600485472616e73616374696f6e5061796d656e7404009801a870616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4576656e743c52756e74696d653e0007001c4772616e64706104009c015470616c6c65745f6772616e6470613a3a4576656e74000a001c496e64696365730400ac017870616c6c65745f696e64696365733a3a4576656e743c52756e74696d653e000b002444656d6f63726163790400b0018070616c6c65745f64656d6f63726163793a3a4576656e743c52756e74696d653e000c001c436f756e63696c0400c401fc70616c6c65745f636f6c6c6563746976653a3a4576656e743c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d001c56657374696e670400c8017870616c6c65745f76657374696e673a3a4576656e743c52756e74696d653e000e0024456c656374696f6e730400cc01a470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4576656e743c52756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400d801d070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a4576656e743c52756e74696d653e0010001c5374616b696e670400ec017870616c6c65745f7374616b696e673a3a4576656e743c52756e74696d653e0011001c53657373696f6e04000501015470616c6c65745f73657373696f6e3a3a4576656e7400120020547265617375727904000901017c70616c6c65745f74726561737572793a3a4576656e743c52756e74696d653e00140020426f756e7469657304000d01017c70616c6c65745f626f756e746965733a3a4576656e743c52756e74696d653e001500344368696c64426f756e7469657304001101019470616c6c65745f6368696c645f626f756e746965733a3a4576656e743c52756e74696d653e00160020426167734c69737404001501018070616c6c65745f626167735f6c6973743a3a4576656e743c52756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304001901019c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a4576656e743c52756e74696d653e001800245363686564756c657204003501018070616c6c65745f7363686564756c65723a3a4576656e743c52756e74696d653e00190020507265696d61676504004101017c70616c6c65745f707265696d6167653a3a4576656e743c52756e74696d653e001a00204f6666656e63657304004501015870616c6c65745f6f6666656e6365733a3a4576656e74001b001c5478506175736504004d01017c70616c6c65745f74785f70617573653a3a4576656e743c52756e74696d653e001c0020496d4f6e6c696e6504005901018070616c6c65745f696d5f6f6e6c696e653a3a4576656e743c52756e74696d653e001d00204964656e7469747904007901017c70616c6c65745f6964656e746974793a3a4576656e743c52756e74696d653e001e001c5574696c69747904008101015470616c6c65745f7574696c6974793a3a4576656e74001f00204d756c746973696704008501017c70616c6c65745f6d756c74697369673a3a4576656e743c52756e74696d653e00200020457468657265756d04008d01015870616c6c65745f657468657265756d3a3a4576656e740021000c45564d0400b901016870616c6c65745f65766d3a3a4576656e743c52756e74696d653e0022001c426173654665650400c501015870616c6c65745f626173655f6665653a3a4576656e7400250018436c61696d730400d501019470616c6c65745f61697264726f705f636c61696d733a3a4576656e743c52756e74696d653e0027001450726f78790400e101017070616c6c65745f70726f78793a3a4576656e743c52756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400ed0101b470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e3a3a4576656e743c52756e74696d653e002d002053657276696365730400fd01017c70616c6c65745f73657276696365733a3a4576656e743c52756e74696d653e0033000c4c737404004502018470616c6c65745f74616e676c655f6c73743a3a4576656e743c52756e74696d653e00340000580c306672616d655f73797374656d1870616c6c6574144576656e7404045400011c4045787472696e7369635375636365737304013464697370617463685f696e666f5c01304469737061746368496e666f00000490416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e3c45787472696e7369634661696c656408013864697370617463685f6572726f7268013444697370617463684572726f7200013464697370617463685f696e666f5c01304469737061746368496e666f00010450416e2065787472696e736963206661696c65642e2c436f64655570646174656400020450603a636f6465602077617320757064617465642e284e65774163636f756e7404011c6163636f756e74000130543a3a4163636f756e7449640003046841206e6577206163636f756e742077617320637265617465642e344b696c6c65644163636f756e7404011c6163636f756e74000130543a3a4163636f756e74496400040458416e206163636f756e7420776173207265617065642e2052656d61726b656408011873656e646572000130543a3a4163636f756e7449640001106861736834011c543a3a48617368000504704f6e206f6e2d636861696e2072656d61726b2068617070656e65642e4455706772616465417574686f72697a6564080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00060468416e20757067726164652077617320617574686f72697a65642e04704576656e7420666f72207468652053797374656d2070616c6c65742e5c0c346672616d655f737570706f7274206469737061746368304469737061746368496e666f00000c0118776569676874280118576569676874000114636c6173736001344469737061746368436c617373000120706179735f666565640110506179730000600c346672616d655f737570706f7274206469737061746368344469737061746368436c61737300010c184e6f726d616c0000002c4f7065726174696f6e616c000100244d616e6461746f727900020000640c346672616d655f737570706f727420646973706174636810506179730001080c596573000000084e6f0001000068082873705f72756e74696d653444697370617463684572726f72000138144f746865720000003043616e6e6f744c6f6f6b7570000100244261644f726967696e000200184d6f64756c6504006c012c4d6f64756c654572726f7200030044436f6e73756d657252656d61696e696e670004002c4e6f50726f76696465727300050040546f6f4d616e79436f6e73756d65727300060014546f6b656e0400700128546f6b656e4572726f720007002841726974686d65746963040074013c41726974686d657469634572726f72000800345472616e73616374696f6e616c04007801485472616e73616374696f6e616c4572726f7200090024457868617573746564000a0028436f7272757074696f6e000b002c556e617661696c61626c65000c0038526f6f744e6f74416c6c6f776564000d00006c082873705f72756e74696d652c4d6f64756c654572726f720000080114696e64657808010875380001146572726f7248018c5b75383b204d41585f4d4f44554c455f4552524f525f454e434f4445445f53495a455d000070082873705f72756e74696d6528546f6b656e4572726f720001284046756e6473556e617661696c61626c65000000304f6e6c7950726f76696465720001003042656c6f774d696e696d756d0002003043616e6e6f7443726561746500030030556e6b6e6f776e41737365740004001846726f7a656e0005002c556e737570706f727465640006004043616e6e6f74437265617465486f6c64000700344e6f74457870656e6461626c650008001c426c6f636b65640009000074083473705f61726974686d657469633c41726974686d657469634572726f7200010c24556e646572666c6f77000000204f766572666c6f77000100384469766973696f6e42795a65726f0002000078082873705f72756e74696d65485472616e73616374696f6e616c4572726f72000108304c696d6974526561636865640000001c4e6f4c61796572000100007c0c2c70616c6c65745f7375646f1870616c6c6574144576656e7404045400011014537564696404012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e00047041207375646f2063616c6c206a75737420746f6f6b20706c6163652e284b65794368616e67656408010c6f6c648801504f7074696f6e3c543a3a4163636f756e7449643e04b4546865206f6c64207375646f206b657920286966206f6e65207761732070726576696f75736c7920736574292e010c6e6577000130543a3a4163636f756e7449640488546865206e6577207375646f206b657920286966206f6e652077617320736574292e010478546865207375646f206b657920686173206265656e20757064617465642e284b657952656d6f76656400020480546865206b657920776173207065726d616e656e746c792072656d6f7665642e285375646f4173446f6e6504012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e0304c841205b7375646f5f61735d2850616c6c65743a3a7375646f5f6173292063616c6c206a75737420746f6f6b20706c6163652e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574800418526573756c740804540184044501680108084f6b040084000000000c45727204006800000100008400000400008804184f7074696f6e04045401000108104e6f6e6500000010536f6d6504000000000100008c0c3470616c6c65745f6173736574731870616c6c6574144576656e740804540004490001681c437265617465640c012061737365745f6964180128543a3a4173736574496400011c63726561746f72000130543a3a4163636f756e7449640001146f776e6572000130543a3a4163636f756e74496400000474536f6d6520617373657420636c6173732077617320637265617465642e184973737565640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500010460536f6d65206173736574732077657265206973737565642e2c5472616e7366657272656410012061737365745f6964180128543a3a4173736574496400011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500020474536f6d65206173736574732077657265207472616e736665727265642e184275726e65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400011c62616c616e6365180128543a3a42616c616e63650003046c536f6d652061737365747320776572652064657374726f7965642e2c5465616d4368616e67656410012061737365745f6964180128543a3a41737365744964000118697373756572000130543a3a4163636f756e74496400011461646d696e000130543a3a4163636f756e74496400011c667265657a6572000130543a3a4163636f756e74496400040470546865206d616e6167656d656e74207465616d206368616e6765642e304f776e65724368616e67656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400050448546865206f776e6572206368616e6765642e1846726f7a656e08012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400060478536f6d65206163636f756e74206077686f60207761732066726f7a656e2e1854686177656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400070478536f6d65206163636f756e74206077686f6020776173207468617765642e2c417373657446726f7a656e04012061737365745f6964180128543a3a4173736574496400080484536f6d65206173736574206061737365745f696460207761732066726f7a656e2e2c417373657454686177656404012061737365745f6964180128543a3a4173736574496400090484536f6d65206173736574206061737365745f69646020776173207468617765642e444163636f756e747344657374726f7965640c012061737365745f6964180128543a3a417373657449640001486163636f756e74735f64657374726f79656410010c7533320001486163636f756e74735f72656d61696e696e6710010c753332000a04a04163636f756e747320776572652064657374726f79656420666f7220676976656e2061737365742e48417070726f76616c7344657374726f7965640c012061737365745f6964180128543a3a4173736574496400014c617070726f76616c735f64657374726f79656410010c75333200014c617070726f76616c735f72656d61696e696e6710010c753332000b04a4417070726f76616c7320776572652064657374726f79656420666f7220676976656e2061737365742e484465737472756374696f6e5374617274656404012061737365745f6964180128543a3a41737365744964000c04d0416e20617373657420636c61737320697320696e207468652070726f63657373206f66206265696e672064657374726f7965642e2444657374726f79656404012061737365745f6964180128543a3a41737365744964000d0474416e20617373657420636c617373207761732064657374726f7965642e30466f7263654372656174656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000e048c536f6d6520617373657420636c6173732077617320666f7263652d637265617465642e2c4d6574616461746153657414012061737365745f6964180128543a3a417373657449640001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000f049c4e6577206d6574616461746120686173206265656e2073657420666f7220616e2061737365742e3c4d65746164617461436c656172656404012061737365745f6964180128543a3a417373657449640010049c4d6574616461746120686173206265656e20636c656172656420666f7220616e2061737365742e40417070726f7665645472616e7366657210012061737365745f6964180128543a3a41737365744964000118736f75726365000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650011043101284164646974696f6e616c292066756e64732068617665206265656e20617070726f76656420666f72207472616e7366657220746f20612064657374696e6174696f6e206163636f756e742e44417070726f76616c43616e63656c6c65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964001204f0416e20617070726f76616c20666f72206163636f756e74206064656c656761746560207761732063616e63656c6c656420627920606f776e6572602e4c5472616e73666572726564417070726f76656414012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e74496400012c64657374696e6174696f6e000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650013083101416e2060616d6f756e746020776173207472616e7366657272656420696e2069747320656e7469726574792066726f6d20606f776e65726020746f206064657374696e6174696f6e602062796074686520617070726f766564206064656c6567617465602e4841737365745374617475734368616e67656404012061737365745f6964180128543a3a41737365744964001404f8416e2061737365742068617320686164206974732061747472696275746573206368616e676564206279207468652060466f72636560206f726967696e2e5841737365744d696e42616c616e63654368616e67656408012061737365745f6964180128543a3a4173736574496400013c6e65775f6d696e5f62616c616e6365180128543a3a42616c616e63650015040101546865206d696e5f62616c616e6365206f6620616e20617373657420686173206265656e207570646174656420627920746865206173736574206f776e65722e1c546f75636865640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640001246465706f7369746f72000130543a3a4163636f756e744964001604fc536f6d65206163636f756e74206077686f6020776173206372656174656420776974682061206465706f7369742066726f6d20606465706f7369746f72602e1c426c6f636b656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640017047c536f6d65206163636f756e74206077686f602077617320626c6f636b65642e244465706f73697465640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365001804dc536f6d65206173736574732077657265206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e2457697468647261776e0c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650019042101536f6d652061737365747320776572652077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574900c3c70616c6c65745f62616c616e6365731870616c6c6574144576656e740804540004490001581c456e646f77656408011c6163636f756e74000130543a3a4163636f756e744964000130667265655f62616c616e6365180128543a3a42616c616e6365000004b8416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e20447573744c6f737408011c6163636f756e74000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650001083d01416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c78726573756c74696e6720696e20616e206f75747269676874206c6f73732e205472616e736665720c011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650002044c5472616e73666572207375636365656465642e2842616c616e636553657408010c77686f000130543a3a4163636f756e74496400011066726565180128543a3a42616c616e636500030468412062616c616e6365207761732073657420627920726f6f742e20526573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000404e0536f6d652062616c616e63652077617320726573657276656420286d6f7665642066726f6d206672656520746f207265736572766564292e28556e726573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000504e8536f6d652062616c616e63652077617320756e726573657276656420286d6f7665642066726f6d20726573657276656420746f2066726565292e4852657365727665526570617472696174656410011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500014864657374696e6174696f6e5f7374617475739401185374617475730006084d01536f6d652062616c616e636520776173206d6f7665642066726f6d207468652072657365727665206f6620746865206669727374206163636f756e7420746f20746865207365636f6e64206163636f756e742ed846696e616c20617267756d656e7420696e64696361746573207468652064657374696e6174696f6e2062616c616e636520747970652e1c4465706f73697408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000704d8536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20576974686472617708010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650008041d01536f6d6520616d6f756e74207761732077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e1c536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650009040101536f6d6520616d6f756e74207761732072656d6f7665642066726f6d20746865206163636f756e742028652e672e20666f72206d69736265686176696f72292e184d696e74656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000a049c536f6d6520616d6f756e7420776173206d696e74656420696e746f20616e206163636f756e742e184275726e656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000b049c536f6d6520616d6f756e7420776173206275726e65642066726f6d20616e206163636f756e742e2453757370656e64656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000c041501536f6d6520616d6f756e74207761732073757370656e6465642066726f6d20616e206163636f756e74202869742063616e20626520726573746f726564206c61746572292e20526573746f72656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000d04a4536f6d6520616d6f756e742077617320726573746f72656420696e746f20616e206163636f756e742e20557067726164656404010c77686f000130543a3a4163636f756e744964000e0460416e206163636f756e74207761732075706772616465642e18497373756564040118616d6f756e74180128543a3a42616c616e6365000f042d01546f74616c2069737375616e63652077617320696e637265617365642062792060616d6f756e74602c206372656174696e6720612063726564697420746f2062652062616c616e6365642e2452657363696e646564040118616d6f756e74180128543a3a42616c616e63650010042501546f74616c2069737375616e636520776173206465637265617365642062792060616d6f756e74602c206372656174696e672061206465627420746f2062652062616c616e6365642e184c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500110460536f6d652062616c616e636520776173206c6f636b65642e20556e6c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500120468536f6d652062616c616e63652077617320756e6c6f636b65642e1846726f7a656e08010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500130460536f6d652062616c616e6365207761732066726f7a656e2e1854686177656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500140460536f6d652062616c616e636520776173207468617765642e4c546f74616c49737375616e6365466f7263656408010c6f6c64180128543a3a42616c616e636500010c6e6577180128543a3a42616c616e6365001504ac5468652060546f74616c49737375616e6365602077617320666f72636566756c6c79206368616e6765642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749414346672616d655f737570706f72741874726169747318746f6b656e73106d6973633442616c616e6365537461747573000108104672656500000020526573657276656400010000980c6870616c6c65745f7472616e73616374696f6e5f7061796d656e741870616c6c6574144576656e74040454000104485472616e73616374696f6e466565506169640c010c77686f000130543a3a4163636f756e74496400012861637475616c5f66656518013042616c616e63654f663c543e00010c74697018013042616c616e63654f663c543e000008590141207472616e73616374696f6e20666565206061637475616c5f666565602c206f662077686963682060746970602077617320616464656420746f20746865206d696e696d756d20696e636c7573696f6e206665652c5c686173206265656e2070616964206279206077686f602e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749c0c3870616c6c65745f6772616e6470611870616c6c6574144576656e7400010c384e6577417574686f726974696573040134617574686f726974795f736574a00134417574686f726974794c6973740000048c4e657720617574686f726974792073657420686173206265656e206170706c6965642e185061757365640001049843757272656e7420617574686f726974792073657420686173206265656e207061757365642e1c526573756d65640002049c43757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574a0000002a400a400000408a83000a80c5073705f636f6e73656e7375735f6772616e6470610c617070185075626c69630000040004013c656432353531393a3a5075626c69630000ac0c3870616c6c65745f696e64696365731870616c6c6574144576656e7404045400010c34496e64657841737369676e656408010c77686f000130543a3a4163636f756e744964000114696e64657810013c543a3a4163636f756e74496e6465780000047441206163636f756e7420696e646578207761732061737369676e65642e28496e6465784672656564040114696e64657810013c543a3a4163636f756e74496e646578000104bc41206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e2c496e64657846726f7a656e080114696e64657810013c543a3a4163636f756e74496e64657800010c77686f000130543a3a4163636f756e744964000204e841206163636f756e7420696e64657820686173206265656e2066726f7a656e20746f206974732063757272656e74206163636f756e742049442e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b00c4070616c6c65745f64656d6f63726163791870616c6c6574144576656e740404540001442050726f706f73656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000004bc41206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e185461626c656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000104d841207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e3845787465726e616c5461626c656400020494416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e1c537461727465640801247265665f696e64657810013c5265666572656e64756d496e6465780001247468726573686f6c64b40134566f74655468726573686f6c640003045c41207265666572656e64756d2068617320626567756e2e185061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000404ac412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e244e6f745061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000504ac412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e2443616e63656c6c65640401247265665f696e64657810013c5265666572656e64756d496e6465780006048041207265666572656e64756d20686173206265656e2063616e63656c6c65642e2444656c65676174656408010c77686f000130543a3a4163636f756e744964000118746172676574000130543a3a4163636f756e744964000704dc416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e2c556e64656c65676174656404011c6163636f756e74000130543a3a4163636f756e744964000804e4416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e185665746f65640c010c77686f000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114756e74696c300144426c6f636b4e756d626572466f723c543e00090494416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e2c426c61636b6c697374656404013470726f706f73616c5f6861736834011c543a3a48617368000a04c4412070726f706f73616c5f6861736820686173206265656e20626c61636b6c6973746564207065726d616e656e746c792e14566f7465640c0114766f746572000130543a3a4163636f756e7449640001247265665f696e64657810013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e000b0490416e206163636f756e742068617320766f74656420696e2061207265666572656e64756d205365636f6e6465640801207365636f6e646572000130543a3a4163636f756e74496400012870726f705f696e64657810012450726f70496e646578000c0488416e206163636f756e7420686173207365636f6e64656420612070726f706f73616c4050726f706f73616c43616e63656c656404012870726f705f696e64657810012450726f70496e646578000d0460412070726f706f73616c20676f742063616e63656c65642e2c4d657461646174615365740801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0e04d44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e207365742e3c4d65746164617461436c65617265640801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0f04e44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e20636c65617265642e4c4d657461646174615472616e736665727265640c0128707265765f6f776e6572c001344d657461646174614f776e6572046050726576696f7573206d65746164617461206f776e65722e01146f776e6572c001344d657461646174614f776e6572044c4e6577206d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e1004ac4d6574616461746120686173206265656e207472616e7366657272656420746f206e6577206f776e65722e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b40c4070616c6c65745f64656d6f637261637938766f74655f7468726573686f6c6434566f74655468726573686f6c6400010c5053757065724d616a6f72697479417070726f76650000005053757065724d616a6f72697479416761696e73740001003853696d706c654d616a6f7269747900020000b80c4070616c6c65745f64656d6f637261637910766f74652c4163636f756e74566f7465041c42616c616e636501180108205374616e64617264080110766f7465bc0110566f746500011c62616c616e636518011c42616c616e63650000001453706c697408010c61796518011c42616c616e636500010c6e617918011c42616c616e636500010000bc0c4070616c6c65745f64656d6f637261637910766f746510566f74650000040008000000c00c4070616c6c65745f64656d6f6372616379147479706573344d657461646174614f776e657200010c2045787465726e616c0000002050726f706f73616c040010012450726f70496e646578000100285265666572656e64756d040010013c5265666572656e64756d496e64657800020000c40c4470616c6c65745f636f6c6c6563746976651870616c6c6574144576656e7408045400044900011c2050726f706f73656410011c6163636f756e74000130543a3a4163636f756e74496400013870726f706f73616c5f696e64657810013450726f706f73616c496e64657800013470726f706f73616c5f6861736834011c543a3a486173680001247468726573686f6c6410012c4d656d626572436f756e74000008490141206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e3c604d656d626572436f756e7460292e14566f74656414011c6163636f756e74000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114766f746564200110626f6f6c00010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e74000108050141206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e671501612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e20417070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000204c041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2c446973617070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000304d041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e20457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c74000404210141206d6f74696f6e207761732065786563757465643b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e384d656d626572457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c740005044901412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e18436c6f7365640c013470726f706f73616c5f6861736834011c543a3a4861736800010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e740006045501412070726f706f73616c2077617320636c6f736564206265636175736520697473207468726573686f6c64207761732072656163686564206f7220616674657220697473206475726174696f6e207761732075702e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c80c3870616c6c65745f76657374696e671870616c6c6574144576656e740404540001083856657374696e675570646174656408011c6163636f756e74000130543a3a4163636f756e744964000120756e76657374656418013042616c616e63654f663c543e000008510154686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e6469636174652061206368616e676520696e2066756e647320617661696c61626c652e25015468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e4056657374696e67436f6d706c6574656404011c6163636f756e74000130543a3a4163636f756e7449640001049c416e205c5b6163636f756e745c5d20686173206265636f6d652066756c6c79207665737465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574cc0c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144576656e7404045400011c1c4e65775465726d04012c6e65775f6d656d62657273d001ec5665633c283c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e7449642c2042616c616e63654f663c543e293e000014450141206e6577207465726d2077697468206e65775f6d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e550174686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e65644501666f72207468697320707572706f73652e204120604e65775465726d285c5b5c5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e645501736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f2c626567696e20776974682e24456d7074795465726d00010831014e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6dc8604e65775465726d285c5b5c5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e34456c656374696f6e4572726f72000204e4496e7465726e616c206572726f722068617070656e6564207768696c6520747279696e6720746f20706572666f726d20656c656374696f6e2e304d656d6265724b69636b65640401186d656d6265720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000308410141206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f723060456d7074795465726d602e2452656e6f756e63656404012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400040498536f6d656f6e65206861732072656e6f756e6365642074686569722063616e6469646163792e4043616e646964617465536c617368656408012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0005103901412063616e6469646174652077617320736c617368656420627920616d6f756e742064756520746f206661696c696e6720746f206f627461696e20612073656174206173206d656d626572206f722872756e6e65722d75702e00e44e6f74652074686174206f6c64206d656d6265727320616e642072756e6e6572732d75702061726520616c736f2063616e646964617465732e4453656174486f6c646572536c617368656408012c736561745f686f6c6465720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000604350141207365617420686f6c6465722077617320736c617368656420627920616d6f756e74206279206265696e6720666f72636566756c6c792072656d6f7665642066726f6d20746865207365742e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d0000002d400d400000408001800d80c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144576656e7404045400011838536f6c7574696f6e53746f7265640c011c636f6d70757465dc013c456c656374696f6e436f6d707574650001186f726967696e8801504f7074696f6e3c543a3a4163636f756e7449643e000130707265765f656a6563746564200110626f6f6c00001cb44120736f6c7574696f6e207761732073746f72656420776974682074686520676976656e20636f6d707574652e00510154686520606f726967696e6020696e6469636174657320746865206f726967696e206f662074686520736f6c7574696f6e2e20496620606f726967696e602069732060536f6d65284163636f756e74496429602c59017468652073746f72656420736f6c7574696f6e20776173207375626d697474656420696e20746865207369676e65642070686173652062792061206d696e657220776974682074686520604163636f756e744964602e25014f74686572776973652c2074686520736f6c7574696f6e207761732073746f7265642065697468657220647572696e672074686520756e7369676e6564207068617365206f722062794d0160543a3a466f7263654f726967696e602e205468652060626f6f6c6020697320607472756560207768656e20612070726576696f757320736f6c7574696f6e2077617320656a656374656420746f206d616b6548726f6f6d20666f722074686973206f6e652e44456c656374696f6e46696e616c697a656408011c636f6d70757465dc013c456c656374696f6e436f6d7075746500011473636f7265e00134456c656374696f6e53636f7265000104190154686520656c656374696f6e20686173206265656e2066696e616c697a65642c20776974682074686520676976656e20636f6d7075746174696f6e20616e642073636f72652e38456c656374696f6e4661696c656400020c4c416e20656c656374696f6e206661696c65642e0001014e6f74206d7563682063616e20626520736169642061626f757420776869636820636f6d7075746573206661696c656420696e207468652070726f636573732e20526577617264656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0003042501416e206163636f756e7420686173206265656e20726577617264656420666f72207468656972207369676e6564207375626d697373696f6e206265696e672066696e616c697a65642e1c536c617368656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0004042101416e206163636f756e7420686173206265656e20736c617368656420666f72207375626d697474696e6720616e20696e76616c6964207369676e6564207375626d697373696f6e2e4450686173655472616e736974696f6e65640c011066726f6de4016050686173653c426c6f636b4e756d626572466f723c543e3e000108746fe4016050686173653c426c6f636b4e756d626572466f723c543e3e000114726f756e6410010c753332000504b85468657265207761732061207068617365207472616e736974696f6e20696e206120676976656e20726f756e642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574dc089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653c456c656374696f6e436f6d707574650001141c4f6e436861696e000000185369676e656400010020556e7369676e65640002002046616c6c6261636b00030024456d657267656e637900040000e0084473705f6e706f735f656c656374696f6e7334456c656374696f6e53636f726500000c01346d696e696d616c5f7374616b6518013c457874656e64656442616c616e636500012473756d5f7374616b6518013c457874656e64656442616c616e636500014473756d5f7374616b655f7371756172656418013c457874656e64656442616c616e63650000e4089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651450686173650408426e013001100c4f6666000000185369676e656400010020556e7369676e65640400e8012828626f6f6c2c20426e2900020024456d657267656e637900030000e800000408203000ec103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144576656e740404540001481c457261506169640c01246572615f696e646578100120457261496e64657800014076616c696461746f725f7061796f757418013042616c616e63654f663c543e00012472656d61696e64657218013042616c616e63654f663c543e000008550154686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973c07468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e2052657761726465640c01147374617368000130543a3a4163636f756e74496400011064657374f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000118616d6f756e7418013042616c616e63654f663c543e0001040d01546865206e6f6d696e61746f7220686173206265656e207265776172646564206279207468697320616d6f756e7420746f20746869732064657374696e6174696f6e2e1c536c61736865640801187374616b6572000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0002041d0141207374616b6572202876616c696461746f72206f72206e6f6d696e61746f722920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e34536c6173685265706f727465640c012476616c696461746f72000130543a3a4163636f756e7449640001206672616374696f6ef4011c50657262696c6c000124736c6173685f657261100120457261496e64657800030859014120736c61736820666f722074686520676976656e2076616c696461746f722c20666f722074686520676976656e2070657263656e74616765206f66207468656972207374616b652c2061742074686520676976656e54657261206173206265656e207265706f727465642e684f6c64536c617368696e675265706f727444697363617264656404013473657373696f6e5f696e64657810013053657373696f6e496e6465780004081901416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64446e6f742062652070726f6365737365642e385374616b657273456c65637465640005048441206e657720736574206f66207374616b6572732077617320656c65637465642e18426f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000610d0416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d004d014e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c210169742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e20556e626f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00070490416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e2457697468647261776e0801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0008085901416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365606466726f6d2074686520756e6c6f636b696e672071756575652e184b69636b65640801246e6f6d696e61746f72000130543a3a4163636f756e7449640001147374617368000130543a3a4163636f756e744964000904b441206e6f6d696e61746f7220686173206265656e206b69636b65642066726f6d20612076616c696461746f722e545374616b696e67456c656374696f6e4661696c6564000a04ac54686520656c656374696f6e206661696c65642e204e6f206e65772065726120697320706c616e6e65642e1c4368696c6c65640401147374617368000130543a3a4163636f756e744964000b042101416e206163636f756e74206861732073746f707065642070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e345061796f7574537461727465640801246572615f696e646578100120457261496e64657800013c76616c696461746f725f7374617368000130543a3a4163636f756e744964000c0498546865207374616b657273272072657761726473206172652067657474696e6720706169642e4456616c696461746f7250726566735365740801147374617368000130543a3a4163636f756e7449640001147072656673f8013856616c696461746f725072656673000d0498412076616c696461746f72206861732073657420746865697220707265666572656e6365732e68536e617073686f74566f7465727353697a65457863656564656404011073697a6510010c753332000e0468566f746572732073697a65206c696d697420726561636865642e6c536e617073686f745461726765747353697a65457863656564656404011073697a6510010c753332000f046c546172676574732073697a65206c696d697420726561636865642e20466f7263654572610401106d6f64650101011c466f7263696e670010047441206e657720666f72636520657261206d6f646520776173207365742e64436f6e74726f6c6c65724261746368446570726563617465640401206661696c7572657310010c753332001104a45265706f7274206f66206120636f6e74726f6c6c6572206261746368206465707265636174696f6e2e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574f0083870616c6c65745f7374616b696e674452657761726444657374696e6174696f6e04244163636f756e74496401000114185374616b656400000014537461736800010028436f6e74726f6c6c65720002001c4163636f756e7404000001244163636f756e744964000300104e6f6e6500040000f40c3473705f61726974686d65746963287065725f7468696e67731c50657262696c6c0000040010010c7533320000f8083870616c6c65745f7374616b696e673856616c696461746f7250726566730000080128636f6d6d697373696f6efc011c50657262696c6c00011c626c6f636b6564200110626f6f6c0000fc000006f4000101083870616c6c65745f7374616b696e671c466f7263696e67000110284e6f74466f7263696e6700000020466f7263654e657700010024466f7263654e6f6e650002002c466f726365416c776179730003000005010c3870616c6c65745f73657373696f6e1870616c6c6574144576656e74000104284e657753657373696f6e04013473657373696f6e5f696e64657810013053657373696f6e496e64657800000839014e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f74207468659c626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657409010c3c70616c6c65745f74726561737572791870616c6c6574144576656e74080454000449000130205370656e64696e670401406275646765745f72656d61696e696e6718013c42616c616e63654f663c542c20493e000004e45765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e1c417761726465640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000114617761726418013c42616c616e63654f663c542c20493e00011c6163636f756e74000130543a3a4163636f756e7449640001047c536f6d652066756e64732068617665206265656e20616c6c6f63617465642e144275726e7404012c6275726e745f66756e647318013c42616c616e63654f663c542c20493e00020488536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20526f6c6c6f766572040140726f6c6c6f7665725f62616c616e636518013c42616c616e63654f663c542c20493e0003042d015370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e1c4465706f73697404011476616c756518013c42616c616e63654f663c542c20493e0004047c536f6d652066756e64732068617665206265656e206465706f73697465642e345370656e64417070726f7665640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000118616d6f756e7418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640005049c41206e6577207370656e642070726f706f73616c20686173206265656e20617070726f7665642e3c55706461746564496e61637469766508012c726561637469766174656418013c42616c616e63654f663c542c20493e00012c646561637469766174656418013c42616c616e63654f663c542c20493e000604cc54686520696e6163746976652066756e6473206f66207468652070616c6c65742068617665206265656e20757064617465642e4841737365745370656e64417070726f766564180114696e6465781001285370656e64496e64657800012861737365745f6b696e64840130543a3a41737365744b696e64000118616d6f756e74180150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000138543a3a42656e656669636961727900012876616c69645f66726f6d300144426c6f636b4e756d626572466f723c543e0001246578706972655f6174300144426c6f636b4e756d626572466f723c543e000704b441206e6577206173736574207370656e642070726f706f73616c20686173206265656e20617070726f7665642e4041737365745370656e64566f69646564040114696e6465781001285370656e64496e64657800080474416e20617070726f766564207370656e642077617320766f696465642e1050616964080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a49640009044c41207061796d656e742068617070656e65642e345061796d656e744661696c6564080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a4964000a049041207061796d656e74206661696c656420616e642063616e20626520726574726965642e385370656e6450726f636573736564040114696e6465781001285370656e64496e646578000b084d0141207370656e64207761732070726f63657373656420616e642072656d6f7665642066726f6d207468652073746f726167652e204974206d696768742068617665206265656e207375636365737366756c6c797070616964206f72206974206d6179206861766520657870697265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65740d010c3c70616c6c65745f626f756e746965731870616c6c6574144576656e7408045400044900012c38426f756e747950726f706f736564040114696e64657810012c426f756e7479496e646578000004504e657720626f756e74792070726f706f73616c2e38426f756e747952656a6563746564080114696e64657810012c426f756e7479496e646578000110626f6e6418013c42616c616e63654f663c542c20493e000104cc4120626f756e74792070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e48426f756e7479426563616d65416374697665040114696e64657810012c426f756e7479496e646578000204b84120626f756e74792070726f706f73616c2069732066756e64656420616e6420626563616d65206163746976652e34426f756e747941776172646564080114696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000304944120626f756e7479206973206177617264656420746f20612062656e65666963696172792e34426f756e7479436c61696d65640c0114696e64657810012c426f756e7479496e6465780001187061796f757418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640004048c4120626f756e747920697320636c61696d65642062792062656e65666963696172792e38426f756e747943616e63656c6564040114696e64657810012c426f756e7479496e646578000504584120626f756e74792069732063616e63656c6c65642e38426f756e7479457874656e646564040114696e64657810012c426f756e7479496e646578000604704120626f756e74792065787069727920697320657874656e6465642e38426f756e7479417070726f766564040114696e64657810012c426f756e7479496e646578000704544120626f756e747920697320617070726f7665642e3c43757261746f7250726f706f736564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000804744120626f756e74792063757261746f722069732070726f706f7365642e4443757261746f72556e61737369676e6564040124626f756e74795f696410012c426f756e7479496e6465780009047c4120626f756e74792063757261746f7220697320756e61737369676e65642e3c43757261746f724163636570746564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000a04744120626f756e74792063757261746f722069732061636365707465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657411010c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144576656e74040454000110144164646564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780000046041206368696c642d626f756e74792069732061646465642e1c417761726465640c0114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000104ac41206368696c642d626f756e7479206973206177617264656420746f20612062656e65666963696172792e1c436c61696d6564100114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780001187061796f757418013042616c616e63654f663c543e00012c62656e6566696369617279000130543a3a4163636f756e744964000204a441206368696c642d626f756e747920697320636c61696d65642062792062656e65666963696172792e2043616e63656c6564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780003047041206368696c642d626f756e74792069732063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657415010c4070616c6c65745f626167735f6c6973741870616c6c6574144576656e740804540004490001082052656261676765640c010c77686f000130543a3a4163636f756e74496400011066726f6d300120543a3a53636f7265000108746f300120543a3a53636f7265000004a44d6f76656420616e206163636f756e742066726f6d206f6e652062616720746f20616e6f746865722e3053636f72655570646174656408010c77686f000130543a3a4163636f756e7449640001246e65775f73636f7265300120543a3a53636f7265000104d855706461746564207468652073636f7265206f6620736f6d65206163636f756e7420746f2074686520676976656e20616d6f756e742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657419010c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f73746174651d010124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e1d01085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e6700020000210104184f7074696f6e0404540125010108104e6f6e6500000010536f6d65040025010000010000250100000408f400002901085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7350436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d62657200002d0104184f7074696f6e0404540131010108104e6f6e6500000010536f6d650400310100000100003101085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7364436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e7449640001000035010c4070616c6c65745f7363686564756c65721870616c6c6574144576656e74040454000124245363686564756c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c753332000004505363686564756c656420736f6d65207461736b2e2043616e63656c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001044c43616e63656c656420736f6d65207461736b2e28446973706174636865640c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118726573756c748001384469737061746368526573756c74000204544469737061746368656420736f6d65207461736b2e2052657472795365741001107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118706572696f64300144426c6f636b4e756d626572466f723c543e00011c726574726965730801087538000304a0536574206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e38526574727943616e63656c6c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000404ac43616e63656c206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e3c43616c6c556e617661696c61626c650801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e00050429015468652063616c6c20666f72207468652070726f7669646564206861736820776173206e6f7420666f756e6420736f20746865207461736b20686173206265656e2061626f727465642e38506572696f6469634661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0006043d0154686520676976656e207461736b2077617320756e61626c6520746f2062652072656e657765642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b2e2c52657472794661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0007085d0154686520676976656e207461736b2077617320756e61626c6520746f20626520726574726965642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b206f722074686572659c776173206e6f7420656e6f7567682077656967687420746f2072657363686564756c652069742e545065726d616e656e746c794f7665727765696768740801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000804f054686520676976656e207461736b2063616e206e657665722062652065786563757465642073696e6365206974206973206f7665727765696768742e04304576656e747320747970652e3901000004083010003d0104184f7074696f6e04045401040108104e6f6e6500000010536f6d65040004000001000041010c3c70616c6c65745f707265696d6167651870616c6c6574144576656e7404045400010c144e6f7465640401106861736834011c543a3a48617368000004684120707265696d61676520686173206265656e206e6f7465642e245265717565737465640401106861736834011c543a3a48617368000104784120707265696d61676520686173206265656e207265717565737465642e1c436c65617265640401106861736834011c543a3a486173680002046c4120707265696d616765206861732062656e20636c65617265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657445010c3c70616c6c65745f6f6666656e6365731870616c6c6574144576656e740001041c4f6666656e63650801106b696e64490101104b696e6400012074696d65736c6f743801384f706171756554696d65536c6f7400000c5101546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e643501286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4c5c5b6b696e642c2074696d65736c6f745c5d2e04304576656e747320747970652e49010000031000000008004d010c3c70616c6c65745f74785f70617573651870616c6c6574144576656e740404540001082843616c6c50617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000004b8546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f77207061757365642e3043616c6c556e70617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000104c0546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f7720756e7061757365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574510100000408550155010055010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000059010c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144576656e7404045400010c444865617274626561745265636569766564040130617574686f726974795f69645d010138543a3a417574686f726974794964000004c041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f726974794964602e1c416c6c476f6f64000104d041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2c536f6d654f66666c696e6504011c6f66666c696e656101016c5665633c4964656e74696669636174696f6e5475706c653c543e3e000204290141742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e047c54686520604576656e746020656e756d206f6620746869732070616c6c65745d01104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139185075626c69630000040004013c737232353531393a3a5075626c696300006101000002650100650100000408006901006901082873705f7374616b696e67204578706f7375726508244163636f756e74496401001c42616c616e63650118000c0114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e00006d01000006180071010000027501007501082873705f7374616b696e6748496e646976696475616c4578706f7375726508244163636f756e74496401001c42616c616e636501180008010c77686f0001244163636f756e74496400011476616c75656d01011c42616c616e6365000079010c3c70616c6c65745f6964656e746974791870616c6c6574144576656e740404540001442c4964656e7469747953657404010c77686f000130543a3a4163636f756e744964000004ec41206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e3c4964656e74697479436c656172656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000104cc41206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e384964656e746974794b696c6c656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000204c441206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e484a756467656d656e7452657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780003049c41206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e504a756467656d656e74556e72657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780004048841206a756467656d656e74207265717565737420776173207265747261637465642e384a756467656d656e74476976656e080118746172676574000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780005049441206a756467656d656e742077617320676976656e2062792061207265676973747261722e38526567697374726172416464656404013c7265676973747261725f696e646578100138526567697374726172496e646578000604584120726567697374726172207761732061646465642e405375624964656e7469747941646465640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000704f441207375622d6964656e746974792077617320616464656420746f20616e206964656e7469747920616e6420746865206465706f73697420706169642e485375624964656e7469747952656d6f7665640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000804090141207375622d6964656e74697479207761732072656d6f7665642066726f6d20616e206964656e7469747920616e6420746865206465706f7369742066726565642e485375624964656e746974795265766f6b65640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000908190141207375622d6964656e746974792077617320636c65617265642c20616e642074686520676976656e206465706f7369742072657061747269617465642066726f6d20746865c86d61696e206964656e74697479206163636f756e7420746f20746865207375622d6964656e74697479206163636f756e742e38417574686f726974794164646564040124617574686f72697479000130543a3a4163636f756e744964000a047c4120757365726e616d6520617574686f72697479207761732061646465642e40417574686f7269747952656d6f766564040124617574686f72697479000130543a3a4163636f756e744964000b04844120757365726e616d6520617574686f72697479207761732072656d6f7665642e2c557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000c04744120757365726e616d65207761732073657420666f72206077686f602e38557365726e616d655175657565640c010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e00012865787069726174696f6e300144426c6f636b4e756d626572466f723c543e000d0419014120757365726e616d6520776173207175657565642c20627574206077686f60206d75737420616363657074206974207072696f7220746f206065787069726174696f6e602e48507265617070726f76616c4578706972656404011477686f7365000130543a3a4163636f756e744964000e043901412071756575656420757365726e616d6520706173736564206974732065787069726174696f6e20776974686f7574206265696e6720636c61696d656420616e64207761732072656d6f7665642e485072696d617279557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000f0401014120757365726e616d6520776173207365742061732061207072696d61727920616e642063616e206265206c6f6f6b65642075702066726f6d206077686f602e5c44616e676c696e67557365726e616d6552656d6f76656408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e0010085d01412064616e676c696e6720757365726e616d652028617320696e2c206120757365726e616d6520636f72726573706f6e64696e6720746f20616e206163636f756e742074686174206861732072656d6f766564206974736c6964656e746974792920686173206265656e2072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65747d010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000081010c3870616c6c65745f7574696c6974791870616c6c6574144576656e74000118404261746368496e746572727570746564080114696e64657810010c7533320001146572726f7268013444697370617463684572726f7200000855014261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061734877656c6c20617320746865206572726f722e384261746368436f6d706c65746564000104c84261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e604261746368436f6d706c65746564576974684572726f7273000204b44261746368206f66206469737061746368657320636f6d706c657465642062757420686173206572726f72732e344974656d436f6d706c657465640003041d01412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206e6f206572726f722e284974656d4661696c65640401146572726f7268013444697370617463684572726f720004041101412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206572726f722e30446973706174636865644173040118726573756c748001384469737061746368526573756c7400050458412063616c6c2077617320646973706174636865642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657485010c3c70616c6c65745f6d756c74697369671870616c6c6574144576656e740404540001102c4e65774d756c74697369670c0124617070726f76696e67000130543a3a4163636f756e7449640001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c486173680000048c41206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e404d756c7469736967417070726f76616c100124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000104c841206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e404d756c74697369674578656375746564140124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000118726573756c748001384469737061746368526573756c740002049c41206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e444d756c746973696743616e63656c6c656410012863616e63656c6c696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000304a041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65748901083c70616c6c65745f6d756c74697369672454696d65706f696e74042c426c6f636b4e756d62657201300008011868656967687430012c426c6f636b4e756d626572000114696e64657810010c75333200008d010c3c70616c6c65745f657468657265756d1870616c6c6574144576656e7400010420457865637574656414011066726f6d9101011048313630000108746f91010110483136300001407472616e73616374696f6e5f686173683401104832353600012c657869745f726561736f6e9901012845786974526561736f6e00012865787472615f6461746138011c5665633c75383e000004c8416e20657468657265756d207472616e73616374696f6e20776173207375636365737366756c6c792065786563757465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749101083c7072696d69746976655f7479706573104831363000000400950101205b75383b2032305d0000950100000314000000080099010c2065766d5f636f7265146572726f722845786974526561736f6e0001101c5375636365656404009d01012c4578697453756363656564000000144572726f720400a1010124457869744572726f72000100185265766572740400b10101284578697452657665727400020014466174616c0400b501012445786974466174616c000300009d010c2065766d5f636f7265146572726f722c457869745375636365656400010c1c53746f707065640000002052657475726e656400010020537569636964656400020000a1010c2065766d5f636f7265146572726f7224457869744572726f7200014038537461636b556e646572666c6f7700000034537461636b4f766572666c6f770001002c496e76616c69644a756d7000020030496e76616c696452616e67650003004444657369676e61746564496e76616c69640004002c43616c6c546f6f446565700005003c437265617465436f6c6c6973696f6e0006004c437265617465436f6e74726163744c696d69740007002c496e76616c6964436f64650400a50101184f70636f6465000f002c4f75744f664f6666736574000800204f75744f66476173000900244f75744f6646756e64000a002c5043556e646572666c6f77000b002c437265617465456d707479000c00144f746865720400a9010144436f773c277374617469632c207374723e000d00204d61784e6f6e6365000e0000a5010c2065766d5f636f7265186f70636f6465184f70636f64650000040008010875380000a901040c436f7704045401ad01000400ad01000000ad010000050200b1010c2065766d5f636f7265146572726f72284578697452657665727400010420526576657274656400000000b5010c2065766d5f636f7265146572726f722445786974466174616c000110304e6f74537570706f7274656400000048556e68616e646c6564496e746572727570740001004043616c6c4572726f724173466174616c0400a1010124457869744572726f72000200144f746865720400a9010144436f773c277374617469632c207374723e00030000b9010c2870616c6c65745f65766d1870616c6c6574144576656e740404540001140c4c6f6704010c6c6f67bd01010c4c6f670000047c457468657265756d206576656e74732066726f6d20636f6e7472616374732e1c4372656174656404011c616464726573739101011048313630000104b44120636f6e747261637420686173206265656e206372656174656420617420676976656e20616464726573732e34437265617465644661696c656404011c61646472657373910101104831363000020405014120636f6e74726163742077617320617474656d7074656420746f20626520637265617465642c206275742074686520657865637574696f6e206661696c65642e20457865637574656404011c616464726573739101011048313630000304f84120636f6e747261637420686173206265656e206578656375746564207375636365737366756c6c79207769746820737461746573206170706c6965642e3845786563757465644661696c656404011c61646472657373910101104831363000040465014120636f6e747261637420686173206265656e2065786563757465642077697468206572726f72732e20537461746573206172652072657665727465642077697468206f6e6c79206761732066656573206170706c6965642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574bd010c20657468657265756d0c6c6f670c4c6f6700000c011c616464726573739101011048313630000118746f70696373c10101245665633c483235363e0001106461746138011442797465730000c1010000023400c5010c3c70616c6c65745f626173655f6665651870616c6c6574144576656e7400010c404e65774261736546656550657247617304010c666565c9010110553235360000003c426173654665654f766572666c6f77000100344e6577456c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000200047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c901083c7072696d69746976655f7479706573105532353600000400cd0101205b7536343b20345d0000cd01000003040000003000d1010c3473705f61726974686d65746963287065725f7468696e67731c5065726d696c6c0000040010010c7533320000d5010c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144576656e740404540001041c436c61696d65640c0124726563697069656e74000130543a3a4163636f756e744964000118736f75726365d90101304d756c746941646472657373000118616d6f756e7418013042616c616e63654f663c543e0000048c536f6d656f6e6520636c61696d656420736f6d65206e617469766520746f6b656e732e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d9010c5470616c6c65745f61697264726f705f636c61696d73147574696c73304d756c7469416464726573730001080c45564d0400dd01013c457468657265756d41646472657373000000184e6174697665040000012c4163636f756e744964333200010000dd01105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733c457468657265756d4164647265737300000400950101205b75383b2032305d0000e1010c3070616c6c65745f70726f78791870616c6c6574144576656e740404540001143450726f78794578656375746564040118726573756c748001384469737061746368526573756c74000004bc412070726f78792077617320657865637574656420636f72726563746c792c20776974682074686520676976656e2e2c507572654372656174656410011070757265000130543a3a4163636f756e74496400010c77686f000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f787954797065000150646973616d626967756174696f6e5f696e646578e901010c753136000108dc412070757265206163636f756e7420686173206265656e2063726561746564206279206e65772070726f7879207769746820676976656e90646973616d626967756174696f6e20696e64657820616e642070726f787920747970652e24416e6e6f756e6365640c01107265616c000130543a3a4163636f756e74496400011470726f7879000130543a3a4163636f756e74496400012463616c6c5f6861736834013443616c6c486173684f663c543e000204e0416e20616e6e6f756e63656d656e742077617320706c6163656420746f206d616b6520612063616c6c20696e20746865206675747572652e2850726f7879416464656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00030448412070726f7879207761732061646465642e3050726f787952656d6f76656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00040450412070726f7879207761732072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574e501085874616e676c655f746573746e65745f72756e74696d652450726f7879547970650001100c416e790000002c4e6f6e5472616e7366657200010028476f7665726e616e63650002001c5374616b696e6700030000e9010000050400ed010c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144576656e74040454000160384f70657261746f724a6f696e656404010c77686f000130543a3a4163636f756e7449640000045c416e206f70657261746f7220686173206a6f696e65642e604f70657261746f724c656176696e675363686564756c656404010c77686f000130543a3a4163636f756e7449640001048c416e206f70657261746f7220686173207363686564756c656420746f206c656176652e584f70657261746f724c6561766543616e63656c6c656404010c77686f000130543a3a4163636f756e744964000204b8416e206f70657261746f72206861732063616e63656c6c6564207468656972206c6561766520726571756573742e544f70657261746f724c65617665457865637574656404010c77686f000130543a3a4163636f756e744964000304b4416e206f70657261746f7220686173206578656375746564207468656972206c6561766520726571756573742e404f70657261746f72426f6e644d6f726508010c77686f000130543a3a4163636f756e74496400013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00040498416e206f70657261746f722068617320696e63726561736564207468656972207374616b652e644f70657261746f72426f6e644c6573735363686564756c656408010c77686f000130543a3a4163636f756e744964000138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504c8416e206f70657261746f7220686173207363686564756c656420746f206465637265617365207468656972207374616b652e604f70657261746f72426f6e644c657373457865637574656404010c77686f000130543a3a4163636f756e744964000604b8416e206f70657261746f7220686173206578656375746564207468656972207374616b652064656372656173652e644f70657261746f72426f6e644c65737343616e63656c6c656404010c77686f000130543a3a4163636f756e744964000704dc416e206f70657261746f72206861732063616e63656c6c6564207468656972207374616b6520646563726561736520726571756573742e4c4f70657261746f7257656e744f66666c696e6504010c77686f000130543a3a4163636f756e74496400080474416e206f70657261746f722068617320676f6e65206f66666c696e652e484f70657261746f7257656e744f6e6c696e6504010c77686f000130543a3a4163636f756e74496400090470416e206f70657261746f722068617320676f6e65206f6e6c696e652e244465706f73697465640c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000a046041206465706f73697420686173206265656e206d6164652e445363686564756c656477697468647261770c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000b047c416e20776974686472617720686173206265656e207363686564756c65642e404578656375746564776974686472617704010c77686f000130543a3a4163636f756e744964000c0478416e20776974686472617720686173206265656e2065786563757465642e4443616e63656c6c6564776974686472617704010c77686f000130543a3a4163636f756e744964000d047c416e20776974686472617720686173206265656e2063616e63656c6c65642e2444656c65676174656410010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000e046c412064656c65676174696f6e20686173206265656e206d6164652e685363686564756c656444656c656761746f72426f6e644c65737310010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000f04bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e207363686564756c65642e64457865637574656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001004b8412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2065786563757465642e6843616e63656c6c656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001104bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2063616e63656c6c65642e54496e63656e74697665415059416e644361705365740c01207661756c745f6964180128543a3a5661756c74496400010c617079f501014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e00120419014576656e7420656d6974746564207768656e20616e20696e63656e746976652041505920616e6420636170206172652073657420666f72206120726577617264207661756c7450426c75657072696e7457686974656c6973746564040130626c75657072696e745f696410010c753332001304e44576656e7420656d6974746564207768656e206120626c75657072696e742069732077686974656c697374656420666f7220726577617264734c417373657455706461746564496e5661756c7410010c77686f000130543a3a4163636f756e7449640001207661756c745f6964180128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6ef901012c4173736574416374696f6e00140498417373657420686173206265656e207570646174656420746f20726577617264207661756c743c4f70657261746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e001504644f70657261746f7220686173206265656e20736c61736865644044656c656761746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0016046844656c656761746f7220686173206265656e20736c61736865642c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e0017049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e04744576656e747320656d6974746564206279207468652070616c6c65742ef1010c4474616e676c655f7072696d697469766573207365727669636573144173736574041c417373657449640118010818437573746f6d040018011c4173736574496400000014457263323004009101013473705f636f72653a3a4831363000010000f5010c3473705f61726974686d65746963287065725f7468696e67731c50657263656e740000040008010875380000f901107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c726577617264732c4173736574416374696f6e0001080c4164640000001852656d6f766500010000fd010c3c70616c6c65745f7365727669636573186d6f64756c65144576656e7404045400014040426c75657072696e74437265617465640801146f776e6572000130543a3a4163636f756e74496404bc546865206163636f756e742074686174206372656174656420746865207365727669636520626c75657072696e742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0004a441206e6577207365727669636520626c75657072696e7420686173206265656e20637265617465642e3c507265526567697374726174696f6e0801206f70657261746f72000130543a3a4163636f756e74496404bc546865206163636f756e742074686174207072652d7265676973746572656420617320616e206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0104dc416e206f70657261746f7220686173207072652d7265676973746572656420666f722061207365727669636520626c75657072696e742e285265676973746572656410012070726f7669646572000130543a3a4163636f756e74496404a8546865206163636f756e74207468617420726567697374657265642061732061206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e012c707265666572656e6365730102014c4f70657261746f72507265666572656e63657304f454686520707265666572656e63657320666f7220746865206f70657261746f7220666f72207468697320737065636966696320626c75657072696e742e0144726567697374726174696f6e5f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e049054686520617267756d656e7473207573656420666f7220726567697374726174696f6e2e020490416e206e6577206f70657261746f7220686173206265656e20726567697374657265642e30556e726567697374657265640801206f70657261746f72000130543a3a4163636f756e74496404b4546865206163636f756e74207468617420756e7265676973746572656420617320616d206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e030488416e206f70657261746f7220686173206265656e20756e726567697374657265642e4c507269636554617267657473557064617465640c01206f70657261746f72000130543a3a4163636f756e74496404c4546865206163636f756e74207468617420757064617465642074686520617070726f76616c20707265666572656e63652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e013470726963655f74617267657473090201305072696365546172676574730458546865206e657720707269636520746172676574732e0404cc546865207072696365207461726765747320666f7220616e206f70657261746f7220686173206265656e20757064617465642e40536572766963655265717565737465641801146f776e6572000130543a3a4163636f756e744964049c546865206163636f756e742074686174207265717565737465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c733d0201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f7665643d0201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e01186173736574734102013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e05048441206e6577207365727669636520686173206265656e207265717565737465642e585365727669636552657175657374417070726f7665641401206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e74207468617420617070726f7665642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c733d0201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f7665643d0201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e060490412073657276696365207265717565737420686173206265656e20617070726f7665642e58536572766963655265717565737452656a65637465640c01206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e7420746861742072656a65637465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e070490412073657276696365207265717565737420686173206265656e2072656a65637465642e4053657276696365496e697469617465641401146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128726571756573745f696430010c75363404c0546865204944206f662074686520736572766963652072657175657374207468617420676f7420617070726f7665642e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e01186173736574734102013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e08047441207365727669636520686173206265656e20696e697469617465642e44536572766963655465726d696e617465640c01146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e09047841207365727669636520686173206265656e207465726d696e617465642e244a6f6243616c6c656414011863616c6c6572000130543a3a4163636f756e7449640480546865206163636f756e7420746861742063616c6c656420746865206a6f622e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0110617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e046454686520617267756d656e7473206f6620746865206a6f622e0a045841206a6f6220686173206265656e2063616c6c65642e484a6f62526573756c745375626d69747465641401206f70657261746f72000130543a3a4163636f756e74496404a8546865206163636f756e742074686174207375626d697474656420746865206a6f6220726573756c742e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0118726573756c740d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e045854686520726573756c74206f6620746865206a6f622e0b048041206a6f6220726573756c7420686173206265656e207375626d69747465642e2c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e000c049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e38556e6170706c696564536c617368180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780d048c416e204f70657261746f722068617320616e20756e6170706c69656420736c6173682e38536c617368446973636172646564180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780e0484416e20556e6170706c69656420536c61736820676f74206469736361726465642e904d6173746572426c75657072696e74536572766963654d616e61676572526576697365640801207265766973696f6e10010c75333204f0546865207265766973696f6e206e756d626572206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e011c61646472657373910101104831363004d05468652061646472657373206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e0f04d8546865204d617374657220426c75657072696e742053657276696365204d616e6167657220686173206265656e20726576697365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657401020c4474616e676c655f7072696d6974697665732073657276696365734c4f70657261746f72507265666572656e636573000008010c6b65790502013465636473613a3a5075626c696300013470726963655f74617267657473090201305072696365546172676574730000050200000321000000080009020c4474616e676c655f7072696d69746976657320736572766963657330507269636554617267657473000014010c63707530010c75363400010c6d656d30010c75363400012c73746f726167655f68646430010c75363400012c73746f726167655f73736430010c75363400013073746f726167655f6e766d6530010c75363400000d020000021102001102104474616e676c655f7072696d697469766573207365727669636573146669656c64144669656c6408044300244163636f756e74496401000140104e6f6e6500000010426f6f6c0400200110626f6f6c0001001455696e74380400080108753800020010496e743804001502010869380003001855696e7431360400e901010c75313600040014496e74313604001902010c6931360005001855696e743332040010010c75333200060014496e74333204001d02010c6933320007001855696e743634040030010c75363400080014496e74363404002102010c69363400090018537472696e6704002502017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e000a00144279746573040029020180426f756e6465645665633c75382c20433a3a4d61784669656c647353697a653e000b0014417272617904002d0201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000c00104c69737404002d0201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000d001853747275637408002502017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e00003102016d01426f756e6465645665633c0a28426f756e646564537472696e673c433a3a4d61784669656c647353697a653e2c20426f783c4669656c643c432c204163636f756e7449643e3e292c20433a3a0a4d61784669656c647353697a653e000e00244163636f756e74496404000001244163636f756e744964006400001502000005090019020000050a001d020000050b0021020000050c002502104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040029020144426f756e6465645665633c75382c20533e000029020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00002d020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540111020453000004000d0201185665633c543e000031020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013502045300000400390201185665633c543e0000350200000408250211020039020000023502003d0200000200004102000002180045020c4470616c6c65745f74616e676c655f6c73741870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f737461746549020124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654d02019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e4902104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e67000200004d02104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e50436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d6265720000510204184f7074696f6e0404540155020108104e6f6e6500000010536f6d650400550200000100005502104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e64436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e74496400010000590208306672616d655f73797374656d14506861736500010c384170706c7945787472696e736963040010010c7533320000003046696e616c697a6174696f6e00010038496e697469616c697a6174696f6e000200005d02000002390100610208306672616d655f73797374656d584c61737452756e74696d6555706772616465496e666f0000080130737065635f76657273696f6e6502014c636f6465633a3a436f6d706163743c7533323e000124737065635f6e616d65ad01016473705f72756e74696d653a3a52756e74696d65537472696e67000065020000061000690208306672616d655f73797374656d60436f646555706772616465417574686f72697a6174696f6e0404540000080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00006d020c306672616d655f73797374656d1870616c6c65741043616c6c04045400012c1872656d61726b04011872656d61726b38011c5665633c75383e00000c684d616b6520736f6d65206f6e2d636861696e2072656d61726b2e008843616e20626520657865637574656420627920657665727920606f726967696e602e387365745f686561705f7061676573040114706167657330010c753634000104f853657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e207365745f636f6465040110636f646538011c5665633c75383e0002046453657420746865206e65772072756e74696d6520636f64652e5c7365745f636f64655f776974686f75745f636865636b73040110636f646538011c5665633c75383e000310190153657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e0051014e6f746520746861742072756e74696d652075706772616465732077696c6c206e6f742072756e20696620746869732069732063616c6c656420776974682061206e6f742d696e6372656173696e6720737065632076657273696f6e212c7365745f73746f726167650401146974656d73710201345665633c4b657956616c75653e0004046853657420736f6d65206974656d73206f662073746f726167652e306b696c6c5f73746f726167650401106b657973790201205665633c4b65793e000504744b696c6c20736f6d65206974656d732066726f6d2073746f726167652e2c6b696c6c5f70726566697808011870726566697838010c4b657900011c7375626b65797310010c75333200061011014b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e0039012a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465723d0174686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e4472656d61726b5f776974685f6576656e7404011872656d61726b38011c5665633c75383e000704a44d616b6520736f6d65206f6e2d636861696e2072656d61726b20616e6420656d6974206576656e742e44617574686f72697a655f75706772616465040124636f64655f6861736834011c543a3a486173680009106101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e80617574686f72697a655f757067726164655f776974686f75745f636865636b73040124636f64655f6861736834011c543a3a48617368000a206101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e005d015741524e494e473a205468697320617574686f72697a657320616e207570677261646520746861742077696c6c2074616b6520706c61636520776974686f757420616e792073616665747920636865636b732c20666f7259016578616d706c652074686174207468652073706563206e616d652072656d61696e73207468652073616d6520616e642074686174207468652076657273696f6e206e756d62657220696e637265617365732e204e6f74f07265636f6d6d656e64656420666f72206e6f726d616c207573652e205573652060617574686f72697a655f757067726164656020696e73746561642e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e606170706c795f617574686f72697a65645f75706772616465040110636f646538011c5665633c75383e000b24550150726f766964652074686520707265696d616765202872756e74696d652062696e617279292060636f64656020666f7220616e2075706772616465207468617420686173206265656e20617574686f72697a65642e00490149662074686520617574686f72697a6174696f6e20726571756972656420612076657273696f6e20636865636b2c20746869732063616c6c2077696c6c20656e73757265207468652073706563206e616d65e872656d61696e7320756e6368616e67656420616e6420746861742074686520737065632076657273696f6e2068617320696e637265617365642e005901446570656e64696e67206f6e207468652072756e74696d65277320604f6e536574436f64656020636f6e66696775726174696f6e2c20746869732066756e6374696f6e206d6179206469726563746c79206170706c791101746865206e65772060636f64656020696e207468652073616d6520626c6f636b206f7220617474656d707420746f207363686564756c652074686520757067726164652e0060416c6c206f726967696e732061726520616c6c6f7765642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e7102000002750200750200000408383800790200000238007d020c306672616d655f73797374656d186c696d69747330426c6f636b5765696768747300000c0128626173655f626c6f636b2801185765696768740001246d61785f626c6f636b2801185765696768740001247065725f636c617373810201845065724469737061746368436c6173733c57656967687473506572436c6173733e000081020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c617373040454018502000c01186e6f726d616c850201045400012c6f7065726174696f6e616c85020104540001246d616e6461746f72798502010454000085020c306672616d655f73797374656d186c696d6974733c57656967687473506572436c6173730000100138626173655f65787472696e7369632801185765696768740001346d61785f65787472696e736963890201384f7074696f6e3c5765696768743e0001246d61785f746f74616c890201384f7074696f6e3c5765696768743e0001207265736572766564890201384f7074696f6e3c5765696768743e0000890204184f7074696f6e04045401280108104e6f6e6500000010536f6d6504002800000100008d020c306672616d655f73797374656d186c696d6974732c426c6f636b4c656e677468000004010c6d6178910201545065724469737061746368436c6173733c7533323e000091020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540110000c01186e6f726d616c1001045400012c6f7065726174696f6e616c100104540001246d616e6461746f72791001045400009502082873705f776569676874733c52756e74696d65446257656967687400000801107265616430010c753634000114777269746530010c75363400009902082873705f76657273696f6e3852756e74696d6556657273696f6e0000200124737065635f6e616d65ad01013452756e74696d65537472696e67000124696d706c5f6e616d65ad01013452756e74696d65537472696e67000144617574686f72696e675f76657273696f6e10010c753332000130737065635f76657273696f6e10010c753332000130696d706c5f76657273696f6e10010c753332000110617069739d02011c4170697356656300014c7472616e73616374696f6e5f76657273696f6e10010c75333200013473746174655f76657273696f6e080108753800009d02040c436f7704045401a102000400a102000000a102000002a50200a50200000408a9021000a902000003080000000800ad020c306672616d655f73797374656d1870616c6c6574144572726f720404540001243c496e76616c6964537065634e616d650000081101546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e685370656356657273696f6e4e65656473546f496e63726561736500010841015468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e744661696c6564546f4578747261637452756e74696d6556657273696f6e00020cec4661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e0009014569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e4c4e6f6e44656661756c74436f6d706f73697465000304fc537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e3c4e6f6e5a65726f526566436f756e74000404350154686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e3043616c6c46696c7465726564000504d0546865206f726967696e2066696c7465722070726576656e74207468652063616c6c20746f20626520646973706174636865642e6c4d756c7469426c6f636b4d6967726174696f6e734f6e676f696e67000604550141206d756c74692d626c6f636b206d6967726174696f6e206973206f6e676f696e6720616e642070726576656e7473207468652063757272656e7420636f64652066726f6d206265696e67207265706c616365642e444e6f7468696e67417574686f72697a6564000704584e6f207570677261646520617574686f72697a65642e30556e617574686f72697a656400080494546865207375626d697474656420636f6465206973206e6f7420617574686f72697a65642e046c4572726f7220666f72207468652053797374656d2070616c6c6574b1020c4070616c6c65745f74696d657374616d701870616c6c65741043616c6c0404540001040c73657404010c6e6f772c0124543a3a4d6f6d656e7400004c54536574207468652063757272656e742074696d652e005501546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6ed470686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e0041015468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e7420737065636966696564206279685b60436f6e6669673a3a4d696e696d756d506572696f64605d2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0051015468697320646973706174636820636c617373206973205f4d616e6461746f72795f20746f20656e73757265206974206765747320657865637574656420696e2074686520626c6f636b2e204265206177617265510174686174206368616e67696e672074686520636f6d706c6578697479206f6620746869732063616c6c20636f756c6420726573756c742065786861757374696e6720746865207265736f757263657320696e206184626c6f636b20746f206578656375746520616e79206f746865722063616c6c732e0034232320436f6d706c657869747931012d20604f2831296020284e6f7465207468617420696d706c656d656e746174696f6e73206f6620604f6e54696d657374616d7053657460206d75737420616c736f20626520604f283129602955012d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f283129602062656361757365206f6620604469645570646174653a3a74616b656020696e402020606f6e5f66696e616c697a656029d42d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f736574602e204d75737420626520604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb5020c2c70616c6c65745f7375646f1870616c6c65741043616c6c040454000114107375646f04011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000004350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e547375646f5f756e636865636b65645f77656967687408011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000114350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e2d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b05375646f207573657220746f20737065636966792074686520776569676874206f66207468652063616c6c2e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e1c7365745f6b657904010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e0002085d0141757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f106b65792e1c7375646f5f617308010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0003104d0141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d406120676976656e206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2872656d6f76655f6b657900040c845065726d616e656e746c792072656d6f76657320746865207375646f206b65792e006c2a2a546869732063616e6e6f7420626520756e2d646f6e652e2a2a040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb902085874616e676c655f746573746e65745f72756e74696d652c52756e74696d6543616c6c0001941853797374656d04006d0201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53797374656d2c2052756e74696d653e0001002454696d657374616d700400b10201b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54696d657374616d702c2052756e74696d653e000200105375646f0400b50201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5375646f2c2052756e74696d653e000300184173736574730400bd0201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4173736574732c2052756e74696d653e0005002042616c616e6365730400c50201b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c42616c616e6365732c2052756e74696d653e00060010426162650400cd0201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426162652c2052756e74696d653e0009001c4772616e6470610400f10201b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4772616e6470612c2052756e74696d653e000a001c496e64696365730400210301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496e64696365732c2052756e74696d653e000b002444656d6f63726163790400250301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44656d6f63726163792c2052756e74696d653e000c001c436f756e63696c0400410301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436f756e63696c2c2052756e74696d653e000d001c56657374696e670400450301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c56657374696e672c2052756e74696d653e000e0024456c656374696f6e7304004d0301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e732c2052756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400550301fd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e50726f76696465724d756c746950686173652c2052756e74696d653e0010001c5374616b696e6704003d0401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5374616b696e672c2052756e74696d653e0011001c53657373696f6e0400710401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657373696f6e2c2052756e74696d653e0012002054726561737572790400790401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54726561737572792c2052756e74696d653e00140020426f756e746965730400810401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426f756e746965732c2052756e74696d653e001500344368696c64426f756e746965730400850401c90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4368696c64426f756e746965732c2052756e74696d653e00160020426167734c6973740400890401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426167734c6973742c2052756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304008d0401d10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4e6f6d696e6174696f6e506f6f6c732c2052756e74696d653e001800245363686564756c65720400a90401b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5363686564756c65722c2052756e74696d653e00190020507265696d6167650400b10401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c507265696d6167652c2052756e74696d653e001a001c547850617573650400b50401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c547850617573652c2052756e74696d653e001c0020496d4f6e6c696e650400b90401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496d4f6e6c696e652c2052756e74696d653e001d00204964656e746974790400c50401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4964656e746974792c2052756e74696d653e001e001c5574696c6974790400690501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5574696c6974792c2052756e74696d653e001f00204d756c74697369670400810501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c74697369672c2052756e74696d653e00200020457468657265756d0400890501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c457468657265756d2c2052756e74696d653e0021000c45564d0400b10501a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c45564d2c2052756e74696d653e0022002844796e616d69634665650400c10501bd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44796e616d69634665652c2052756e74696d653e0024001c426173654665650400c50501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426173654665652c2052756e74696d653e00250044486f7466697853756666696369656e74730400c90501d90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c486f7466697853756666696369656e74732c2052756e74696d653e00260018436c61696d730400d10501ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436c61696d732c2052756e74696d653e0027001450726f78790400fd0501a90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c50726f78792c2052756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400050601e50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c7469417373657444656c65676174696f6e2c2052756e74696d653e002d0020536572766963657304001d0601b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657276696365732c2052756e74696d653e0033000c4c73740400ed0601a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4c73742c2052756e74696d653e00340000bd020c3470616c6c65745f6173736574731870616c6c65741043616c6c080454000449000180186372656174650c010869646d01014c543a3a41737365744964506172616d6574657200011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e6365180128543a3a42616c616e636500004ce849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d2061207075626c6963206f726967696e2e00250154686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c7920616e6420697473206f776e657220697320746865206f726967696e2e006101546865206f726967696e206d75737420636f6e666f726d20746f2074686520636f6e6669677572656420604372656174654f726967696e6020616e6420686176652073756666696369656e742066756e647320667265652e00bc46756e6473206f662073656e64657220617265207265736572766564206279206041737365744465706f736974602e002c506172616d65746572733a59012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d206061646d696e603a205468652061646d696e206f66207468697320636c617373206f66206173736574732e205468652061646d696e2069732074686520696e697469616c2061646472657373206f6620656163689c6d656d626572206f662074686520617373657420636c61737327732061646d696e207465616d2e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e0098456d69747320604372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296030666f7263655f63726561746510010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00013469735f73756666696369656e74200110626f6f6c00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500014cf849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d20612070726976696c65676564206f726967696e2e00b454686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c792e00a4546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e602e009c556e6c696b652060637265617465602c206e6f2066756e6473206172652072657365727665642e0059012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d20606f776e6572603a20546865206f776e6572206f66207468697320636c617373206f66206173736574732e20546865206f776e6572206861732066756c6c20737570657275736572207065726d697373696f6e7325016f76657220746869732061737365742c20627574206d6179206c61746572206368616e676520616e6420636f6e66696775726520746865207065726d697373696f6e73207573696e6790607472616e736665725f6f776e6572736869706020616e6420607365745f7465616d602e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e00ac456d6974732060466f7263654372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f283129603473746172745f64657374726f7904010869646d01014c543a3a41737365744964506172616d6574657200022cdc5374617274207468652070726f63657373206f662064657374726f79696e6720612066756e6769626c6520617373657420636c6173732e0059016073746172745f64657374726f79602069732074686520666972737420696e206120736572696573206f662065787472696e7369637320746861742073686f756c642062652063616c6c65642c20746f20616c6c6f77786465737472756374696f6e206f6620616e20617373657420636c6173732e005101546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e60206f72206d75737420626520605369676e65646020627920746865206173736574277320606f776e6572602e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00f854686520617373657420636c617373206d7573742062652066726f7a656e206265666f72652063616c6c696e67206073746172745f64657374726f79602e4064657374726f795f6163636f756e747304010869646d01014c543a3a41737365744964506172616d65746572000330cc44657374726f7920616c6c206163636f756e7473206173736f6369617465642077697468206120676976656e2061737365742e005d016064657374726f795f6163636f756e7473602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79310164657374726f7920616c6c206163636f756e74732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d697460206163636f756e747320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d4456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f7965644163636f756e747360206576656e742e4464657374726f795f617070726f76616c7304010869646d01014c543a3a41737365744964506172616d65746572000430610144657374726f7920616c6c20617070726f76616c73206173736f6369617465642077697468206120676976656e20617373657420757020746f20746865206d61782028543a3a52656d6f76654974656d734c696d6974292e0061016064657374726f795f617070726f76616c73602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79390164657374726f7920616c6c20617070726f76616c732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d69746020617070726f76616c7320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d8456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f796564417070726f76616c7360206576656e742e3866696e6973685f64657374726f7904010869646d01014c543a3a41737365744964506172616d65746572000528c4436f6d706c6574652064657374726f79696e6720617373657420616e6420756e726573657276652063757272656e63792e0055016066696e6973685f64657374726f79602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e64207468655901617373657420697320696e2061206044657374726f79696e67602073746174652e20416c6c206163636f756e7473206f7220617070726f76616c732073686f756c642062652064657374726f796564206265666f72651468616e642e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00e045616368207375636365737366756c2063616c6c20656d6974732074686520604576656e743a3a44657374726f79656460206576656e742e106d696e740c010869646d01014c543a3a41737365744964506172616d6574657200012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000630884d696e7420617373657473206f66206120706172746963756c617220636c6173732e003901546865206f726967696e206d757374206265205369676e656420616e64207468652073656e646572206d7573742062652074686520497373756572206f662074686520617373657420606964602e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206d696e7465642e0d012d206062656e6566696369617279603a20546865206163636f756e7420746f206265206372656469746564207769746820746865206d696e746564206173736574732ec42d2060616d6f756e74603a2054686520616d6f756e74206f662074686520617373657420746f206265206d696e7465642e0094456d697473206049737375656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296055014d6f6465733a205072652d6578697374696e672062616c616e6365206f66206062656e6566696369617279603b204163636f756e74207072652d6578697374656e6365206f66206062656e6566696369617279602e106275726e0c010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500073c4501526564756365207468652062616c616e6365206f66206077686f60206279206173206d75636820617320706f737369626c6520757020746f2060616d6f756e746020617373657473206f6620606964602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204d616e61676572206f662074686520617373657420606964602e00d04261696c73207769746820604e6f4163636f756e746020696620746865206077686f6020697320616c726561647920646561642e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206275726e65642ea02d206077686f603a20546865206163636f756e7420746f20626520646562697465642066726f6d2e29012d2060616d6f756e74603a20546865206d6178696d756d20616d6f756e74206279207768696368206077686f6027732062616c616e63652073686f756c6420626520726564756365642e005101456d69747320604275726e6564602077697468207468652061637475616c20616d6f756e74206275726e65642e20496620746869732074616b6573207468652062616c616e636520746f2062656c6f772074686539016d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74206275726e656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296009014d6f6465733a20506f73742d6578697374656e6365206f66206077686f603b20507265202620706f7374205a6f6d6269652d737461747573206f66206077686f602e207472616e736665720c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000848d04d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e4c7472616e736665725f6b6565705f616c6976650c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500094859014d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722c206b656570696e67207468652073656e646572206163636f756e7420616c6976652e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e38666f7263655f7472616e7366657210010869646d01014c543a3a41737365744964506172616d65746572000118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000a4cb44d6f766520736f6d65206173736574732066726f6d206f6e65206163636f756e7420746f20616e6f746865722e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e982d2060736f75726365603a20546865206163636f756e7420746f20626520646562697465642e942d206064657374603a20546865206163636f756e7420746f2062652063726564697465642e59012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652060736f757263656027732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e64590160646573746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e4d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652060736f75726365602062616c616e63652061626f7665207a65726f20627574d462656c6f7720746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f66206064657374603b20506f73742d6578697374656e6365206f662060736f75726365603b204163636f756e74207072652d6578697374656e6365206f661c6064657374602e18667265657a6508010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000b305501446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e20617373657420606964602066726f6d20616e206163636f756e74206077686f602e206077686f604d016d75737420616c726561647920657869737420617320616e20656e74727920696e20604163636f756e746073206f66207468652061737365742e20496620796f752077616e7420746f20667265657a6520616ef46163636f756e74207468617420646f6573206e6f74206861766520616e20656e7472792c207573652060746f7563685f6f74686572602066697273742e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e882d206077686f603a20546865206163636f756e7420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f28312960107468617708010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000c28e8416c6c6f7720756e70726976696c65676564207472616e736665727320746f20616e642066726f6d20616e206163636f756e7420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e902d206077686f603a20546865206163636f756e7420746f20626520756e66726f7a656e2e003c456d6974732060546861776564602e00385765696768743a20604f2831296030667265657a655f617373657404010869646d01014c543a3a41737365744964506172616d65746572000d24f0446973616c6c6f77206675727468657220756e70726976696c65676564207472616e736665727320666f722074686520617373657420636c6173732e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f2831296028746861775f617373657404010869646d01014c543a3a41737365744964506172616d65746572000e24c4416c6c6f7720756e70726976696c65676564207472616e736665727320666f722074686520617373657420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206265207468617765642e003c456d6974732060546861776564602e00385765696768743a20604f28312960487472616e736665725f6f776e65727368697008010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e000f28744368616e676520746865204f776e6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742e0054456d69747320604f776e65724368616e676564602e00385765696768743a20604f28312960207365745f7465616d10010869646d01014c543a3a41737365744964506172616d65746572000118697373756572c10201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c10201504163636f756e7449644c6f6f6b75704f663c543e001030c44368616e676520746865204973737565722c2041646d696e20616e6420467265657a6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e0050456d69747320605465616d4368616e676564602e00385765696768743a20604f28312960307365745f6d6574616461746110010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c7308010875380011407853657420746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00d846756e6473206f662073656e64657220617265207265736572766564206163636f7264696e6720746f2074686520666f726d756c613a5101604d657461646174614465706f73697442617365202b204d657461646174614465706f73697450657242797465202a20286e616d652e6c656e202b2073796d626f6c2e6c656e29602074616b696e6720696e746f8c6163636f756e7420616e7920616c72656164792072657365727665642066756e64732e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e00385765696768743a20604f2831296038636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200122c80436c65617220746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00a4416e79206465706f73697420697320667265656420666f7220746865206173736574206f776e65722e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f7365745f6d6574616461746114010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c001338b8466f72636520746865206d6574616461746120666f7220616e20617373657420746f20736f6d652076616c75652e006c4f726967696e206d75737420626520466f7263654f726967696e2e0068416e79206465706f736974206973206c65667420616c6f6e652e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e0051015765696768743a20604f284e202b20532960207768657265204e20616e6420532061726520746865206c656e677468206f6620746865206e616d6520616e642073796d626f6c20726573706563746976656c792e50666f7263655f636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200142c80436c65617220746865206d6574616461746120666f7220616e2061737365742e006c4f726967696e206d75737420626520466f7263654f726967696e2e0060416e79206465706f7369742069732072657475726e65642e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f61737365745f73746174757320010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e000118697373756572c10201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500013469735f73756666696369656e74200110626f6f6c00012469735f66726f7a656e200110626f6f6c00155898416c746572207468652061747472696275746573206f66206120676976656e2061737365742e00744f726967696e206d7573742062652060466f7263654f726967696e602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e51012d206069735f73756666696369656e74603a20576865746865722061206e6f6e2d7a65726f2062616c616e6365206f662074686973206173736574206973206465706f736974206f662073756666696369656e744d0176616c756520746f206163636f756e7420666f722074686520737461746520626c6f6174206173736f6369617465642077697468206974732062616c616e63652073746f726167652e2049662073657420746f55016074727565602c207468656e206e6f6e2d7a65726f2062616c616e636573206d61792062652073746f72656420776974686f757420612060636f6e73756d657260207265666572656e63652028616e6420746875734d01616e20454420696e207468652042616c616e6365732070616c6c6574206f7220776861746576657220656c7365206973207573656420746f20636f6e74726f6c20757365722d6163636f756e742073746174652067726f777468292e3d012d206069735f66726f7a656e603a2057686574686572207468697320617373657420636c6173732069732066726f7a656e2065786365707420666f72207065726d697373696f6e65642f61646d696e34696e737472756374696f6e732e00e8456d697473206041737365745374617475734368616e67656460207769746820746865206964656e74697479206f66207468652061737365742e00385765696768743a20604f2831296040617070726f76655f7472616e736665720c010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650016502d01417070726f766520616e20616d6f756e74206f6620617373657420666f72207472616e7366657220627920612064656c6567617465642074686972642d7061727479206163636f756e742e00584f726967696e206d757374206265205369676e65642e004d01456e737572657320746861742060417070726f76616c4465706f7369746020776f727468206f66206043757272656e6379602069732072657365727665642066726f6d207369676e696e67206163636f756e745501666f722074686520707572706f7365206f6620686f6c64696e672074686520617070726f76616c2e20496620736f6d65206e6f6e2d7a65726f20616d6f756e74206f662061737365747320697320616c72656164794901617070726f7665642066726f6d207369676e696e67206163636f756e7420746f206064656c6567617465602c207468656e20697420697320746f70706564207570206f7220756e726573657276656420746f546d656574207468652072696768742076616c75652e0045014e4f54453a20546865207369676e696e67206163636f756e7420646f6573206e6f74206e65656420746f206f776e2060616d6f756e7460206f66206173736574732061742074686520706f696e74206f66446d616b696e6720746869732063616c6c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e0d012d206064656c6567617465603a20546865206163636f756e7420746f2064656c6567617465207065726d697373696f6e20746f207472616e736665722061737365742e49012d2060616d6f756e74603a2054686520616d6f756e74206f662061737365742074686174206d6179206265207472616e73666572726564206279206064656c6567617465602e204966207468657265206973e0616c726561647920616e20617070726f76616c20696e20706c6163652c207468656e207468697320616374732061646469746976656c792e0090456d6974732060417070726f7665645472616e7366657260206f6e20737563636573732e00385765696768743a20604f283129603c63616e63656c5f617070726f76616c08010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e001734490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e003d014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c616365206265747765656e207369676e657220616e642c6064656c6567617465602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f2831296054666f7263655f63616e63656c5f617070726f76616c0c010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e001834490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e0049014f726967696e206d7573742062652065697468657220466f7263654f726967696e206f72205369676e6564206f726967696e207769746820746865207369676e6572206265696e67207468652041646d696e686163636f756e74206f662074686520617373657420606964602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f28312960447472616e736665725f617070726f76656410010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012c64657374696e6174696f6ec10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650019484d015472616e7366657220736f6d652061737365742062616c616e63652066726f6d20612070726576696f75736c792064656c656761746564206163636f756e7420746f20736f6d652074686972642d7061727479206163636f756e742e0049014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c6163652062792074686520606f776e65726020746f207468651c7369676e65722e00590149662074686520656e7469726520616d6f756e7420617070726f76656420666f72207472616e73666572206973207472616e736665727265642c207468656e20616e79206465706f7369742070726576696f75736c79b472657365727665642062792060617070726f76655f7472616e736665726020697320756e72657365727665642e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e61012d20606f776e6572603a20546865206163636f756e742077686963682070726576696f75736c7920617070726f76656420666f722061207472616e73666572206f66206174206c656173742060616d6f756e746020616e64bc66726f6d207768696368207468652061737365742062616c616e63652077696c6c2062652077697468647261776e2e61012d206064657374696e6174696f6e603a20546865206163636f756e7420746f207768696368207468652061737365742062616c616e6365206f662060616d6f756e74602077696c6c206265207472616e736665727265642eb42d2060616d6f756e74603a2054686520616d6f756e74206f662061737365747320746f207472616e736665722e009c456d69747320605472616e73666572726564417070726f76656460206f6e20737563636573732e00385765696768743a20604f2831296014746f75636804010869646d01014c543a3a41737365744964506172616d65746572001a24c043726561746520616e206173736574206163636f756e7420666f72206e6f6e2d70726f7669646572206173736574732e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e005d012d20606f726967696e603a204d757374206265205369676e65643b20746865207369676e6572206163636f756e74206d75737420686176652073756666696369656e742066756e647320666f722061206465706f736974382020746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e18726566756e6408010869646d01014c543a3a41737365744964506172616d65746572000128616c6c6f775f6275726e200110626f6f6c001b28590152657475726e20746865206465706f7369742028696620616e7929206f6620616e206173736574206163636f756e74206f72206120636f6e73756d6572207265666572656e63652028696620616e7929206f6620616e206163636f756e742e0068546865206f726967696e206d757374206265205369676e65642e003d012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f72207768696368207468652063616c6c657220776f756c64206c696b6520746865206465706f7369742c2020726566756e6465642e5d012d2060616c6c6f775f6275726e603a20496620607472756560207468656e20617373657473206d61792062652064657374726f79656420696e206f7264657220746f20636f6d706c6574652074686520726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e3c7365745f6d696e5f62616c616e636508010869646d01014c543a3a41737365744964506172616d6574657200012c6d696e5f62616c616e6365180128543a3a42616c616e6365001c30945365747320746865206d696e696d756d2062616c616e6365206f6620616e2061737365742e0021014f6e6c7920776f726b73206966207468657265206172656e277420616e79206163636f756e747320746861742061726520686f6c64696e6720746865206173736574206f72206966e0746865206e65772076616c7565206f6620606d696e5f62616c616e636560206973206c657373207468616e20746865206f6c64206f6e652e00fc4f726967696e206d757374206265205369676e656420616e64207468652073656e6465722068617320746f20626520746865204f776e6572206f66207468652c617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742ec02d20606d696e5f62616c616e6365603a20546865206e65772076616c7565206f6620606d696e5f62616c616e6365602e00d4456d697473206041737365744d696e42616c616e63654368616e67656460206576656e74207768656e207375636365737366756c2e2c746f7563685f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001d288843726561746520616e206173736574206163636f756e7420666f72206077686f602e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e0061012d20606f726967696e603a204d757374206265205369676e65642062792060467265657a657260206f72206041646d696e60206f662074686520617373657420606964603b20746865207369676e6572206163636f756e74dc20206d75737420686176652073756666696369656e742066756e647320666f722061206465706f73697420746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e8c2d206077686f603a20546865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e30726566756e645f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001e285d0152657475726e20746865206465706f7369742028696620616e7929206f66206120746172676574206173736574206163636f756e742e2055736566756c20696620796f752061726520746865206465706f7369746f722e005d01546865206f726967696e206d757374206265205369676e656420616e642065697468657220746865206163636f756e74206f776e65722c206465706f7369746f722c206f72206173736574206041646d696e602e20496e61016f7264657220746f206275726e2061206e6f6e2d7a65726f2062616c616e6365206f66207468652061737365742c207468652063616c6c6572206d75737420626520746865206163636f756e7420616e642073686f756c64347573652060726566756e64602e0019012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420686f6c64696e672061206465706f7369742e7c2d206077686f603a20546865206163636f756e7420746f20726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e14626c6f636b08010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001f285901446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e206173736574206069646020746f20616e642066726f6d20616e206163636f756e74206077686f602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00b82d20606964603a20546865206964656e746966696572206f6620746865206163636f756e7427732061737365742e942d206077686f603a20546865206163636f756e7420746f20626520756e626c6f636b65642e0040456d6974732060426c6f636b6564602e00385765696768743a20604f28312960040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec1020c2873705f72756e74696d65306d756c746961646472657373304d756c74694164647265737308244163636f756e7449640100304163636f756e74496e6465780110011408496404000001244163636f756e74496400000014496e6465780400650201304163636f756e74496e6465780001000c526177040038011c5665633c75383e0002002441646472657373333204000401205b75383b2033325d000300244164647265737332300400950101205b75383b2032305d00040000c5020c3c70616c6c65745f62616c616e6365731870616c6c65741043616c6c080454000449000124507472616e736665725f616c6c6f775f646561746808011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e636500001cd45472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e003501607472616e736665725f616c6c6f775f6465617468602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e11014966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74b06f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e38666f7263655f7472616e736665720c0118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000208610145786163746c7920617320607472616e736665725f616c6c6f775f6465617468602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74446d6179206265207370656369666965642e4c7472616e736665725f6b6565705f616c69766508011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000318590153616d6520617320746865205b607472616e736665725f616c6c6f775f6465617468605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74606b696c6c20746865206f726967696e206163636f756e742e00e8393925206f66207468652074696d6520796f752077616e74205b607472616e736665725f616c6c6f775f6465617468605d20696e73746561642e00f05b607472616e736665725f616c6c6f775f6465617468605d3a207374727563742e50616c6c65742e68746d6c236d6574686f642e7472616e73666572307472616e736665725f616c6c08011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e0001286b6565705f616c697665200110626f6f6c00043c05015472616e736665722074686520656e74697265207472616e7366657261626c652062616c616e63652066726f6d207468652063616c6c6572206163636f756e742e0059014e4f54453a20546869732066756e6374696f6e206f6e6c7920617474656d70747320746f207472616e73666572205f7472616e7366657261626c655f2062616c616e6365732e2054686973206d65616e7320746861746101616e79206c6f636b65642c2072657365727665642c206f72206578697374656e7469616c206465706f7369747320287768656e20606b6565705f616c6976656020697320607472756560292c2077696c6c206e6f742062655d017472616e7366657272656420627920746869732066756e6374696f6e2e20546f20656e73757265207468617420746869732066756e6374696f6e20726573756c747320696e2061206b696c6c6564206163636f756e742c4501796f75206d69676874206e65656420746f207072657061726520746865206163636f756e742062792072656d6f76696e6720616e79207265666572656e636520636f756e746572732c2073746f72616765406465706f736974732c206574632e2e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205369676e65642e00a02d206064657374603a2054686520726563697069656e74206f6620746865207472616e736665722e59012d20606b6565705f616c697665603a204120626f6f6c65616e20746f2064657465726d696e652069662074686520607472616e736665725f616c6c60206f7065726174696f6e2073686f756c642073656e6420616c6c4d0120206f66207468652066756e647320746865206163636f756e74206861732c2063617573696e67207468652073656e646572206163636f756e7420746f206265206b696c6c6564202866616c7365292c206f72590120207472616e736665722065766572797468696e6720657863657074206174206c6561737420746865206578697374656e7469616c206465706f7369742c2077686963682077696c6c2067756172616e74656520746f9c20206b656570207468652073656e646572206163636f756e7420616c697665202874727565292e3c666f7263655f756e7265736572766508010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e74180128543a3a42616c616e636500050cb0556e7265736572766520736f6d652062616c616e63652066726f6d2061207573657220627920666f7263652e006c43616e206f6e6c792062652063616c6c656420627920524f4f542e40757067726164655f6163636f756e747304010c77686f3d0201445665633c543a3a4163636f756e7449643e0006207055706772616465206120737065636966696564206163636f756e742e00742d20606f726967696e603a204d75737420626520605369676e6564602e902d206077686f603a20546865206163636f756e7420746f2062652075706772616465642e005501546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966206174206c6561737420616c6c2062757420313025206f6620746865206163636f756e7473206e656564656420746f410162652075706772616465642e20285765206c657420736f6d65206e6f74206861766520746f206265207570677261646564206a75737420696e206f7264657220746f20616c6c6f7720666f722074686558706f73736962696c697479206f6620636875726e292e44666f7263655f7365745f62616c616e636508010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e0001206e65775f667265656d010128543a3a42616c616e636500080cac5365742074686520726567756c61722062616c616e6365206f66206120676976656e206163636f756e742e00b0546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e6c666f7263655f61646a7573745f746f74616c5f69737375616e6365080124646972656374696f6ec902014c41646a7573746d656e74446972656374696f6e00011464656c74616d010128543a3a42616c616e6365000914b841646a7573742074686520746f74616c2069737375616e636520696e20612073617475726174696e67207761792e00fc43616e206f6e6c792062652063616c6c656420627920726f6f7420616e6420616c77617973206e65656473206120706f736974697665206064656c7461602e002423204578616d706c65106275726e08011476616c75656d010128543a3a42616c616e63650001286b6565705f616c697665200110626f6f6c000a1cfc4275726e2074686520737065636966696564206c697175696420667265652062616c616e63652066726f6d20746865206f726967696e206163636f756e742e002501496620746865206f726967696e2773206163636f756e7420656e64732075702062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c7409016f6620746865206275726e20616e6420606b6565705f616c697665602069732066616c73652c20746865206163636f756e742077696c6c206265207265617065642e005101556e6c696b652073656e64696e672066756e647320746f2061205f6275726e5f20616464726573732c207768696368206d6572656c79206d616b6573207468652066756e647320696e61636365737369626c652c21017468697320606275726e60206f7065726174696f6e2077696c6c2072656475636520746f74616c2069737375616e63652062792074686520616d6f756e74205f6275726e65645f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec9020c3c70616c6c65745f62616c616e6365731474797065734c41646a7573746d656e74446972656374696f6e00010820496e63726561736500000020446563726561736500010000cd020c2c70616c6c65745f626162651870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66d1020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e1020140543a3a4b65794f776e657250726f6f6600001009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66d1020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e1020140543a3a4b65794f776e657250726f6f6600012009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e0d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e48706c616e5f636f6e6669675f6368616e6765040118636f6e666967e50201504e657874436f6e66696744657363726970746f720002105d01506c616e20616e2065706f636820636f6e666967206368616e67652e205468652065706f636820636f6e666967206368616e6765206973207265636f7264656420616e642077696c6c20626520656e6163746564206f6e5101746865206e6578742063616c6c20746f2060656e6163745f65706f63685f6368616e6765602e2054686520636f6e6669672077696c6c20626520616374697661746564206f6e652065706f63682061667465722e59014d756c7469706c652063616c6c7320746f2074686973206d6574686f642077696c6c207265706c61636520616e79206578697374696e6720706c616e6e656420636f6e666967206368616e6765207468617420686164546e6f74206265656e20656e6163746564207965742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed102084873705f636f6e73656e7375735f736c6f74734445717569766f636174696f6e50726f6f66081848656164657201d50208496401d902001001206f6666656e646572d90201084964000110736c6f74dd020110536c6f7400013066697273745f686561646572d50201184865616465720001347365636f6e645f686561646572d50201184865616465720000d502102873705f72756e74696d651c67656e65726963186865616465721848656164657208184e756d62657201301048617368000014012c706172656e745f68617368340130486173683a3a4f75747075740001186e756d6265722c01184e756d62657200012873746174655f726f6f74340130486173683a3a4f757470757400013c65787472696e736963735f726f6f74340130486173683a3a4f75747075740001186469676573743c01184469676573740000d9020c4473705f636f6e73656e7375735f626162650c617070185075626c69630000040004013c737232353531393a3a5075626c69630000dd02084873705f636f6e73656e7375735f736c6f747310536c6f740000040030010c7536340000e102082873705f73657373696f6e3c4d656d6265727368697050726f6f6600000c011c73657373696f6e10013053657373696f6e496e646578000128747269655f6e6f646573790201305665633c5665633c75383e3e00013c76616c696461746f725f636f756e7410013856616c696461746f72436f756e740000e5020c4473705f636f6e73656e7375735f626162651c64696765737473504e657874436f6e66696744657363726970746f7200010408563108010463e9020128287536342c2075363429000134616c6c6f7765645f736c6f7473ed020130416c6c6f776564536c6f747300010000e90200000408303000ed02084473705f636f6e73656e7375735f6261626530416c6c6f776564536c6f747300010c305072696d617279536c6f7473000000745072696d617279416e645365636f6e64617279506c61696e536c6f74730001006c5072696d617279416e645365636f6e64617279565246536c6f747300020000f1020c3870616c6c65745f6772616e6470611870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66f50201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f661d030140543a3a4b65794f776e657250726f6f6600001009015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66f50201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f661d030140543a3a4b65794f776e657250726f6f6600012409015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e000d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e306e6f74655f7374616c6c656408011464656c6179300144426c6f636b4e756d626572466f723c543e00016c626573745f66696e616c697a65645f626c6f636b5f6e756d626572300144426c6f636b4e756d626572466f723c543e0002303d014e6f74652074686174207468652063757272656e7420617574686f7269747920736574206f6620746865204752414e4450412066696e616c6974792067616467657420686173207374616c6c65642e006101546869732077696c6c2074726967676572206120666f7263656420617574686f7269747920736574206368616e67652061742074686520626567696e6e696e67206f6620746865206e6578742073657373696f6e2c20746f6101626520656e6163746564206064656c61796020626c6f636b7320616674657220746861742e20546865206064656c6179602073686f756c64206265206869676820656e6f75676820746f20736166656c7920617373756d654901746861742074686520626c6f636b207369676e616c6c696e672074686520666f72636564206368616e67652077696c6c206e6f742062652072652d6f7267656420652e672e203130303020626c6f636b732e5d0154686520626c6f636b2070726f64756374696f6e207261746520287768696368206d617920626520736c6f77656420646f776e2062656361757365206f662066696e616c697479206c616767696e67292073686f756c64510162652074616b656e20696e746f206163636f756e74207768656e2063686f6f73696e6720746865206064656c6179602e20546865204752414e44504120766f74657273206261736564206f6e20746865206e65775501617574686f726974792077696c6c20737461727420766f74696e67206f6e20746f70206f662060626573745f66696e616c697a65645f626c6f636b5f6e756d6265726020666f72206e65772066696e616c697a65644d01626c6f636b732e2060626573745f66696e616c697a65645f626c6f636b5f6e756d626572602073686f756c64206265207468652068696768657374206f6620746865206c61746573742066696e616c697a6564c4626c6f636b206f6620616c6c2076616c696461746f7273206f6620746865206e657720617574686f72697479207365742e00584f6e6c792063616c6c61626c6520627920726f6f742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef502085073705f636f6e73656e7375735f6772616e6470614445717569766f636174696f6e50726f6f660804480134044e0130000801187365745f6964300114536574496400013065717569766f636174696f6ef902014845717569766f636174696f6e3c482c204e3e0000f902085073705f636f6e73656e7375735f6772616e6470613045717569766f636174696f6e0804480134044e013001081c507265766f74650400fd0201890166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265766f74653c0a482c204e3e2c20417574686f726974795369676e61747572652c3e00000024507265636f6d6d69740400110301910166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265636f6d6d69740a3c482c204e3e2c20417574686f726974795369676e61747572652c3e00010000fd02084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456010103045301050300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273740d03011828562c2053290001187365636f6e640d03011828562c20532900000103084066696e616c6974795f6772616e6470611c507265766f74650804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000005030c5073705f636f6e73656e7375735f6772616e6470610c617070245369676e61747572650000040009030148656432353531393a3a5369676e6174757265000009030000034000000008000d030000040801030503001103084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456011503045301050300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273741903011828562c2053290001187365636f6e641903011828562c20532900001503084066696e616c6974795f6772616e64706124507265636f6d6d69740804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000019030000040815030503001d03081c73705f636f726510566f69640001000021030c3870616c6c65745f696e64696365731870616c6c65741043616c6c04045400011414636c61696d040114696e64657810013c543a3a4163636f756e74496e6465780000309841737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e00dc5061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00f02d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e207472616e7366657208010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e6465780001305d0141737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6eb86973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0025012d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e1066726565040114696e64657810013c543a3a4163636f756e74496e646578000230944672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e005d015061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e000d012d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e0084456d6974732060496e646578467265656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e38666f7263655f7472616e736665720c010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e646578000118667265657a65200110626f6f6c0003345501466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c7265616479e868656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00a42d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e41012d2060667265657a65603a2069662073657420746f206074727565602c2077696c6c20667265657a652074686520696e64657820736f2069742063616e6e6f74206265207472616e736665727265642e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e18667265657a65040114696e64657810013c543a3a4163636f756e74496e6465780004304101467265657a6520616e20696e64657820736f2069742077696c6c20616c7761797320706f696e7420746f207468652073656e646572206163636f756e742e205468697320636f6e73756d657320746865206465706f7369742e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d757374206861766520616c6e6f6e2d66726f7a656e206163636f756e742060696e646578602e00ac2d2060696e646578603a2074686520696e64657820746f2062652066726f7a656e20696e20706c6163652e0088456d6974732060496e64657846726f7a656e60206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e25030c4070616c6c65745f64656d6f63726163791870616c6c65741043616c6c04045400014c1c70726f706f736508012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00011476616c75656d01013042616c616e63654f663c543e0000249c50726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e001501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737480686176652066756e647320746f20636f76657220746865206465706f7369742e00d42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e15012d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e0044456d697473206050726f706f736564602e187365636f6e6404012070726f706f73616c6502012450726f70496e646578000118b45369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e64657211016d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e00c82d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e10766f74650801247265665f696e6465786502013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e00021c3101566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3bb86f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00dc2d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e842d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e40656d657267656e63795f63616e63656c0401247265665f696e64657810013c5265666572656e64756d496e6465780003204d015363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d652c7265666572656e64756d2e00f8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e00d02d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e003c5765696768743a20604f283129602e4065787465726e616c5f70726f706f736504012070726f706f73616c29030140426f756e64656443616c6c4f663c543e0004182d015363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c2c7265666572656e64756d2e00e8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e6465787465726e616c5f70726f706f73655f6d616a6f7269747904012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00052c55015363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c655c616e2065787465726e616c207265666572656e64756d2e00ec546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f283129606065787465726e616c5f70726f706f73655f64656661756c7404012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00062c45015363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f807363686564756c6520616e2065787465726e616c207265666572656e64756d2e00e8546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f2831296028666173745f747261636b0c013470726f706f73616c5f6861736834011c543a3a48617368000134766f74696e675f706572696f64300144426c6f636b4e756d626572466f723c543e00011464656c6179300144426c6f636b4e756d626572466f723c543e0007404d015363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c65646101696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e65e8627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e00d0546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e00f42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e5d012d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f88094d75737420626520616c776179732067726561746572207468616e207a65726f2e350109466f72206046617374547261636b4f726967696e60206d75737420626520657175616c206f722067726561746572207468616e206046617374547261636b566f74696e67506572696f64602e51012d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265b82020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e0040456d697473206053746172746564602e00385765696768743a20604f28312960347665746f5f65787465726e616c04013470726f706f73616c5f6861736834011c543a3a48617368000824b85665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e00d8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e002d012d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e003c456d69747320605665746f6564602e00fc5765696768743a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f657273604463616e63656c5f7265666572656e64756d0401247265665f696e6465786502013c5265666572656e64756d496e64657800091c5052656d6f76652061207265666572656e64756d2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e00d42d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e004423205765696768743a20604f283129602e2064656c65676174650c0108746fc10201504163636f756e7449644c6f6f6b75704f663c543e000128636f6e76696374696f6e35030128436f6e76696374696f6e00011c62616c616e636518013042616c616e63654f663c543e000a50390144656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e0055015468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f7220746865c874696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a7420202d2062652064656c65676174696e6720616c72656164793b206f72590120202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656494202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e0045012d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e55012d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e20746865410120206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e61012d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d757374206e6f74b420206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e0048456d697473206044656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e28756e64656c6567617465000b30cc556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e005d01546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64dc6f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062655463757272656e746c792064656c65676174696e672e0050456d6974732060556e64656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e58636c6561725f7075626c69635f70726f706f73616c73000c1470436c6561727320616c6c207075626c69632070726f706f73616c732e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e003c5765696768743a20604f283129602e18756e6c6f636b040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000d1ca0556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00b82d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e00bc5765696768743a20604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e2c72656d6f76655f766f7465040114696e64657810013c5265666572656e64756d496e646578000e6c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e000c49663a882d20746865207265666572656e64756d207761732063616e63656c6c65642c206f727c2d20746865207265666572656e64756d206973206f6e676f696e672c206f72902d20746865207265666572656e64756d2068617320656e64656420737563682074686174fc20202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f72d420202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f728420202d20746865206163636f756e74206d61646520612073706c697420766f74655d012e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72655866756e6473206265696e6720617661696c61626c652e00a849662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643aec2d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64dc2d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64bc2d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f76657259012e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c766559012a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756de46f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e004901546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465887265676973746572656420666f72207265666572656e64756d2060696e646578602e00f42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e4472656d6f76655f6f746865725f766f7465080118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c5265666572656e64756d496e646578000f3c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e004d0149662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f2d016072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c5501656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7298626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e004d012d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f725420207265666572656e64756d2060696e646578602ef42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e24626c61636b6c69737408013470726f706f73616c5f6861736834011c543a3a4861736800013c6d617962655f7265665f696e6465783903015c4f7074696f6e3c5265666572656e64756d496e6465783e00103c45015065726d616e656e746c7920706c61636520612070726f706f73616c20696e746f2074686520626c61636b6c6973742e20546869732070726576656e74732069742066726f6d2065766572206265696e673c70726f706f73656420616761696e2e00510149662063616c6c6564206f6e206120717565756564207075626c6963206f722065787465726e616c2070726f706f73616c2c207468656e20746869732077696c6c20726573756c7420696e206974206265696e67510172656d6f7665642e2049662074686520607265665f696e6465786020737570706c69656420697320616e20616374697665207265666572656e64756d2077697468207468652070726f706f73616c20686173682c687468656e2069742077696c6c2062652063616e63656c6c65642e00ec546865206469737061746368206f726967696e206f6620746869732063616c6c206d7573742062652060426c61636b6c6973744f726967696e602e00f82d206070726f706f73616c5f68617368603a205468652070726f706f73616c206861736820746f20626c61636b6c697374207065726d616e656e746c792e45012d20607265665f696e646578603a20416e206f6e676f696e67207265666572656e64756d2077686f73652068617368206973206070726f706f73616c5f68617368602c2077686963682077696c6c2062652863616e63656c6c65642e0041015765696768743a20604f28702960202874686f756768206173207468697320697320616e20686967682d70726976696c6567652064697370617463682c20776520617373756d65206974206861732061502020726561736f6e61626c652076616c7565292e3c63616e63656c5f70726f706f73616c04012870726f705f696e6465786502012450726f70496e64657800111c4852656d6f766520612070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c50726f706f73616c4f726967696e602e00d02d206070726f705f696e646578603a2054686520696e646578206f66207468652070726f706f73616c20746f2063616e63656c2e00e45765696768743a20604f28702960207768657265206070203d205075626c696350726f70733a3a3c543e3a3a6465636f64655f6c656e282960307365745f6d657461646174610801146f776e6572c001344d657461646174614f776e65720001286d617962655f686173683d03013c4f7074696f6e3c543a3a486173683e00123cd8536574206f7220636c6561722061206d65746164617461206f6620612070726f706f73616c206f722061207265666572656e64756d2e002c506172616d65746572733acc2d20606f726967696e603a204d75737420636f72726573706f6e6420746f2074686520604d657461646174614f776e6572602e3d01202020202d206045787465726e616c4f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479417070726f766560402020202020207468726573686f6c642e5901202020202d206045787465726e616c44656661756c744f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479416761696e737460402020202020207468726573686f6c642e4501202020202d206045787465726e616c4d616a6f726974794f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053696d706c654d616a6f7269747960402020202020207468726573686f6c642ec8202020202d20605369676e65646020627920612063726561746f7220666f722061207075626c69632070726f706f73616c2ef4202020202d20605369676e65646020746f20636c6561722061206d6574616461746120666f7220612066696e6973686564207265666572656e64756d2ee4202020202d2060526f6f746020746f207365742061206d6574616461746120666f7220616e206f6e676f696e67207265666572656e64756d2eb42d20606f776e6572603a20616e206964656e746966696572206f662061206d65746164617461206f776e65722e51012d20606d617962655f68617368603a205468652068617368206f6620616e206f6e2d636861696e2073746f72656420707265696d6167652e20604e6f6e656020746f20636c6561722061206d657461646174612e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e290310346672616d655f737570706f72741874726169747324707265696d616765731c426f756e64656408045401b9020448012d03010c184c656761637904011068617368340124483a3a4f757470757400000018496e6c696e65040031030134426f756e646564496e6c696e65000100184c6f6f6b757008011068617368340124483a3a4f757470757400010c6c656e10010c753332000200002d030c2873705f72756e74696d65187472616974732c426c616b6554776f3235360000000031030c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000035030c4070616c6c65745f64656d6f637261637928636f6e76696374696f6e28436f6e76696374696f6e00011c104e6f6e65000000204c6f636b65643178000100204c6f636b65643278000200204c6f636b65643378000300204c6f636b65643478000400204c6f636b65643578000500204c6f636b6564367800060000390304184f7074696f6e04045401100108104e6f6e6500000010536f6d6504001000000100003d0304184f7074696f6e04045401340108104e6f6e6500000010536f6d65040034000001000041030c4470616c6c65745f636f6c6c6563746976651870616c6c65741043616c6c0804540004490001182c7365745f6d656d626572730c012c6e65775f6d656d626572733d0201445665633c543a3a4163636f756e7449643e0001147072696d658801504f7074696f6e3c543a3a4163636f756e7449643e0001246f6c645f636f756e7410012c4d656d626572436f756e74000060805365742074686520636f6c6c6563746976652773206d656d626572736869702e0045012d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642ee02d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e59012d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e205573656420666f7250202077656967687420657374696d6174696f6e2e00d4546865206469737061746368206f6620746869732063616c6c206d75737420626520605365744d656d626572734f726967696e602e0051014e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d61784d656d6265727360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c2062757421012020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e002823205741524e494e473a005901546865206070616c6c65742d636f6c6c656374697665602063616e20616c736f206265206d616e61676564206279206c6f676963206f757473696465206f66207468652070616c6c6574207468726f75676820746865b8696d706c656d656e746174696f6e206f6620746865207472616974205b604368616e67654d656d62657273605d2e5501416e792063616c6c20746f20607365745f6d656d6265727360206d757374206265206361726566756c207468617420746865206d656d6265722073657420646f65736e277420676574206f7574206f662073796e63a477697468206f74686572206c6f676963206d616e6167696e6720746865206d656d626572207365742e0038232320436f6d706c65786974793a502d20604f284d50202b204e29602077686572653ae020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429e020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564299820202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564291c6578656375746508012070726f706f73616cb902017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646502010c753332000124f0446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e00a84f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e0038232320436f6d706c65786974793a5c2d20604f2842202b204d202b205029602077686572653ad82d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429882d20604d60206d656d626572732d636f756e742028636f64652d626f756e64656429a82d2060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c601c70726f706f73650c01247468726573686f6c646502012c4d656d626572436f756e7400012070726f706f73616cb902017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646502010c753332000238f84164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e00845265717569726573207468652073656e64657220746f206265206d656d6265722e004101607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029546f722070757420757020666f7220766f74696e672e0034232320436f6d706c6578697479ac2d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c420202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653af4202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c20326029fc202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d2032602910766f74650c012070726f706f73616c34011c543a3a48617368000114696e6465786502013450726f706f73616c496e64657800011c617070726f7665200110626f6f6c000324f041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e008c5265717569726573207468652073656e64657220746f2062652061206d656d6265722e0049015472616e73616374696f6e20666565732077696c6c2062652077616976656420696620746865206d656d62657220697320766f74696e67206f6e20616e7920706172746963756c61722070726f706f73616c5101666f72207468652066697273742074696d6520616e64207468652063616c6c206973207375636365737366756c2e2053756273657175656e7420766f7465206368616e6765732077696c6c206368617267652061106665652e34232320436f6d706c657869747909012d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564294c646973617070726f76655f70726f706f73616c04013470726f706f73616c5f6861736834011c543a3a486173680005285901446973617070726f766520612070726f706f73616c2c20636c6f73652c20616e642072656d6f76652069742066726f6d207468652073797374656d2c207265676172646c657373206f66206974732063757272656e741873746174652e00884d7573742062652063616c6c65642062792074686520526f6f74206f726967696e2e002c506172616d65746572733a1d012a206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20746861742073686f756c6420626520646973617070726f7665642e0034232320436f6d706c6578697479ac4f285029207768657265205020697320746865206e756d626572206f66206d61782070726f706f73616c7314636c6f736510013470726f706f73616c5f6861736834011c543a3a48617368000114696e6465786502013450726f706f73616c496e64657800015470726f706f73616c5f7765696768745f626f756e642801185765696768740001306c656e6774685f626f756e646502010c7533320006604d01436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e0055014d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e00490149662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f7465206966206974206973bc68617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e00490149662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e732501756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e00610149662074686520636c6f7365206f7065726174696f6e20636f6d706c65746573207375636365737366756c6c79207769746820646973617070726f76616c2c20746865207472616e73616374696f6e206665652077696c6c5d016265207761697665642e204f746865727769736520657865637574696f6e206f662074686520617070726f766564206f7065726174696f6e2077696c6c206265206368617267656420746f207468652063616c6c65722e0061012b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642470726f706f73616c2e61012b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b65642076696135016073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e0034232320436f6d706c6578697479742d20604f2842202b204d202b205031202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c820202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652ea420202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e45030c3870616c6c65745f76657374696e671870616c6c65741043616c6c0404540001181076657374000024b8556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e005d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e28766573745f6f74686572040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e00012cb8556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051012d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e3c7665737465645f7472616e73666572080118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65490301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00023464437265617465206120766573746564207472616e736665722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00cc2d2060746172676574603a20546865206163636f756e7420726563656976696e6720746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e54666f7263655f7665737465645f7472616e736665720c0118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65490301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00033860466f726365206120766573746564207472616e736665722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00e82d2060736f75726365603a20546865206163636f756e742077686f73652066756e64732073686f756c64206265207472616e736665727265642e11012d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e3c6d657267655f7363686564756c657308013c7363686564756c65315f696e64657810010c75333200013c7363686564756c65325f696e64657810010c7533320004545d014d657267652074776f2076657374696e67207363686564756c657320746f6765746865722c206372656174696e672061206e65772076657374696e67207363686564756c65207468617420756e6c6f636b73206f7665725501746865206869676865737420706f737369626c6520737461727420616e6420656e6420626c6f636b732e20496620626f7468207363686564756c6573206861766520616c7265616479207374617274656420746865590163757272656e7420626c6f636b2077696c6c206265207573656420617320746865207363686564756c652073746172743b207769746820746865206361766561742074686174206966206f6e65207363686564756c655d0169732066696e6973686564206279207468652063757272656e7420626c6f636b2c20746865206f746865722077696c6c206265207472656174656420617320746865206e6577206d6572676564207363686564756c652c2c756e6d6f6469666965642e00f84e4f54453a20496620607363686564756c65315f696e646578203d3d207363686564756c65325f696e6465786020746869732069732061206e6f2d6f702e41014e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b207072696f7220746f206d657267696e672e61014e4f54453a20496620626f7468207363686564756c6573206861766520656e646564206279207468652063757272656e7420626c6f636b2c206e6f206e6577207363686564756c652077696c6c206265206372656174656464616e6420626f74682077696c6c2062652072656d6f7665642e006c4d6572676564207363686564756c6520617474726962757465733a35012d20607374617274696e675f626c6f636b603a20604d4158287363686564756c65312e7374617274696e675f626c6f636b2c207363686564756c6564322e7374617274696e675f626c6f636b2c48202063757272656e745f626c6f636b29602e21012d2060656e64696e675f626c6f636b603a20604d4158287363686564756c65312e656e64696e675f626c6f636b2c207363686564756c65322e656e64696e675f626c6f636b29602e59012d20606c6f636b6564603a20607363686564756c65312e6c6f636b65645f61742863757272656e745f626c6f636b29202b207363686564756c65322e6c6f636b65645f61742863757272656e745f626c6f636b29602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00e82d20607363686564756c65315f696e646578603a20696e646578206f6620746865206669727374207363686564756c6520746f206d657267652eec2d20607363686564756c65325f696e646578603a20696e646578206f6620746865207365636f6e64207363686564756c6520746f206d657267652e74666f7263655f72656d6f76655f76657374696e675f7363686564756c65080118746172676574c102018c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263650001387363686564756c655f696e64657810010c7533320005187c466f7263652072656d6f766520612076657374696e67207363686564756c6500c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00c82d2060746172676574603a20416e206163636f756e7420746861742068617320612076657374696e67207363686564756c6515012d20607363686564756c655f696e646578603a205468652076657374696e67207363686564756c6520696e64657820746861742073686f756c642062652072656d6f766564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e49030c3870616c6c65745f76657374696e673076657374696e675f696e666f2c56657374696e67496e666f081c42616c616e636501182c426c6f636b4e756d6265720130000c01186c6f636b656418011c42616c616e63650001247065725f626c6f636b18011c42616c616e63650001387374617274696e675f626c6f636b30012c426c6f636b4e756d62657200004d030c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c65741043616c6c04045400011810766f7465080114766f7465733d0201445665633c543a3a4163636f756e7449643e00011476616c75656d01013042616c616e63654f663c543e00004c5901566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746fe07365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e005d0155706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e642061206465706f73697420616d6f756e742069734d0172657365727665642e20546865206465706f736974206973206261736564206f6e20746865206e756d626572206f6620766f74657320616e642063616e2062652075706461746564206f7665722074696d652e004c5468652060766f746573602073686f756c643a4420202d206e6f7420626520656d7074792e550120202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e6411012020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e0049014966206076616c756560206973206d6f7265207468616e206077686f60277320667265652062616c616e63652c207468656e20746865206d6178696d756d206f66207468652074776f20697320757365642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e6700550149742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f202a2a4e4f542a2a20706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865a86c6f636b20616e64206b65657020736f6d6520666f722066757274686572206f7065726174696f6e732e3072656d6f76655f766f7465720001146c52656d6f766520606f726967696e60206173206120766f7465722e00b8546869732072656d6f76657320746865206c6f636b20616e642072657475726e7320746865206465706f7369742e00fc546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420616e64206265206120766f7465722e407375626d69745f63616e64696461637904013c63616e6469646174655f636f756e746502010c75333200023c11015375626d6974206f6e6573656c6620666f722063616e6469646163792e204120666978656420616d6f756e74206f66206465706f736974206973207265636f726465642e005d01416c6c2063616e64696461746573206172652077697065642061742074686520656e64206f6620746865207465726d2e205468657920656974686572206265636f6d652061206d656d6265722f72756e6e65722d75702ccc6f72206c65617665207468652073797374656d207768696c65207468656972206465706f73697420697320736c61736865642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e67005d014576656e20696620612063616e64696461746520656e6473207570206265696e672061206d656d6265722c2074686579206d7573742063616c6c205b6043616c6c3a3a72656e6f756e63655f63616e646964616379605d5901746f20676574207468656972206465706f736974206261636b2e204c6f73696e67207468652073706f7420696e20616e20656c656374696f6e2077696c6c20616c77617973206c65616420746f206120736c6173682e000901546865206e756d626572206f662063757272656e742063616e64696461746573206d7573742062652070726f7669646564206173207769746e65737320646174612e34232320436f6d706c6578697479a44f2843202b206c6f672843292920776865726520432069732063616e6469646174655f636f756e742e4872656e6f756e63655f63616e64696461637904012872656e6f756e63696e675103012852656e6f756e63696e670003504d0152656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c3c6f7574636f6d65732065786973743a0049012d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c20746865206465706f736974206973f02020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e61012d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c20746865206465706f73697420697320756e72657365727665642c2072657475726e656420616e648c20206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e55012d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c20746865206465706f73697420697320756e726573657276656420616e64206f726967696e2069735501202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e6101202053696d696c617220746f205b6072656d6f76655f6d656d626572605d2853656c663a3a72656d6f76655f6d656d626572292c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865795901202061726520696d6d6564696174656c7920757365642e20496620746865207072696d652069732072656e6f756e63696e672c207468656e206e6f207072696d652077696c6c20657869737420756e74696c207468653420206e65787420726f756e642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642c20616e642068617665206f6e65206f66207468652061626f766520726f6c65732ee05468652074797065206f662072656e6f756e63696e67206d7573742062652070726f7669646564206173207769746e65737320646174612e0034232320436f6d706c6578697479dc20202d2052656e6f756e63696e673a3a43616e64696461746528636f756e74293a204f28636f756e74202b206c6f6728636f756e7429297020202d2052656e6f756e63696e673a3a4d656d6265723a204f2831297820202d2052656e6f756e63696e673a3a52756e6e657255703a204f2831293472656d6f76655f6d656d6265720c010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000128736c6173685f626f6e64200110626f6f6c000138726572756e5f656c656374696f6e200110626f6f6c000440590152656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f667c746865206f7574676f696e67206d656d62657220697320736c61736865642e005501496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c616365732074686555016f7574676f696e67206d656d6265722e204f74686572776973652c2069662060726572756e5f656c656374696f6e60206973206074727565602c2061206e65772070687261676d656e20656c656374696f6e2069737c737461727465642c20656c73652c206e6f7468696e672068617070656e732e00590149662060736c6173685f626f6e64602069732073657420746f20747275652c2074686520626f6e64206f6620746865206d656d626572206265696e672072656d6f76656420697320736c61736865642e20456c73652c3c69742069732072657475726e65642e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0041014e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e0034232320436f6d706c657869747905012d20436865636b2064657461696c73206f662072656d6f76655f616e645f7265706c6163655f6d656d626572282920616e6420646f5f70687261676d656e28292e50636c65616e5f646566756e63745f766f746572730801286e756d5f766f7465727310010c75333200012c6e756d5f646566756e637410010c7533320005244501436c65616e20616c6c20766f746572732077686f2061726520646566756e63742028692e652e207468657920646f206e6f7420736572766520616e7920707572706f736520617420616c6c292e20546865ac6465706f736974206f66207468652072656d6f76656420766f74657273206172652072657475726e65642e0001015468697320697320616e20726f6f742066756e6374696f6e20746f2062652075736564206f6e6c7920666f7220636c65616e696e67207468652073746174652e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0034232320436f6d706c65786974798c2d20436865636b2069735f646566756e63745f766f74657228292064657461696c732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5103086470616c6c65745f656c656374696f6e735f70687261676d656e2852656e6f756e63696e6700010c184d656d6265720000002052756e6e657255700001002443616e64696461746504006502010c7533320002000055030c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c65741043616c6c0404540001143c7375626d69745f756e7369676e65640801307261775f736f6c7574696f6e590301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e00011c7769746e65737329040158536f6c7574696f6e4f72536e617073686f7453697a65000038a45375626d6974206120736f6c7574696f6e20666f722074686520756e7369676e65642070686173652e00c8546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f6e6f6e655f5f2e003d0154686973207375626d697373696f6e20697320636865636b6564206f6e2074686520666c792e204d6f72656f7665722c207468697320756e7369676e656420736f6c7574696f6e206973206f6e6c79550176616c696461746564207768656e207375626d697474656420746f2074686520706f6f6c2066726f6d20746865202a2a6c6f63616c2a2a206e6f64652e204566666563746976656c792c2074686973206d65616e735d0174686174206f6e6c79206163746976652076616c696461746f72732063616e207375626d69742074686973207472616e73616374696f6e207768656e20617574686f72696e67206120626c6f636b202873696d696c617240746f20616e20696e686572656e74292e005901546f2070726576656e7420616e7920696e636f727265637420736f6c7574696f6e2028616e642074687573207761737465642074696d652f776569676874292c2074686973207472616e73616374696f6e2077696c6c4d0170616e69632069662074686520736f6c7574696f6e207375626d6974746564206279207468652076616c696461746f7220697320696e76616c696420696e20616e79207761792c206566666563746976656c799c70757474696e6720746865697220617574686f72696e6720726577617264206174207269736b2e00e04e6f206465706f736974206f7220726577617264206973206173736f63696174656420776974682074686973207375626d697373696f6e2e6c7365745f6d696e696d756d5f756e747275737465645f73636f72650401406d617962655f6e6578745f73636f72652d0401544f7074696f6e3c456c656374696f6e53636f72653e000114b05365742061206e65772076616c756520666f7220604d696e696d756d556e7472757374656453636f7265602e00d84469737061746368206f726967696e206d75737420626520616c69676e656420776974682060543a3a466f7263654f726967696e602e00f05468697320636865636b2063616e206265207475726e6564206f66662062792073657474696e67207468652076616c756520746f20604e6f6e65602e747365745f656d657267656e63795f656c656374696f6e5f726573756c74040120737570706f72747331040158537570706f7274733c543a3a4163636f756e7449643e0002205901536574206120736f6c7574696f6e20696e207468652071756575652c20746f2062652068616e646564206f757420746f2074686520636c69656e74206f6620746869732070616c6c657420696e20746865206e6578748863616c6c20746f2060456c656374696f6e50726f76696465723a3a656c656374602e004501546869732063616e206f6e6c79206265207365742062792060543a3a466f7263654f726967696e602c20616e64206f6e6c79207768656e207468652070686173652069732060456d657267656e6379602e00610154686520736f6c7574696f6e206973206e6f7420636865636b656420666f7220616e7920666561736962696c69747920616e6420697320617373756d656420746f206265207472757374776f727468792c20617320616e795101666561736962696c69747920636865636b20697473656c662063616e20696e207072696e6369706c652063617573652074686520656c656374696f6e2070726f6365737320746f206661696c202864756520746f686d656d6f72792f77656967687420636f6e73747261696e73292e187375626d69740401307261775f736f6c7574696f6e590301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e0003249c5375626d6974206120736f6c7574696f6e20666f7220746865207369676e65642070686173652e00d0546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f7369676e65645f5f2e005d0154686520736f6c7574696f6e20697320706f74656e7469616c6c79207175657565642c206261736564206f6e2074686520636c61696d65642073636f726520616e642070726f6365737365642061742074686520656e64506f6620746865207369676e65642070686173652e005d0141206465706f73697420697320726573657276656420616e64207265636f7264656420666f722074686520736f6c7574696f6e2e204261736564206f6e20746865206f7574636f6d652c2074686520736f6c7574696f6e15016d696768742062652072657761726465642c20736c61736865642c206f722067657420616c6c206f7220612070617274206f6620746865206465706f736974206261636b2e4c676f7665726e616e63655f66616c6c6261636b0801406d617962655f6d61785f766f746572733903012c4f7074696f6e3c7533323e0001446d617962655f6d61785f746172676574733903012c4f7074696f6e3c7533323e00041080547269676765722074686520676f7665726e616e63652066616c6c6261636b2e004901546869732063616e206f6e6c792062652063616c6c6564207768656e205b6050686173653a3a456d657267656e6379605d20697320656e61626c65642c20617320616e20616c7465726e617469766520746fc063616c6c696e67205b6043616c6c3a3a7365745f656d657267656e63795f656c656374696f6e5f726573756c74605d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5903089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173652c526177536f6c7574696f6e040453015d03000c0120736f6c7574696f6e5d0301045300011473636f7265e00134456c656374696f6e53636f7265000114726f756e6410010c75333200005d03085874616e676c655f746573746e65745f72756e74696d65384e706f73536f6c7574696f6e31360000400118766f74657331610300000118766f746573326d0300000118766f74657333810300000118766f746573348d0300000118766f74657335990300000118766f74657336a50300000118766f74657337b10300000118766f74657338bd0300000118766f74657339c9030000011c766f7465733130d5030000011c766f7465733131e1030000011c766f7465733132ed030000011c766f7465733133f9030000011c766f746573313405040000011c766f746573313511040000011c766f74657331361d04000000610300000265030065030000040865026903006903000006e901006d0300000271030071030000040c65027503690300750300000408690379030079030000067d03007d030c3473705f61726974686d65746963287065725f7468696e67731850657255313600000400e901010c7531360000810300000285030085030000040c650289036903008903000003020000007503008d0300000291030091030000040c6502950369030095030000030300000075030099030000029d03009d030000040c6502a103690300a10300000304000000750300a503000002a90300a9030000040c6502ad03690300ad0300000305000000750300b103000002b50300b5030000040c6502b903690300b90300000306000000750300bd03000002c10300c1030000040c6502c503690300c50300000307000000750300c903000002cd0300cd030000040c6502d103690300d10300000308000000750300d503000002d90300d9030000040c6502dd03690300dd0300000309000000750300e103000002e50300e5030000040c6502e903690300e9030000030a000000750300ed03000002f10300f1030000040c6502f503690300f5030000030b000000750300f903000002fd0300fd030000040c6502010469030001040000030c000000750300050400000209040009040000040c65020d046903000d040000030d000000750300110400000215040015040000040c6502190469030019040000030e0000007503001d0400000221040021040000040c6502250469030025040000030f0000007503002904089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736558536f6c7574696f6e4f72536e617073686f7453697a650000080118766f746572736502010c75333200011c746172676574736502010c75333200002d0404184f7074696f6e04045401e00108104e6f6e6500000010536f6d650400e000000100003104000002350400350400000408003904003904084473705f6e706f735f656c656374696f6e731c537570706f727404244163636f756e744964010000080114746f74616c18013c457874656e64656442616c616e6365000118766f74657273d001845665633c284163636f756e7449642c20457874656e64656442616c616e6365293e00003d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c65741043616c6c04045400017810626f6e6408011476616c75656d01013042616c616e63654f663c543e0001147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000040610154616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c80626520746865206163636f756e74207468617420636f6e74726f6c732069742e002d016076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e002101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e003c456d6974732060426f6e646564602e34232320436f6d706c6578697479d02d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e1c2d204f2831292e642d20546872656520657874726120444220656e74726965732e004d014e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e65645901756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20286f7220657175616c20746f20302920616e6420676574732072656d6f76656420617320647573742e28626f6e645f65787472610401386d61785f6164646974696f6e616c6d01013042616c616e63654f663c543e000138610141646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757030666f72207374616b696e672e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e004d01557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e5501556e6c696b65205b60626f6e64605d2853656c663a3a626f6e6429206f72205b60756e626f6e64605d2853656c663a3a756e626f6e642920746869732066756e6374696f6e20646f6573206e6f7420696d706f7365bc616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e003c456d6974732060426f6e646564602e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e1c2d204f2831292e18756e626f6e6404011476616c75656d01013042616c616e63654f663c543e00024c51015363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e64fc706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e2101543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0045014f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665bc7468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e0031014e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d6178556e6c6f636b696e674368756e6b736029410163616e20636f2d657869737473206174207468652073616d652074696d652e20496620746865726520617265206e6f20756e6c6f636b696e67206368756e6b7320736c6f747320617661696c61626c6545015b6043616c6c3a3a77697468647261775f756e626f6e646564605d2069732063616c6c656420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e00390149662061207573657220656e636f756e74657273207468652060496e73756666696369656e74426f6e6460206572726f72207768656e2063616c6c696e6720746869732065787472696e7369632c1901746865792073686f756c642063616c6c20606368696c6c6020666972737420696e206f7264657220746f206672656520757020746865697220626f6e6465642066756e64732e0044456d6974732060556e626f6e646564602e009453656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e4477697468647261775f756e626f6e6465640401486e756d5f736c617368696e675f7370616e7310010c75333200035c290152656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e0055015468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722469742077616e74732e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722e0048456d697473206057697468647261776e602e006853656520616c736f205b6043616c6c3a3a756e626f6e64605d2e0034232320506172616d65746572730051012d20606e756d5f736c617368696e675f7370616e736020696e6469636174657320746865206e756d626572206f66206d6574616461746120736c617368696e67207370616e7320746f20636c656172207768656e5501746869732063616c6c20726573756c747320696e206120636f6d706c6574652072656d6f76616c206f6620616c6c2074686520646174612072656c6174656420746f20746865207374617368206163636f756e742e3d01496e207468697320636173652c2074686520606e756d5f736c617368696e675f7370616e7360206d757374206265206c6172676572206f7220657175616c20746f20746865206e756d626572206f665d01736c617368696e67207370616e73206173736f636961746564207769746820746865207374617368206163636f756e7420696e20746865205b60536c617368696e675370616e73605d2073746f7261676520747970652c25016f7468657277697365207468652063616c6c2077696c6c206661696c2e205468652063616c6c20776569676874206973206469726563746c792070726f706f7274696f6e616c20746f54606e756d5f736c617368696e675f7370616e73602e0034232320436f6d706c6578697479d84f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f766509014e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e2076616c69646174650401147072656673f8013856616c696461746f725072656673000414e44465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e206e6f6d696e61746504011c74617267657473410401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e0005280d014465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c65786974792d012d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e29050177686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542028543a3a4d61784e6f6d696e6174696f6e73292ed42d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e146368696c6c000628c44465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e502d20436f6e7461696e73206f6e6520726561642ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e247365745f70617965650401147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000730b42852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479182d204f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e242d2d2d2d2d2d2d2d2d387365745f636f6e74726f6c6c657200083845012852652d29736574732074686520636f6e74726f6c6c6572206f66206120737461736820746f2074686520737461736820697473656c662e20546869732066756e6374696f6e2070726576696f75736c794d01616363657074656420612060636f6e74726f6c6c65726020617267756d656e7420746f207365742074686520636f6e74726f6c6c657220746f20616e206163636f756e74206f74686572207468616e207468655901737461736820697473656c662e20546869732066756e6374696f6e616c69747920686173206e6f77206265656e2072656d6f7665642c206e6f77206f6e6c792073657474696e672074686520636f6e74726f6c6c65728c746f207468652073746173682c206966206974206973206e6f7420616c72656164792e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479104f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e4c7365745f76616c696461746f725f636f756e7404010c6e65776502010c75333200091890536574732074686520696465616c206e756d626572206f662076616c696461746f72732e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c6578697479104f28312960696e6372656173655f76616c696461746f725f636f756e740401286164646974696f6e616c6502010c753332000a1ce8496e6372656d656e74732074686520696465616c206e756d626572206f662076616c696461746f727320757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e547363616c655f76616c696461746f725f636f756e74040118666163746f72f501011c50657263656e74000b1c11015363616c652075702074686520696465616c206e756d626572206f662076616c696461746f7273206279206120666163746f7220757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e34666f7263655f6e6f5f65726173000c34ac466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e3901546875732074686520656c656374696f6e2070726f63657373206d6179206265206f6e676f696e67207768656e20746869732069732063616c6c65642e20496e2074686973206361736520746865dc656c656374696f6e2077696c6c20636f6e74696e756520756e74696c20746865206e65787420657261206973207472696767657265642e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f28312934666f7263655f6e65775f657261000d384901466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c2062659c726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f283129447365745f696e76756c6e657261626c6573040134696e76756c6e657261626c65733d0201445665633c543a3a4163636f756e7449643e000e0cc8536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e34666f7263655f756e7374616b650801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c753332000f200901466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e50666f7263655f6e65775f6572615f616c776179730010240101466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e5463616e63656c5f64656665727265645f736c61736808010c657261100120457261496e646578000134736c6173685f696e6469636573450401205665633c7533323e0011149443616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e009843616e2062652063616c6c6564206279207468652060543a3a41646d696e4f726967696e602e000101506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e387061796f75745f7374616b65727308013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780012341901506179206f7574206e6578742070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e206572612e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e00490154686520726577617264207061796f757420636f756c6420626520706167656420696e20636173652074686572652061726520746f6f206d616e79206e6f6d696e61746f7273206261636b696e67207468655d016076616c696461746f725f7374617368602e20546869732063616c6c2077696c6c207061796f757420756e7061696420706167657320696e20616e20617363656e64696e67206f726465722e20546f20636c61696d2061b4737065636966696320706167652c2075736520607061796f75745f7374616b6572735f62795f70616765602e6000f0496620616c6c2070616765732061726520636c61696d65642c2069742072657475726e7320616e206572726f722060496e76616c696450616765602e187265626f6e6404011476616c75656d01013042616c616e63654f663c543e00131cdc5265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e00d4546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479d02d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73882d20426f756e64656420627920604d6178556e6c6f636b696e674368756e6b73602e28726561705f73746173680801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c7533320014485d0152656d6f766520616c6c2064617461207374727563747572657320636f6e6365726e696e672061207374616b65722f7374617368206f6e636520697420697320617420612073746174652077686572652069742063616e0501626520636f6e736964657265642060647573746020696e20746865207374616b696e672073797374656d2e2054686520726571756972656d656e7473206172653a000501312e207468652060746f74616c5f62616c616e636560206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e1101322e206f722c2074686520606c65646765722e746f74616c60206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e6101332e206f722c206578697374656e7469616c206465706f736974206973207a65726f20616e64206569746865722060746f74616c5f62616c616e636560206f7220606c65646765722e746f74616c60206973207a65726f2e00550154686520666f726d65722063616e2068617070656e20696e206361736573206c696b65206120736c6173683b20746865206c6174746572207768656e20612066756c6c7920756e626f6e646564206163636f756e7409016973207374696c6c20726563656976696e67207374616b696e67207265776172647320696e206052657761726444657374696e6174696f6e3a3a5374616b6564602e00310149742063616e2062652063616c6c656420627920616e796f6e652c206173206c6f6e672061732060737461736860206d65657473207468652061626f766520726571756972656d656e74732e00dc526566756e647320746865207472616e73616374696f6e20666565732075706f6e207375636365737366756c20657865637574696f6e2e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e106b69636b04010c77686f410401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e00152ce052656d6f76652074686520676976656e206e6f6d696e6174696f6e732066726f6d207468652063616c6c696e672076616c696461746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e004d012d206077686f603a2041206c697374206f66206e6f6d696e61746f72207374617368206163636f756e74732077686f20617265206e6f6d696e6174696e6720746869732076616c696461746f72207768696368c0202073686f756c64206e6f206c6f6e676572206265206e6f6d696e6174696e6720746869732076616c696461746f722e0055014e6f74653a204d616b696e6720746869732063616c6c206f6e6c79206d616b65732073656e736520696620796f7520666972737420736574207468652076616c696461746f7220707265666572656e63657320746f78626c6f636b20616e792066757274686572206e6f6d696e6174696f6e732e4c7365745f7374616b696e675f636f6e666967731c01486d696e5f6e6f6d696e61746f725f626f6e6449040158436f6e6669674f703c42616c616e63654f663c543e3e0001486d696e5f76616c696461746f725f626f6e6449040158436f6e6669674f703c42616c616e63654f663c543e3e00014c6d61785f6e6f6d696e61746f725f636f756e744d040134436f6e6669674f703c7533323e00014c6d61785f76616c696461746f725f636f756e744d040134436f6e6669674f703c7533323e00013c6368696c6c5f7468726573686f6c6451040144436f6e6669674f703c50657263656e743e0001386d696e5f636f6d6d697373696f6e55040144436f6e6669674f703c50657262696c6c3e0001486d61785f7374616b65645f7265776172647351040144436f6e6669674f703c50657263656e743e001644ac5570646174652074686520766172696f7573207374616b696e6720636f6e66696775726174696f6e73202e0025012a20606d696e5f6e6f6d696e61746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f2062652061206e6f6d696e61746f722e25012a20606d696e5f76616c696461746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f20626520612076616c696461746f722e55012a20606d61785f6e6f6d696e61746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e2062652061206e6f6d696e61746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e55012a20606d61785f76616c696461746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e20626520612076616c696461746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e59012a20606368696c6c5f7468726573686f6c64603a2054686520726174696f206f6620606d61785f6e6f6d696e61746f725f636f756e7460206f7220606d61785f76616c696461746f725f636f756e74602077686963681901202073686f756c642062652066696c6c656420696e206f7264657220666f722074686520606368696c6c5f6f7468657260207472616e73616374696f6e20746f20776f726b2e61012a20606d696e5f636f6d6d697373696f6e603a20546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e550120205468697320697320636865636b6564206f6e6c792075706f6e2063616c6c696e67206076616c6964617465602e204578697374696e672076616c696461746f727320617265206e6f742061666665637465642e00c452756e74696d654f726967696e206d75737420626520526f6f7420746f2063616c6c20746869732066756e6374696f6e2e0035014e4f54453a204578697374696e67206e6f6d696e61746f727320616e642076616c696461746f72732077696c6c206e6f742062652061666665637465642062792074686973207570646174652e1101746f206b69636b2070656f706c6520756e64657220746865206e6577206c696d6974732c20606368696c6c5f6f74686572602073686f756c642062652063616c6c65642e2c6368696c6c5f6f746865720401147374617368000130543a3a4163636f756e74496400176841014465636c61726520612060636f6e74726f6c6c65726020746f2073746f702070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e004101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2c206275742063616e2062652063616c6c656420627920616e796f6e652e0059014966207468652063616c6c6572206973207468652073616d652061732074686520636f6e74726f6c6c6572206265696e672074617267657465642c207468656e206e6f206675727468657220636865636b7320617265d8656e666f726365642c20616e6420746869732066756e6374696f6e2062656861766573206a757374206c696b6520606368696c6c602e005d014966207468652063616c6c657220697320646966666572656e74207468616e2074686520636f6e74726f6c6c6572206265696e672074617267657465642c2074686520666f6c6c6f77696e6720636f6e646974696f6e73306d757374206265206d65743a001d012a2060636f6e74726f6c6c657260206d7573742062656c6f6e6720746f2061206e6f6d696e61746f722077686f20686173206265636f6d65206e6f6e2d6465636f6461626c652c000c4f723a003d012a204120604368696c6c5468726573686f6c6460206d7573742062652073657420616e6420636865636b656420776869636820646566696e657320686f7720636c6f736520746f20746865206d6178550120206e6f6d696e61746f7273206f722076616c696461746f7273207765206d757374207265616368206265666f72652075736572732063616e207374617274206368696c6c696e67206f6e652d616e6f746865722e59012a204120604d61784e6f6d696e61746f72436f756e746020616e6420604d617856616c696461746f72436f756e7460206d75737420626520736574207768696368206973207573656420746f2064657465726d696e65902020686f7720636c6f73652077652061726520746f20746865207468726573686f6c642e5d012a204120604d696e4e6f6d696e61746f72426f6e646020616e6420604d696e56616c696461746f72426f6e6460206d7573742062652073657420616e6420636865636b65642c2077686963682064657465726d696e65735101202069662074686973206973206120706572736f6e20746861742073686f756c64206265206368696c6c6564206265636175736520746865792068617665206e6f74206d657420746865207468726573686f6c64402020626f6e642072657175697265642e005501546869732063616e2062652068656c7066756c20696620626f6e6420726571756972656d656e74732061726520757064617465642c20616e64207765206e65656420746f2072656d6f7665206f6c642075736572739877686f20646f206e6f74207361746973667920746865736520726571756972656d656e74732e68666f7263655f6170706c795f6d696e5f636f6d6d697373696f6e04013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400180c4501466f72636520612076616c696461746f7220746f2068617665206174206c6561737420746865206d696e696d756d20636f6d6d697373696f6e2e20546869732077696c6c206e6f74206166666563742061610176616c696461746f722077686f20616c726561647920686173206120636f6d6d697373696f6e2067726561746572207468616e206f7220657175616c20746f20746865206d696e696d756d2e20416e79206163636f756e743863616e2063616c6c20746869732e487365745f6d696e5f636f6d6d697373696f6e04010c6e6577f4011c50657262696c6c00191025015365747320746865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e005901546869732063616c6c20686173206c6f7765722070726976696c65676520726571756972656d656e7473207468616e20607365745f7374616b696e675f636f6e6669676020616e642063616e2062652063616c6c6564cc6279207468652060543a3a41646d696e4f726967696e602e20526f6f742063616e20616c776179732063616c6c20746869732e587061796f75745f7374616b6572735f62795f706167650c013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780001107061676510011050616765001a443101506179206f757420612070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e2065726120616e6420706167652e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e31012d2060706167656020697320746865207061676520696e646578206f66206e6f6d696e61746f727320746f20706179206f757420776974682076616c7565206265747765656e203020616e64b02020606e756d5f6e6f6d696e61746f7273202f20543a3a4d61784578706f737572655061676553697a65602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e003d01496620612076616c696461746f7220686173206d6f7265207468616e205b60436f6e6669673a3a4d61784578706f737572655061676553697a65605d206e6f6d696e61746f7273206261636b696e6729017468656d2c207468656e20746865206c697374206f66206e6f6d696e61746f72732069732070616765642c207769746820656163682070616765206265696e672063617070656420617455015b60436f6e6669673a3a4d61784578706f737572655061676553697a65602e5d20496620612076616c696461746f7220686173206d6f7265207468616e206f6e652070616765206f66206e6f6d696e61746f72732c49017468652063616c6c206e6565647320746f206265206d61646520666f72206561636820706167652073657061726174656c7920696e206f7264657220666f7220616c6c20746865206e6f6d696e61746f727355016261636b696e6720612076616c696461746f7220746f207265636569766520746865207265776172642e20546865206e6f6d696e61746f727320617265206e6f7420736f72746564206163726f73732070616765736101616e6420736f2069742073686f756c64206e6f7420626520617373756d6564207468652068696768657374207374616b657220776f756c64206265206f6e2074686520746f706d6f7374207061676520616e642076696365490176657273612e204966207265776172647320617265206e6f7420636c61696d656420696e205b60436f6e6669673a3a486973746f72794465707468605d20657261732c207468657920617265206c6f73742e307570646174655f7061796565040128636f6e74726f6c6c6572000130543a3a4163636f756e744964001b18e04d6967726174657320616e206163636f756e742773206052657761726444657374696e6174696f6e3a3a436f6e74726f6c6c65726020746fa46052657761726444657374696e6174696f6e3a3a4163636f756e7428636f6e74726f6c6c657229602e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e003101546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966207468652060706179656560206973207375636365737366756c6c79206d696772617465642e686465707265636174655f636f6e74726f6c6c65725f626174636804012c636f6e74726f6c6c657273590401f4426f756e6465645665633c543a3a4163636f756e7449642c20543a3a4d6178436f6e74726f6c6c657273496e4465707265636174696f6e42617463683e001c1c5d01557064617465732061206261746368206f6620636f6e74726f6c6c6572206163636f756e747320746f20746865697220636f72726573706f6e64696e67207374617368206163636f756e7420696620746865792061726561016e6f74207468652073616d652e2049676e6f72657320616e7920636f6e74726f6c6c6572206163636f756e7473207468617420646f206e6f742065786973742c20616e6420646f6573206e6f74206f706572617465206966b874686520737461736820616e6420636f6e74726f6c6c65722061726520616c7265616479207468652073616d652e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e00b4546865206469737061746368206f726967696e206d7573742062652060543a3a41646d696e4f726967696e602e38726573746f72655f6c65646765721001147374617368000130543a3a4163636f756e7449640001406d617962655f636f6e74726f6c6c65728801504f7074696f6e3c543a3a4163636f756e7449643e00012c6d617962655f746f74616c5d0401504f7074696f6e3c42616c616e63654f663c543e3e00013c6d617962655f756e6c6f636b696e6761040115014f7074696f6e3c426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a0a4d6178556e6c6f636b696e674368756e6b733e3e001d2c0501526573746f72657320746865207374617465206f662061206c656467657220776869636820697320696e20616e20696e636f6e73697374656e742073746174652e00dc54686520726571756972656d656e747320746f20726573746f72652061206c6564676572206172652074686520666f6c6c6f77696e673a642a2054686520737461736820697320626f6e6465643b206f720d012a20546865207374617368206973206e6f7420626f6e64656420627574206974206861732061207374616b696e67206c6f636b206c65667420626568696e643b206f7225012a204966207468652073746173682068617320616e206173736f636961746564206c656467657220616e642069747320737461746520697320696e636f6e73697374656e743b206f721d012a20496620746865206c6564676572206973206e6f7420636f72727570746564202a6275742a20697473207374616b696e67206c6f636b206973206f7574206f662073796e632e00610154686520606d617962655f2a6020696e70757420706172616d65746572732077696c6c206f76657277726974652074686520636f72726573706f6e64696e67206461746120616e64206d65746164617461206f662074686559016c6564676572206173736f6369617465642077697468207468652073746173682e2049662074686520696e70757420706172616d657465727320617265206e6f74207365742c20746865206c65646765722077696c6c9062652072657365742076616c7565732066726f6d206f6e2d636861696e2073746174652e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e4104000002c10200450400000210004904103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200004d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200005104103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f501010c104e6f6f700000000c5365740400f5010104540001001852656d6f7665000200005504103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000059040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e00005d0404184f7074696f6e04045401180108104e6f6e6500000010536f6d650400180000010000610404184f7074696f6e0404540165040108104e6f6e6500000010536f6d6504006504000001000065040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540169040453000004006d0401185665633c543e00006904083870616c6c65745f7374616b696e672c556e6c6f636b4368756e6b041c42616c616e636501180008011476616c75656d01011c42616c616e636500010c65726165020120457261496e64657800006d0400000269040071040c3870616c6c65745f73657373696f6e1870616c6c65741043616c6c040454000108207365745f6b6579730801106b6579737504011c543a3a4b65797300011470726f6f6638011c5665633c75383e000024e453657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e1d01416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722ec05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e00d0546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e0034232320436f6d706c657869747959012d20604f283129602e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f69647328296020776869636820697320202066697865642e2870757267655f6b657973000130c852656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e00c05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e005501546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265205369676e656420616e6420746865206163636f756e74206d757374206265206569746865722062655d01636f6e7665727469626c6520746f20612076616c696461746f72204944207573696e672074686520636861696e2773207479706963616c2061646472657373696e672073797374656d20287468697320757375616c6c7951016d65616e73206265696e67206120636f6e74726f6c6c6572206163636f756e7429206f72206469726563746c7920636f6e7665727469626c6520696e746f20612076616c696461746f722049442028776869636894757375616c6c79206d65616e73206265696e672061207374617368206163636f756e74292e0034232320436f6d706c65786974793d012d20604f2831296020696e206e756d626572206f66206b65792074797065732e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f6698202060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e75040c5874616e676c655f746573746e65745f72756e74696d65186f70617175652c53657373696f6e4b65797300000c011062616265d90201c43c42616265206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c696300011c6772616e647061a801d03c4772616e647061206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000124696d5f6f6e6c696e655d0101d43c496d4f6e6c696e65206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000079040c3c70616c6c65745f74726561737572791870616c6c65741043616c6c0804540004490001182c7370656e645f6c6f63616c080118616d6f756e746d01013c42616c616e63654f663c542c20493e00012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000344b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e0045014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c656173742060616d6f756e74602e002c2323232044657461696c7345014e4f54453a20466f72207265636f72642d6b656570696e6720707572706f7365732c207468652070726f706f736572206973206465656d656420746f206265206571756976616c656e7420746f207468653062656e65666963696172792e003823232320506172616d657465727341012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602ee82d206062656e6566696369617279603a205468652064657374696e6174696f6e206163636f756e7420666f7220746865207472616e736665722e00242323204576656e747300b4456d697473205b604576656e743a3a5370656e64417070726f766564605d206966207375636365737366756c2e3c72656d6f76655f617070726f76616c04012c70726f706f73616c5f69646502013450726f706f73616c496e6465780004542d01466f72636520612070726576696f75736c7920617070726f7665642070726f706f73616c20746f2062652072656d6f7665642066726f6d2074686520617070726f76616c2071756575652e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c7300c0546865206f726967696e616c206465706f7369742077696c6c206e6f206c6f6e6765722062652072657475726e65642e003823232320506172616d6574657273a02d206070726f706f73616c5f6964603a2054686520696e646578206f6620612070726f706f73616c003823232320436f6d706c6578697479ac2d204f2841292077686572652060416020697320746865206e756d626572206f6620617070726f76616c730028232323204572726f727345012d205b604572726f723a3a50726f706f73616c4e6f74417070726f766564605d3a20546865206070726f706f73616c5f69646020737570706c69656420776173206e6f7420666f756e6420696e2074686551012020617070726f76616c2071756575652c20692e652e2c207468652070726f706f73616c20686173206e6f74206265656e20617070726f7665642e205468697320636f756c6420616c736f206d65616e207468655901202070726f706f73616c20646f6573206e6f7420657869737420616c746f6765746865722c2074687573207468657265206973206e6f2077617920697420776f756c642068617665206265656e20617070726f766564542020696e2074686520666972737420706c6163652e147370656e6410012861737365745f6b696e64840144426f783c543a3a41737365744b696e643e000118616d6f756e746d010150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000178426f783c42656e65666963696172794c6f6f6b75704f663c542c20493e3e00012876616c69645f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000568b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e001d014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c65617374550160616d6f756e7460206f66206061737365745f6b696e646020696e20746865206e61746976652061737365742e2054686520616d6f756e74206f66206061737365745f6b696e646020697320636f6e766572746564d4666f7220617373657274696f6e207573696e6720746865205b60436f6e6669673a3a42616c616e6365436f6e766572746572605d2e002823232044657461696c7300490143726561746520616e20617070726f766564207370656e6420666f72207472616e7366657272696e6720612073706563696669632060616d6f756e7460206f66206061737365745f6b696e646020746f2061610164657369676e617465642062656e65666963696172792e20546865207370656e64206d75737420626520636c61696d6564207573696e672074686520607061796f75746020646973706174636861626c652077697468696e74746865205b60436f6e6669673a3a5061796f7574506572696f64605d2e003823232320506172616d657465727315012d206061737365745f6b696e64603a20416e20696e64696361746f72206f662074686520737065636966696320617373657420636c61737320746f206265207370656e742e41012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602eb82d206062656e6566696369617279603a205468652062656e6566696369617279206f6620746865207370656e642e55012d206076616c69645f66726f6d603a2054686520626c6f636b206e756d6265722066726f6d20776869636820746865207370656e642063616e20626520636c61696d65642e2049742063616e20726566657220746f1901202074686520706173742069662074686520726573756c74696e67207370656e6420686173206e6f74207965742065787069726564206163636f7264696e6720746f20746865450120205b60436f6e6669673a3a5061796f7574506572696f64605d2e20496620604e6f6e65602c20746865207370656e642063616e20626520636c61696d656420696d6d6564696174656c792061667465722c2020617070726f76616c2e00242323204576656e747300c8456d697473205b604576656e743a3a41737365745370656e64417070726f766564605d206966207375636365737366756c2e187061796f7574040114696e6465781001285370656e64496e64657800064c38436c61696d2061207370656e642e00482323204469737061746368204f726967696e00384d757374206265207369676e6564002823232044657461696c730055015370656e6473206d75737420626520636c61696d65642077697468696e20736f6d652074656d706f72616c20626f756e64732e2041207370656e64206d617920626520636c61696d65642077697468696e206f6e65d45b60436f6e6669673a3a5061796f7574506572696f64605d2066726f6d20746865206076616c69645f66726f6d6020626c6f636b2e5501496e2063617365206f662061207061796f7574206661696c7572652c20746865207370656e6420737461747573206d75737420626520757064617465642077697468207468652060636865636b5f73746174757360dc646973706174636861626c65206265666f7265207265747279696e672077697468207468652063757272656e742066756e6374696f6e2e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e74730090456d697473205b604576656e743a3a50616964605d206966207375636365737366756c2e30636865636b5f737461747573040114696e6465781001285370656e64496e64657800074c2901436865636b2074686520737461747573206f6620746865207370656e6420616e642072656d6f76652069742066726f6d207468652073746f726167652069662070726f6365737365642e00482323204469737061746368204f726967696e003c4d757374206265207369676e65642e002823232044657461696c730001015468652073746174757320636865636b20697320612070726572657175697369746520666f72207265747279696e672061206661696c6564207061796f75742e490149662061207370656e64206861732065697468657220737563636565646564206f7220657870697265642c2069742069732072656d6f7665642066726f6d207468652073746f726167652062792074686973ec66756e6374696f6e2e20496e207375636820696e7374616e6365732c207472616e73616374696f6e20666565732061726520726566756e6465642e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300f8456d697473205b604576656e743a3a5061796d656e744661696c6564605d20696620746865207370656e64207061796f757420686173206661696c65642e0101456d697473205b604576656e743a3a5370656e6450726f636573736564605d20696620746865207370656e64207061796f75742068617320737563636565642e28766f69645f7370656e64040114696e6465781001285370656e64496e6465780008407c566f69642070726576696f75736c7920617070726f766564207370656e642e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c73001d0141207370656e6420766f6964206973206f6e6c7920706f737369626c6520696620746865207061796f757420686173206e6f74206265656e20617474656d70746564207965742e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300c0456d697473205b604576656e743a3a41737365745370656e64566f69646564605d206966207375636365737366756c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e7d0404184f7074696f6e04045401300108104e6f6e6500000010536f6d65040030000001000081040c3c70616c6c65745f626f756e746965731870616c6c65741043616c6c0804540004490001243870726f706f73655f626f756e747908011476616c75656d01013c42616c616e63654f663c542c20493e00012c6465736372697074696f6e38011c5665633c75383e0000305450726f706f73652061206e657720626f756e74792e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051015061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c206173510160446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e2049742077696c6c20626520756e72657365727665642075706f6e20617070726f76616c2c646f7220736c6173686564207768656e2072656a65637465642e00f82d206063757261746f72603a205468652063757261746f72206163636f756e742077686f6d2077696c6c206d616e616765207468697320626f756e74792e642d2060666565603a205468652063757261746f72206665652e25012d206076616c7565603a2054686520746f74616c207061796d656e7420616d6f756e74206f66207468697320626f756e74792c2063757261746f722066656520696e636c756465642ec02d20606465736372697074696f6e603a20546865206465736372697074696f6e206f66207468697320626f756e74792e38617070726f76655f626f756e7479040124626f756e74795f69646502012c426f756e7479496e64657800011c5d01417070726f7665206120626f756e74792070726f706f73616c2e2041742061206c617465722074696d652c2074686520626f756e74792077696c6c2062652066756e64656420616e64206265636f6d6520616374697665a8616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e3c70726f706f73655f63757261746f720c0124626f756e74795f69646502012c426f756e7479496e64657800011c63757261746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013c42616c616e63654f663c542c20493e0002189450726f706f736520612063757261746f7220746f20612066756e64656420626f756e74792e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e40756e61737369676e5f63757261746f72040124626f756e74795f69646502012c426f756e7479496e6465780003447c556e61737369676e2063757261746f722066726f6d206120626f756e74792e001d01546869732066756e6374696f6e2063616e206f6e6c792062652063616c6c656420627920746865206052656a6563744f726967696e602061207369676e6564206f726967696e2e003d01496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e602c20776520617373756d652074686174207468652063757261746f7220697331016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c2077652077696c6c20736c617368207468652063757261746f72207768656e20706f737369626c652e006101496620746865206f726967696e206973207468652063757261746f722c2077652074616b6520746869732061732061207369676e20746865792061726520756e61626c6520746f20646f207468656972206a6f6220616e645d01746865792077696c6c696e676c7920676976652075702e20576520636f756c6420736c617368207468656d2c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f207265636f76657220746865697235016465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966206974206973206162757365642e29005d0146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e6520696620616e64206f6e6c79206966207468652063757261746f722069732022696e616374697665222e205468697320616c6c6f77736101616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f7574207468617420612063757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e64390177652073686f756c64207069636b2061206e65772063757261746f722e20496e20746869732063617365207468652063757261746f722073686f756c6420616c736f20626520736c61736865642e0034232320436f6d706c65786974791c2d204f2831292e386163636570745f63757261746f72040124626f756e74795f69646502012c426f756e7479496e64657800041c94416363657074207468652063757261746f7220726f6c6520666f72206120626f756e74792e290141206465706f7369742077696c6c2062652072657365727665642066726f6d2063757261746f7220616e6420726566756e642075706f6e207375636365737366756c207061796f75742e00904d6179206f6e6c792062652063616c6c65642066726f6d207468652063757261746f722e0034232320436f6d706c65786974791c2d204f2831292e3061776172645f626f756e7479080124626f756e74795f69646502012c426f756e7479496e64657800012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e0005285901417761726420626f756e747920746f20612062656e6566696369617279206163636f756e742e205468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647338616674657220612064656c61792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f2061776172642e19012d206062656e6566696369617279603a205468652062656e6566696369617279206163636f756e742077686f6d2077696c6c207265636569766520746865207061796f75742e0034232320436f6d706c65786974791c2d204f2831292e30636c61696d5f626f756e7479040124626f756e74795f69646502012c426f756e7479496e646578000620ec436c61696d20746865207061796f75742066726f6d20616e206177617264656420626f756e7479206166746572207061796f75742064656c61792e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652062656e6566696369617279206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f20636c61696d2e0034232320436f6d706c65786974791c2d204f2831292e30636c6f73655f626f756e7479040124626f756e74795f69646502012c426f756e7479496e646578000724390143616e63656c20612070726f706f736564206f722061637469766520626f756e74792e20416c6c207468652066756e64732077696c6c2062652073656e7420746f20747265617375727920616e64cc7468652063757261746f72206465706f7369742077696c6c20626520756e726573657276656420696620706f737369626c652e00c84f6e6c792060543a3a52656a6563744f726967696e602069732061626c6520746f2063616e63656c206120626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f2063616e63656c2e0034232320436f6d706c65786974791c2d204f2831292e50657874656e645f626f756e74795f657870697279080124626f756e74795f69646502012c426f756e7479496e64657800011872656d61726b38011c5665633c75383e000824ac457874656e6420746865206578706972792074696d65206f6620616e2061637469766520626f756e74792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f20657874656e642e8c2d206072656d61726b603a206164646974696f6e616c20696e666f726d6174696f6e2e0034232320436f6d706c65786974791c2d204f2831292e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e85040c5470616c6c65745f6368696c645f626f756e746965731870616c6c65741043616c6c04045400011c406164645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800011476616c75656d01013042616c616e63654f663c543e00012c6465736372697074696f6e38011c5665633c75383e00004c5c4164642061206e6577206368696c642d626f756e74792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f6620706172656e74dc626f756e747920616e642074686520706172656e7420626f756e7479206d75737420626520696e2022616374697665222073746174652e0005014368696c642d626f756e74792067657473206164646564207375636365737366756c6c7920262066756e642067657473207472616e736665727265642066726f6d0901706172656e7420626f756e747920746f206368696c642d626f756e7479206163636f756e742c20696620706172656e7420626f756e74792068617320656e6f7567686c66756e64732c20656c7365207468652063616c6c206661696c732e000d01557070657220626f756e6420746f206d6178696d756d206e756d626572206f662061637469766520206368696c6420626f756e7469657320746861742063616e206265a8616464656420617265206d616e61676564207669612072756e74696d6520747261697420636f6e666967985b60436f6e6669673a3a4d61784163746976654368696c64426f756e7479436f756e74605d2e0001014966207468652063616c6c20697320737563636573732c2074686520737461747573206f66206368696c642d626f756e7479206973207570646174656420746f20224164646564222e004d012d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e747920666f72207768696368206368696c642d626f756e7479206973206265696e672061646465642eb02d206076616c7565603a2056616c756520666f7220657865637574696e67207468652070726f706f73616c2edc2d20606465736372697074696f6e603a2054657874206465736372697074696f6e20666f7220746865206368696c642d626f756e74792e3c70726f706f73655f63757261746f72100140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800011c63757261746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013042616c616e63654f663c543e00013ca050726f706f73652063757261746f7220666f722066756e646564206368696c642d626f756e74792e000d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652063757261746f72206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e20224164646564222073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6405017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202243757261746f7250726f706f73656422206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792eb42d206063757261746f72603a2041646472657373206f66206368696c642d626f756e74792063757261746f722eec2d2060666565603a207061796d656e742066656520746f206368696c642d626f756e74792063757261746f7220666f7220657865637574696f6e2e386163636570745f63757261746f72080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800024cb4416363657074207468652063757261746f7220726f6c6520666f7220746865206368696c642d626f756e74792e00f4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f662074686973346368696c642d626f756e74792e00ec41206465706f7369742077696c6c2062652072657365727665642066726f6d207468652063757261746f7220616e6420726566756e642075706f6e887375636365737366756c207061796f7574206f722063616e63656c6c6174696f6e2e00f846656520666f722063757261746f722069732064656475637465642066726f6d2063757261746f7220666565206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e202243757261746f7250726f706f736564222073746174652c20666f722070726f63657373696e6720746865090163616c6c2e20416e64207374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202241637469766522206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e40756e61737369676e5f63757261746f72080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800038894556e61737369676e2063757261746f722066726f6d2061206368696c642d626f756e74792e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c2063616e20626520656974686572206052656a6563744f726967696e602c206f72dc7468652063757261746f72206f662074686520706172656e7420626f756e74792c206f7220616e79207369676e6564206f726967696e2e00f8466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e20616e6420746865206368696c642d626f756e7479010163757261746f722c20706172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f7220746869732063616c6c20746f0901776f726b2e20576520616c6c6f77206368696c642d626f756e74792063757261746f7220616e6420543a3a52656a6563744f726967696e20746f2065786563757465c8746869732063616c6c20697272657370656374697665206f662074686520706172656e7420626f756e74792073746174652e00dc496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e60206f72207468650501706172656e7420626f756e74792063757261746f722c20776520617373756d65207468617420746865206368696c642d626f756e74792063757261746f722069730d016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e000501496620746865206f726967696e20697320746865206368696c642d626f756e74792063757261746f722c2077652074616b6520746869732061732061207369676e09017468617420746865792061726520756e61626c6520746f20646f207468656972206a6f622c20616e64206172652077696c6c696e676c7920676976696e672075702e0901576520636f756c6420736c61736820746865206465706f7369742c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f20756e7265736572766511017468656972206465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966386974206973206162757365642e2900050146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e652069666620746865206368696c642d626f756e74792063757261746f72206973090122696e616374697665222e204578706972792075706461746520647565206f6620706172656e7420626f756e7479206973207573656420746f20657374696d6174659c696e616374697665207374617465206f66206368696c642d626f756e74792063757261746f722e000d015468697320616c6c6f777320616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f757420746861742061206368696c642d626f756e7479090163757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e642077652073686f756c64207069636b2061206e6577f86f6e652e20496e2074686973206361736520746865206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e0001015374617465206f66206368696c642d626f756e7479206973206d6f76656420746f204164646564207374617465206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e4861776172645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000444904177617264206368696c642d626f756e747920746f20612062656e65666963696172792e00f85468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647320616674657220612064656c61792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652074686520706172656e742063757261746f72206f727463757261746f72206f662074686973206368696c642d626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e0009014368696c642d626f756e7479206d75737420626520696e206163746976652073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6411017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202250656e64696e675061796f757422206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e942d206062656e6566696369617279603a2042656e6566696369617279206163636f756e742e48636c61696d5f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e6465780005400501436c61696d20746865207061796f75742066726f6d20616e2061776172646564206368696c642d626f756e7479206166746572207061796f75742064656c61792e00ec546865206469737061746368206f726967696e20666f7220746869732063616c6c206d617920626520616e79207369676e6564206f726967696e2e00050143616c6c20776f726b7320696e646570656e64656e74206f6620706172656e7420626f756e74792073746174652c204e6f206e65656420666f7220706172656e7474626f756e747920746f20626520696e206163746976652073746174652e0011015468652042656e65666963696172792069732070616964206f757420776974682061677265656420626f756e74792076616c75652e2043757261746f7220666565206973947061696420262063757261746f72206465706f73697420697320756e72657365727665642e0005014368696c642d626f756e7479206d75737420626520696e202250656e64696e675061796f7574222073746174652c20666f722070726f63657373696e6720746865fc63616c6c2e20416e6420696e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e6c7375636365737366756c2063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e48636c6f73655f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e646578000658110143616e63656c20612070726f706f736564206f7220616374697665206368696c642d626f756e74792e204368696c642d626f756e7479206163636f756e742066756e64730901617265207472616e7366657272656420746f20706172656e7420626f756e7479206163636f756e742e20546865206368696c642d626f756e74792063757261746f72986465706f736974206d617920626520756e726573657276656420696620706f737369626c652e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652065697468657220706172656e742063757261746f72206f724860543a3a52656a6563744f726967696e602e00f0496620746865207374617465206f66206368696c642d626f756e74792069732060416374697665602c2063757261746f72206465706f7369742069732c756e72657365727665642e00f4496620746865207374617465206f66206368696c642d626f756e7479206973206050656e64696e675061796f7574602c2063616c6c206661696c7320267872657475726e73206050656e64696e675061796f757460206572726f722e000d01466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e2c20706172656e7420626f756e7479206d75737420626520696ef06163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f20776f726b2e20466f72206f726967696e90543a3a52656a6563744f726967696e20657865637574696f6e20697320666f726365642e000101496e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89040c4070616c6c65745f626167735f6c6973741870616c6c65741043616c6c08045400044900010c1472656261670401286469736c6f6361746564c10201504163636f756e7449644c6f6f6b75704f663c543e00002859014465636c617265207468617420736f6d6520606469736c6f636174656460206163636f756e74206861732c207468726f7567682072657761726473206f722070656e616c746965732c2073756666696369656e746c7951016368616e676564206974732073636f726520746861742069742073686f756c642070726f7065726c792066616c6c20696e746f206120646966666572656e7420626167207468616e206974732063757272656e74106f6e652e001d01416e796f6e652063616e2063616c6c20746869732066756e6374696f6e2061626f757420616e7920706f74656e7469616c6c79206469736c6f6361746564206163636f756e742e00490157696c6c20616c7761797320757064617465207468652073746f7265642073636f7265206f6620606469736c6f63617465646020746f2074686520636f72726563742073636f72652c206261736564206f6e406053636f726550726f7669646572602e00d4496620606469736c6f63617465646020646f6573206e6f74206578697374732c2069742072657475726e7320616e206572726f722e3c7075745f696e5f66726f6e745f6f6604011c6c696768746572c10201504163636f756e7449644c6f6f6b75704f663c543e000128d04d6f7665207468652063616c6c65722773204964206469726563746c7920696e2066726f6e74206f6620606c696768746572602e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642063616e206f6e6c792062652063616c6c656420627920746865204964206f663501746865206163636f756e7420676f696e6720696e2066726f6e74206f6620606c696768746572602e2046656520697320706179656420627920746865206f726967696e20756e64657220616c6c3863697263756d7374616e6365732e00384f6e6c7920776f726b732069663a00942d20626f7468206e6f646573206172652077697468696e207468652073616d65206261672cd02d20616e6420606f726967696e602068617320612067726561746572206053636f726560207468616e20606c696768746572602e547075745f696e5f66726f6e745f6f665f6f7468657208011c68656176696572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c6c696768746572c10201504163636f756e7449644c6f6f6b75704f663c543e00020c110153616d65206173205b6050616c6c65743a3a7075745f696e5f66726f6e745f6f66605d2c206275742069742063616e2062652063616c6c656420627920616e796f6e652e00c8466565206973207061696420627920746865206f726967696e20756e64657220616c6c2063697263756d7374616e6365732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d040c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c65741043616c6c040454000168106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002845015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f746500cc2a20416e206163636f756e742063616e206f6e6c792062652061206d656d626572206f6620612073696e676c6520706f6f6c2ed82a20416e206163636f756e742063616e6e6f74206a6f696e207468652073616d6520706f6f6c206d756c7469706c652074696d65732e41012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726104011465787472619104015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e30636c61696d5f7061796f757400022055014120626f6e646564206d656d6265722063616e20757365207468697320746f20636c61696d207468656972207061796f7574206261736564206f6e20746865207265776172647320746861742074686520706f6f6c610168617320616363756d756c617465642073696e6365207468656972206c61737420636c61696d6564207061796f757420284f522073696e6365206a6f696e696e6720696620746869732069732074686569722066697273743d0174696d6520636c61696d696e672072657761726473292e20546865207061796f75742077696c6c206265207472616e7366657272656420746f20746865206d656d6265722773206163636f756e742e004901546865206d656d6265722077696c6c206561726e20726577617264732070726f2072617461206261736564206f6e20746865206d656d62657273207374616b65207673207468652073756d206f6620746865d06d656d6265727320696e2074686520706f6f6c73207374616b652e205265776172647320646f206e6f742022657870697265222e0041015365652060636c61696d5f7061796f75745f6f746865726020746f20636c61696d2072657761726473206f6e20626568616c66206f6620736f6d6520606f746865726020706f6f6c206d656d6265722e18756e626f6e640801386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640801386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e0001486e756d5f736c617368696e675f7370616e7310010c7533320005585501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500f42d204966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e61012d2049662074686520706f6f6c2068617320616e792070656e64696e6720736c6173682c20776520616c736f2074727920746f20736c61736820746865206d656d626572206265666f7265206c657474696e67207468656d5d0177697468647261772e20546869732063616c63756c6174696f6e206164647320736f6d6520776569676874206f7665726865616420616e64206973206f6e6c7920646566656e736976652e20496e207265616c6974792c5501706f6f6c20736c6173686573206d7573742068617665206265656e20616c7265616479206170706c69656420766961207065726d697373696f6e6c657373205b6043616c6c3a3a6170706c795f736c617368605d2e18637265617465100118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f6964140118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f72733d0201445665633c543a3a4163636f756e7449643e0008307c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e001823204e6f7465005d01496e206164646974696f6e20746f20612060726f6f7460206f7220606e6f6d696e61746f726020726f6c65206f6620606f726967696e602c20706f6f6c2773206465706f7369746f72206e6565647320746f2068617665f86174206c6561737420606465706f7369746f725f6d696e5f626f6e646020696e2074686520706f6f6c20746f207374617274206e6f6d696e6174696e672e247365745f737461746508011c706f6f6c5f6964100118506f6f6c496400011473746174651d010124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731801346d696e5f6a6f696e5f626f6e6495040158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6495040158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7399040134436f6e6669674f703c7533323e00012c6d61785f6d656d6265727399040134436f6e6669674f703c7533323e0001506d61785f6d656d626572735f7065725f706f6f6c99040134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e9d040144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d757374206265605b60436f6e6669673a3a41646d696e4f726967696e605d2e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f74a1040158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f72a1040158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e636572a1040158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d40704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004101546865206469737061746368206f726967696e206f6620746869732063616c6c2063616e206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463683a59012a205768656e20706f6f6c206465706f7369746f7220686173206c657373207468616e20604d696e4e6f6d696e61746f72426f6e6460207374616b65642c206f74686572776973652020706f6f6c206d656d626572735c202061726520756e61626c6520746f20756e626f6e642e009c2320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463683ad82a205468652063616c6c6572206861732061206e6f6d696e61746f72206f7220726f6f7420726f6c65206f662074686520706f6f6c2e490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720801186d656d626572c10201504163636f756e7449644c6f6f6b75704f663c543e00011465787472619104015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373436f6d706f756e6460206f7220605065726d697373696f6e6c657373416c6c602e507365745f636c61696d5f7065726d697373696f6e0401287065726d697373696f6ea504013c436c61696d5065726d697373696f6e000f1c4901416c6c6f7773206120706f6f6c206d656d62657220746f20736574206120636c61696d207065726d697373696f6e20746f20616c6c6f77206f7220646973616c6c6f77207065726d697373696f6e6c65737360626f6e64696e6720616e64207769746864726177696e672e002c2320417267756d656e747300782a20606f726967696e60202d204d656d626572206f66206120706f6f6c2eb82a20607065726d697373696f6e60202d20546865207065726d697373696f6e20746f206265206170706c6965642e48636c61696d5f7061796f75745f6f746865720401146f74686572000130543a3a4163636f756e7449640010100101606f726967696e602063616e20636c61696d207061796f757473206f6e20736f6d6520706f6f6c206d656d62657220606f7468657260277320626568616c662e005501506f6f6c206d656d62657220606f7468657260206d7573742068617665206120605065726d697373696f6e6c657373576974686472617760206f7220605065726d697373696f6e6c657373416c6c6020636c61696da87065726d697373696f6e20666f7220746869732063616c6c20746f206265207375636365737366756c2e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6cc869732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e2c6170706c795f736c6173680401386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00171c884170706c7920612070656e64696e6720736c617368206f6e2061206d656d6265722e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e005501546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79206163636f756e74292e20496620746865206d656d626572206861731d01736c61736820746f206265206170706c6965642c2063616c6c6572206d61792062652072657761726465642077697468207468652070617274206f662074686520736c6173682e486d6967726174655f64656c65676174696f6e0401386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e0018241d014d696772617465732064656c6567617465642066756e64732066726f6d2074686520706f6f6c206163636f756e7420746f2074686520606d656d6265725f6163636f756e74602e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e002901546869732069732061207065726d697373696f6e2d6c6573732063616c6c20616e6420726566756e647320616e792066656520696620636c61696d206973207375636365737366756c2e005d0149662074686520706f6f6c20686173206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746865207374616b656420746f6b656e73206f6620706f6f6c206d656d62657273290163616e206265206d6f76656420616e642068656c6420696e207468656972206f776e206163636f756e742e20536565205b60616461707465723a3a44656c65676174655374616b65605d786d6967726174655f706f6f6c5f746f5f64656c65676174655f7374616b6504011c706f6f6c5f6964100118506f6f6c4964001924f44d69677261746520706f6f6c2066726f6d205b60616461707465723a3a5374616b655374726174656779547970653a3a5472616e73666572605d20746fa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e004101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792c20616e6420726566756e647320616e7920666565206966207375636365737366756c2e00490149662074686520706f6f6c2068617320616c7265616479206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746869732063616c6c2077696c6c206661696c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e9104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324426f6e644578747261041c42616c616e6365011801082c4672656542616c616e6365040018011c42616c616e63650000001c52657761726473000100009504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200009904085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200009d04085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f766500020000a104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f766500020000a504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000a9040c4070616c6c65745f7363686564756c65721870616c6c65741043616c6c040454000128207363686564756c651001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00000470416e6f6e796d6f75736c79207363686564756c652061207461736b2e1863616e63656c0801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001049443616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e387363686564756c655f6e616d656414010869640401205461736b4e616d650001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000204585363686564756c652061206e616d6564207461736b2e3063616e63656c5f6e616d656404010869640401205461736b4e616d650003047843616e63656c2061206e616d6564207363686564756c6564207461736b2e387363686564756c655f61667465721001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000404a8416e6f6e796d6f75736c79207363686564756c652061207461736b20616674657220612064656c61792e507363686564756c655f6e616d65645f616674657214010869640401205461736b4e616d650001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000504905363686564756c652061206e616d6564207461736b20616674657220612064656c61792e247365745f72657472790c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0006305901536574206120726574727920636f6e66696775726174696f6e20666f722061207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069742077696c6c5501626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c2069742473756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3c7365745f72657472795f6e616d65640c010869640401205461736b4e616d6500011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0007305d01536574206120726574727920636f6e66696775726174696f6e20666f722061206e616d6564207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069745d0177696c6c20626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c3069742073756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3063616e63656c5f72657472790401107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e000804a852656d6f7665732074686520726574727920636f6e66696775726174696f6e206f662061207461736b2e4863616e63656c5f72657472795f6e616d656404010869640401205461736b4e616d65000904bc43616e63656c2074686520726574727920636f6e66696775726174696f6e206f662061206e616d6564207461736b2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ead0404184f7074696f6e0404540139010108104e6f6e6500000010536f6d65040039010000010000b1040c3c70616c6c65745f707265696d6167651870616c6c65741043616c6c040454000114346e6f74655f707265696d616765040114627974657338011c5665633c75383e000010745265676973746572206120707265696d616765206f6e2d636861696e2e00550149662074686520707265696d616765207761732070726576696f75736c79207265717565737465642c206e6f2066656573206f72206465706f73697473206172652074616b656e20666f722070726f766964696e67550174686520707265696d6167652e204f74686572776973652c2061206465706f7369742069732074616b656e2070726f706f7274696f6e616c20746f207468652073697a65206f662074686520707265696d6167652e3c756e6e6f74655f707265696d6167650401106861736834011c543a3a48617368000118dc436c65617220616e20756e72657175657374656420707265696d6167652066726f6d207468652072756e74696d652073746f726167652e00fc496620606c656e602069732070726f76696465642c207468656e2069742077696c6c2062652061206d7563682063686561706572206f7065726174696f6e2e0001012d206068617368603a205468652068617368206f662074686520707265696d61676520746f2062652072656d6f7665642066726f6d207468652073746f72652eb82d20606c656e603a20546865206c656e677468206f662074686520707265696d616765206f66206068617368602e40726571756573745f707265696d6167650401106861736834011c543a3a48617368000210410152657175657374206120707265696d6167652062652075706c6f6164656420746f2074686520636861696e20776974686f757420706179696e6720616e792066656573206f72206465706f736974732e00550149662074686520707265696d6167652072657175657374732068617320616c7265616479206265656e2070726f7669646564206f6e2d636861696e2c20776520756e7265736572766520616e79206465706f7369743901612075736572206d6179206861766520706169642c20616e642074616b652074686520636f6e74726f6c206f662074686520707265696d616765206f7574206f662074686569722068616e64732e48756e726571756573745f707265696d6167650401106861736834011c543a3a4861736800030cbc436c65617220612070726576696f75736c79206d616465207265717565737420666f72206120707265696d6167652e002d014e4f54453a2054484953204d555354204e4f542042452043414c4c4544204f4e20606861736860204d4f52452054494d4553205448414e2060726571756573745f707265696d616765602e38656e737572655f75706461746564040118686173686573c10101305665633c543a3a486173683e00040cc4456e7375726520746861742074686520612062756c6b206f66207072652d696d616765732069732075706772616465642e003d015468652063616c6c65722070617973206e6f20666565206966206174206c6561737420393025206f66207072652d696d616765732077657265207375636365737366756c6c7920757064617465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb5040c3c70616c6c65745f74785f70617573651870616c6c65741043616c6c04045400010814706175736504012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e00001034506175736520612063616c6c2e00b843616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a50617573654f726967696e605d2ec0456d69747320616e205b604576656e743a3a43616c6c506175736564605d206576656e74206f6e20737563636573732e1c756e70617573650401146964656e745101015052756e74696d6543616c6c4e616d654f663c543e00011040556e2d706175736520612063616c6c2e00c043616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a556e70617573654f726967696e605d2ec8456d69747320616e205b604576656e743a3a43616c6c556e706175736564605d206576656e74206f6e20737563636573732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb9040c4070616c6c65745f696d5f6f6e6c696e651870616c6c65741043616c6c04045400010424686561727462656174080124686561727462656174bd0401704865617274626561743c426c6f636b4e756d626572466f723c543e3e0001247369676e6174757265c10401bc3c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000c38232320436f6d706c65786974793afc2d20604f284b2960207768657265204b206973206c656e677468206f6620604b6579736020286865617274626561742e76616c696461746f72735f6c656e298820202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b60040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ebd04084070616c6c65745f696d5f6f6e6c696e6524486561727462656174042c426c6f636b4e756d626572013000100130626c6f636b5f6e756d62657230012c426c6f636b4e756d62657200013473657373696f6e5f696e64657810013053657373696f6e496e64657800013c617574686f726974795f696e64657810012441757468496e64657800013876616c696461746f72735f6c656e10010c7533320000c104104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139245369676e61747572650000040009030148737232353531393a3a5369676e61747572650000c5040c3c70616c6c65745f6964656e746974791870616c6c65741043616c6c040454000158346164645f72656769737472617204011c6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00001c7841646420612072656769737472617220746f207468652073797374656d2e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060543a3a5265676973747261724f726967696e602e00a82d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e0094456d6974732060526567697374726172416464656460206966207375636365737366756c2e307365745f6964656e74697479040110696e666fc904016c426f783c543a3a4964656e74697479496e666f726d6174696f6e3e000128290153657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e005501496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7450666f7220746865206e6577206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e008c2d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e0088456d69747320604964656e7469747953657460206966207375636365737366756c2e207365745f7375627304011073756273510501645665633c28543a3a4163636f756e7449642c2044617461293e0002248c53657420746865207375622d6163636f756e7473206f66207468652073656e6465722e0055015061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e65642d01616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e00b02d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e38636c6561725f6964656e746974790003203901436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e00ec5061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e0098456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e44726571756573745f6a756467656d656e740801247265675f696e64657865020138526567697374726172496e64657800011c6d61785f6665656d01013042616c616e63654f663c543e00044094526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e0055015061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7418676976656e2e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e001d012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e55012d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a00306060606e6f636f6d70696c65b853656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665650c60606000a4456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e3863616e63656c5f726571756573740401247265675f696e646578100138526567697374726172496e6465780005286843616e63656c20612070726576696f757320726571756573742e00f85061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e0045012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e00ac456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e1c7365745f666565080114696e64657865020138526567697374726172496e64657800010c6665656d01013042616c616e63654f663c543e00061c1901536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e542d2060666565603a20746865206e6577206665652e387365745f6163636f756e745f6964080114696e64657865020138526567697374726172496e64657800010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e00071cbc4368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e702d20606e6577603a20746865206e6577206163636f756e742049442e287365745f6669656c6473080114696e64657865020138526567697374726172496e6465780001186669656c6473300129013c543a3a4964656e74697479496e666f726d6174696f6e206173204964656e74697479496e666f726d6174696f6e50726f76696465723e3a3a0a4669656c64734964656e74696669657200081ca853657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e0d012d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e4470726f766964655f6a756467656d656e741001247265675f696e64657865020138526567697374726172496e646578000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001246a756467656d656e745905015c4a756467656d656e743c42616c616e63654f663c543e3e0001206964656e7469747934011c543a3a4861736800093cb850726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74b06f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e0021012d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e55012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e49012d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e5d012d20606964656e74697479603a205468652068617368206f6620746865205b604964656e74697479496e666f726d6174696f6e50726f7669646572605d20666f72207468617420746865206a756467656d656e742069732c202070726f76696465642e00b04e6f74653a204a756467656d656e747320646f206e6f74206170706c7920746f206120757365726e616d652e0094456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e346b696c6c5f6964656e74697479040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000a30410152656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e0061015061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c6564206279450160536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564806d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e00f8546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206d617463682060543a3a466f7263654f726967696e602e0055012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e0094456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e1c6164645f73756208010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d504011044617461000b1cac4164642074686520676976656e206163636f756e7420746f207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656e616d655f73756208010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d504011044617461000c10cc416c74657220746865206173736f636961746564206e616d65206f662074686520676976656e207375622d6163636f756e742e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656d6f76655f73756204010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e000d1cc052656d6f76652074686520676976656e206163636f756e742066726f6d207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e20717569745f737562000e288c52656d6f7665207468652073656e6465722061732061207375622d6163636f756e742e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c206265207265706174726961746564b4746f207468652073656e64657220282a6e6f742a20746865206f726967696e616c206465706f7369746f72292e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d7573742068617665206120726567697374657265643c73757065722d6964656e746974792e0045014e4f54453a20546869732073686f756c64206e6f74206e6f726d616c6c7920626520757365642c206275742069732070726f766964656420696e207468652063617365207468617420746865206e6f6e2d1101636f6e74726f6c6c6572206f6620616e206163636f756e74206973206d616c6963696f75736c7920726567697374657265642061732061207375622d6163636f756e742e586164645f757365726e616d655f617574686f726974790c0124617574686f72697479c10201504163636f756e7449644c6f6f6b75704f663c543e00011873756666697838011c5665633c75383e000128616c6c6f636174696f6e10010c753332000f10550141646420616e20604163636f756e744964602077697468207065726d697373696f6e20746f206772616e7420757365726e616d65732077697468206120676976656e20607375666669786020617070656e6465642e00590154686520617574686f726974792063616e206772616e7420757020746f2060616c6c6f636174696f6e6020757365726e616d65732e20546f20746f7020757020746865697220616c6c6f636174696f6e2c2074686579490173686f756c64206a75737420697373756520286f7220726571756573742076696120676f7665726e616e6365292061206e657720606164645f757365726e616d655f617574686f72697479602063616c6c2e6472656d6f76655f757365726e616d655f617574686f72697479040124617574686f72697479c10201504163636f756e7449644c6f6f6b75704f663c543e001004c452656d6f76652060617574686f72697479602066726f6d2074686520757365726e616d6520617574686f7269746965732e407365745f757365726e616d655f666f720c010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000120757365726e616d6538011c5665633c75383e0001247369676e61747572655d0501704f7074696f6e3c543a3a4f6666636861696e5369676e61747572653e0011240d015365742074686520757365726e616d6520666f72206077686f602e204d7573742062652063616c6c6564206279206120757365726e616d6520617574686f726974792e00550154686520617574686f72697479206d757374206861766520616e2060616c6c6f636174696f6e602e2055736572732063616e20656974686572207072652d7369676e20746865697220757365726e616d6573206f7248616363657074207468656d206c617465722e003c557365726e616d6573206d7573743ad820202d204f6e6c7920636f6e7461696e206c6f776572636173652041534349492063686172616374657273206f72206469676974732e350120202d205768656e20636f6d62696e656420776974682074686520737566666978206f66207468652069737375696e6720617574686f72697479206265205f6c657373207468616e5f207468656020202020604d6178557365726e616d654c656e677468602e3c6163636570745f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0012084d01416363657074206120676976656e20757365726e616d65207468617420616e2060617574686f7269747960206772616e7465642e205468652063616c6c206d75737420696e636c756465207468652066756c6c88757365726e616d652c20617320696e2060757365726e616d652e737566666978602e5c72656d6f76655f657870697265645f617070726f76616c040120757365726e616d657d01012c557365726e616d653c543e00130c610152656d6f766520616e206578706972656420757365726e616d6520617070726f76616c2e2054686520757365726e616d652077617320617070726f76656420627920616e20617574686f7269747920627574206e657665725501616363657074656420627920746865207573657220616e64206d757374206e6f77206265206265796f6e64206974732065787069726174696f6e2e205468652063616c6c206d75737420696e636c756465207468659c66756c6c20757365726e616d652c20617320696e2060757365726e616d652e737566666978602e507365745f7072696d6172795f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0014043101536574206120676976656e20757365726e616d6520617320746865207072696d6172792e2054686520757365726e616d652073686f756c6420696e636c75646520746865207375666669782e6072656d6f76655f64616e676c696e675f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e001508550152656d6f7665206120757365726e616d65207468617420636f72726573706f6e647320746f20616e206163636f756e742077697468206e6f206964656e746974792e20457869737473207768656e20612075736572c067657473206120757365726e616d6520627574207468656e2063616c6c732060636c6561725f6964656e74697479602e04704964656e746974792070616c6c6574206465636c61726174696f6e2ec9040c3c70616c6c65745f6964656e74697479186c6567616379304964656e74697479496e666f04284669656c644c696d697400002401286164646974696f6e616ccd040190426f756e6465645665633c28446174612c2044617461292c204669656c644c696d69743e00011c646973706c6179d5040110446174610001146c6567616cd50401104461746100010c776562d50401104461746100011072696f74d504011044617461000114656d61696cd50401104461746100013c7067705f66696e6765727072696e744d0501404f7074696f6e3c5b75383b2032305d3e000114696d616765d50401104461746100011c74776974746572d5040110446174610000cd040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d104045300000400490501185665633c543e0000d10400000408d504d50400d5040c3c70616c6c65745f6964656e746974791474797065731044617461000198104e6f6e6500000010526177300400d9040000010010526177310400dd040000020010526177320400e1040000030010526177330400e5040000040010526177340400480000050010526177350400e9040000060010526177360400ed040000070010526177370400f1040000080010526177380400a9020000090010526177390400f50400000a001452617731300400f90400000b001452617731310400fd0400000c001452617731320400010500000d001452617731330400050500000e001452617731340400090500000f0014526177313504000d05000010001452617731360400490100001100145261773137040011050000120014526177313804001505000013001452617731390400190500001400145261773230040095010000150014526177323104001d050000160014526177323204002105000017001452617732330400250500001800145261773234040029050000190014526177323504002d0500001a001452617732360400310500001b001452617732370400350500001c001452617732380400390500001d0014526177323904003d0500001e001452617733300400410500001f001452617733310400450500002000145261773332040004000021002c426c616b6554776f323536040004000022001853686132353604000400002300244b656363616b323536040004000024002c53686154687265653235360400040000250000d904000003000000000800dd04000003010000000800e104000003020000000800e504000003030000000800e904000003050000000800ed04000003060000000800f104000003070000000800f504000003090000000800f9040000030a0000000800fd040000030b000000080001050000030c000000080005050000030d000000080009050000030e00000008000d050000030f00000008001105000003110000000800150500000312000000080019050000031300000008001d050000031500000008002105000003160000000800250500000317000000080029050000031800000008002d0500000319000000080031050000031a000000080035050000031b000000080039050000031c00000008003d050000031d000000080041050000031e000000080045050000031f00000008004905000002d104004d0504184f7074696f6e0404540195010108104e6f6e6500000010536f6d65040095010000010000510500000255050055050000040800d5040059050c3c70616c6c65745f6964656e74697479147479706573244a756467656d656e74041c42616c616e63650118011c1c556e6b6e6f776e0000001c46656550616964040018011c42616c616e636500010028526561736f6e61626c65000200244b6e6f776e476f6f64000300244f75744f6644617465000400284c6f775175616c697479000500244572726f6e656f7573000600005d0504184f7074696f6e0404540161050108104e6f6e6500000010536f6d650400610500000100006105082873705f72756e74696d65384d756c74695369676e617475726500010c1c45643235353139040009030148656432353531393a3a5369676e61747572650000001c53723235353139040009030148737232353531393a3a5369676e617475726500010014456364736104006505014065636473613a3a5369676e617475726500020000650500000341000000080069050c3870616c6c65745f7574696c6974791870616c6c65741043616c6c04045400011814626174636804011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000487c53656e642061206261746368206f662064697370617463682063616c6c732e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e005501546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e31016576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e207468655501604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d6164654d01616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c65746564604c6576656e74206973206465706f73697465642e3461735f64657269766174697665080114696e646578e901010c75313600011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000134dc53656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e00550146696c7465722066726f6d206f726967696e206172652070617373656420616c6f6e672e205468652063616c6c2077696c6c2062652064697370617463686564207769746820616e206f726967696e207768696368bc757365207468652073616d652066696c74657220617320746865206f726967696e206f6620746869732063616c6c2e0045014e4f54453a20496620796f75206e65656420746f20656e73757265207468617420616e79206163636f756e742d62617365642066696c746572696e67206973206e6f7420686f6e6f7265642028692e652e61016265636175736520796f7520657870656374206070726f78796020746f2068617665206265656e2075736564207072696f7220696e207468652063616c6c20737461636b20616e6420796f7520646f206e6f742077616e7451017468652063616c6c207265737472696374696f6e7320746f206170706c7920746f20616e79207375622d6163636f756e7473292c207468656e20757365206061735f6d756c74695f7468726573686f6c645f31607c696e20746865204d756c74697369672070616c6c657420696e73746561642e00f44e4f54453a205072696f7220746f2076657273696f6e202a31322c2074686973207761732063616c6c6564206061735f6c696d697465645f737562602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2462617463685f616c6c04011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000234ec53656e642061206261746368206f662064697370617463682063616c6c7320616e642061746f6d6963616c6c792065786563757465207468656d2e21015468652077686f6c65207472616e73616374696f6e2077696c6c20726f6c6c6261636b20616e64206661696c20696620616e79206f66207468652063616c6c73206661696c65642e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c64697370617463685f617308012461735f6f726967696e71050154426f783c543a3a50616c6c6574734f726967696e3e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000318c84469737061746368657320612066756e6374696f6e2063616c6c207769746820612070726f7669646564206f726967696e2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e0034232320436f6d706c65786974791c2d204f2831292e2c666f7263655f626174636804011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0004347c53656e642061206261746368206f662064697370617463682063616c6c732ed4556e6c696b6520606261746368602c20697420616c6c6f7773206572726f727320616e6420776f6e277420696e746572727570742e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e004d014966206f726967696e20697320726f6f74207468656e207468652063616c6c732061726520646973706174636820776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c776974685f77656967687408011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000518c4446973706174636820612066756e6374696f6e2063616c6c2077697468206120737065636966696564207765696768742e002d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b8526f6f74206f726967696e20746f20737065636966792074686520776569676874206f66207468652063616c6c2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e6d05000002b902007105085874616e676c655f746573746e65745f72756e74696d65304f726967696e43616c6c65720001101873797374656d0400750501746672616d655f73797374656d3a3a4f726967696e3c52756e74696d653e0001001c436f756e63696c0400790501010170616c6c65745f636f6c6c6563746976653a3a4f726967696e3c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d0020457468657265756d04007d05015c70616c6c65745f657468657265756d3a3a4f726967696e00210010566f696404001d0301410173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a0a5f5f707269766174653a3a566f69640003000075050c346672616d655f737570706f7274206469737061746368245261774f726967696e04244163636f756e7449640100010c10526f6f74000000185369676e656404000001244163636f756e744964000100104e6f6e65000200007905084470616c6c65745f636f6c6c656374697665245261774f726967696e08244163636f756e7449640100044900010c1c4d656d62657273080010012c4d656d626572436f756e74000010012c4d656d626572436f756e74000000184d656d62657204000001244163636f756e744964000100205f5068616e746f6d000200007d05083c70616c6c65745f657468657265756d245261774f726967696e0001044c457468657265756d5472616e73616374696f6e040091010110483136300000000081050c3c70616c6c65745f6d756c74697369671870616c6c65741043616c6c0404540001105061735f6d756c74695f7468726573686f6c645f310801446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000305101496d6d6564696174656c792064697370617463682061206d756c74692d7369676e61747572652063616c6c207573696e6720612073696e676c6520617070726f76616c2066726f6d207468652063616c6c65722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e003d012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f206172652070617274206f662074686501016d756c74692d7369676e61747572652c2062757420646f206e6f7420706172746963697061746520696e2074686520617070726f76616c2070726f636573732e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e00b8526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c742e0034232320436f6d706c657869747919014f285a202b204329207768657265205a20697320746865206c656e677468206f66207468652063616c6c20616e6420432069747320657865637574696f6e207765696768742e2061735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74850501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0001286d61785f77656967687428011857656967687400019c5501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e00b049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e001d014e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f20757365190160617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e005901526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f746865727769736555016f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642cdc6d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e0034232320436f6d706c6578697479502d20604f2853202b205a202b2043616c6c29602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e21012d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e6c2d2054686520776569676874206f6620746865206063616c6c602e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e40617070726f76655f61735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74850501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00012463616c6c5f686173680401205b75383b2033325d0001286d61785f7765696768742801185765696768740002785501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0035014e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e3c63616e63656c5f61735f6d756c74691001247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e00012463616c6c5f686173680401205b75383b2033325d000354550143616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c79c4666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e5d012d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c787472616e73616374696f6e20666f7220746869732064697370617463682ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e302d204f6e65206576656e742e842d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e702d2053746f726167653a2072656d6f766573206f6e65206974656d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e850504184f7074696f6e0404540189010108104e6f6e6500000010536f6d6504008901000001000089050c3c70616c6c65745f657468657265756d1870616c6c65741043616c6c040454000104207472616e7361637404012c7472616e73616374696f6e8d05012c5472616e73616374696f6e000004845472616e7361637420616e20457468657265756d207472616e73616374696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d050c20657468657265756d2c7472616e73616374696f6e345472616e73616374696f6e563200010c184c65676163790400910501444c65676163795472616e73616374696f6e0000001c454950323933300400a1050148454950323933305472616e73616374696f6e0001001c454950313535390400ad050148454950313535395472616e73616374696f6e0002000091050c20657468657265756d2c7472616e73616374696f6e444c65676163795472616e73616374696f6e00001c01146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e70757438011442797465730001247369676e6174757265990501505472616e73616374696f6e5369676e6174757265000095050c20657468657265756d2c7472616e73616374696f6e445472616e73616374696f6e416374696f6e0001081043616c6c04009101011048313630000000184372656174650001000099050c20657468657265756d2c7472616e73616374696f6e505472616e73616374696f6e5369676e617475726500000c0104769d0501545472616e73616374696f6e5265636f7665727949640001047234011048323536000104733401104832353600009d050c20657468657265756d2c7472616e73616374696f6e545472616e73616374696f6e5265636f7665727949640000040030010c7536340000a1050c20657468657265756d2c7472616e73616374696f6e48454950323933305472616e73616374696f6e00002c0120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a50501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000a505000002a90500a9050c20657468657265756d2c7472616e73616374696f6e384163636573734c6973744974656d000008011c616464726573739101011c4164647265737300013073746f726167655f6b657973c10101245665633c483235363e0000ad050c20657468657265756d2c7472616e73616374696f6e48454950313535395472616e73616374696f6e0000300120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173c90101105532353600013c6d61785f6665655f7065725f676173c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a50501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000b1050c2870616c6c65745f65766d1870616c6c65741043616c6c04045400011020776974686472617708011c61646472657373910101104831363000011476616c756518013042616c616e63654f663c543e000004e057697468647261772062616c616e63652066726f6d2045564d20696e746f2063757272656e63792f62616c616e6365732070616c6c65742e1063616c6c240118736f7572636591010110483136300001187461726765749101011048313630000114696e70757438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0001045d01497373756520616e2045564d2063616c6c206f7065726174696f6e2e20546869732069732073696d696c617220746f2061206d6573736167652063616c6c207472616e73616374696f6e20696e20457468657265756d2e18637265617465200118736f757263659101011048313630000110696e697438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0002085101497373756520616e2045564d20637265617465206f7065726174696f6e2e20546869732069732073696d696c617220746f206120636f6e7472616374206372656174696f6e207472616e73616374696f6e20696e24457468657265756d2e1c63726561746532240118736f757263659101011048313630000110696e697438011c5665633c75383e00011073616c743401104832353600011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0003047c497373756520616e2045564d2063726561746532206f7065726174696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb50504184f7074696f6e04045401c9010108104e6f6e6500000010536f6d650400c9010000010000b905000002bd0500bd05000004089101c10100c1050c4870616c6c65745f64796e616d69635f6665651870616c6c65741043616c6c040454000104646e6f74655f6d696e5f6761735f70726963655f746172676574040118746172676574c901011055323536000000040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5050c3c70616c6c65745f626173655f6665651870616c6c65741043616c6c040454000108507365745f626173655f6665655f7065725f67617304010c666565c901011055323536000000387365745f656c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000100040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec9050c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c65741043616c6c04045400010478686f746669785f696e635f6163636f756e745f73756666696369656e7473040124616464726573736573cd0501245665633c483136303e0000100502496e6372656d656e74206073756666696369656e74736020666f72206578697374696e67206163636f756e747320686176696e672061206e6f6e7a65726f20606e6f6e63656020627574207a65726f206073756666696369656e7473602c2060636f6e73756d6572736020616e64206070726f766964657273602076616c75652e2d0154686973207374617465207761732063617573656420627920612070726576696f75732062756720696e2045564d20637265617465206163636f756e7420646973706174636861626c652e006501416e79206163636f756e747320696e2074686520696e707574206c697374206e6f742073617469736679696e67207468652061626f766520636f6e646974696f6e2077696c6c2072656d61696e20756e61666665637465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ecd05000002910100d1050c5470616c6c65745f61697264726f705f636c61696d731870616c6c65741043616c6c04045400011814636c61696d0c011064657374d50501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d50501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d90501544d756c7469416464726573735369676e6174757265000060904d616b65206120636c61696d20746f20636f6c6c65637420796f757220746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a0501412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653a943e2028636f6e666967757265642070726566697820737472696e672928616464726573732900a4616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732ee057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d696e745f636c61696d10010c77686fd90101304d756c74694164647265737300011476616c756518013042616c616e63654f663c543e00014076657374696e675f7363686564756c65e5050179014f7074696f6e3c426f756e6465645665633c0a2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e292c20543a3a0a4d617856657374696e675363686564756c65733e2c3e00012473746174656d656e74f50501544f7074696f6e3c53746174656d656e744b696e643e00013ca84d696e742061206e657720636c61696d20746f20636f6c6c656374206e617469766520746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e002c506172616d65746572733af02d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2ef02d206076616c7565603a20546865206e756d626572206f66206e617469766520746f6b656e7320746861742077696c6c20626520636c61696d65642e2d012d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f72207468657365206e617469766520746f6b656e732e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e1d01576520617373756d6520776f7273742063617365207468617420626f74682076657374696e6720616e642073746174656d656e74206973206265696e6720696e7365727465642e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e30636c61696d5f61747465737410011064657374d50501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d50501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d90501544d756c7469416464726573735369676e617475726500012473746174656d656e7438011c5665633c75383e00026c09014d616b65206120636c61696d20746f20636f6c6c65637420796f7572206e617469766520746f6b656e73206279207369676e696e6720612073746174656d656e742e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a2901412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653ac03e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e7429004901616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973c06578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e39012d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e207468653020207369676e61747572652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732efc57656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d5f617474657374602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d6f76655f636c61696d08010c6f6c64d90101304d756c74694164647265737300010c6e6577d90101304d756c7469416464726573730004005c666f7263655f7365745f6578706972795f636f6e6669670801306578706972795f626c6f636b300144426c6f636b4e756d626572466f723c543e00011064657374d90101304d756c74694164647265737300050878536574207468652076616c756520666f7220657870697279636f6e6669678443616e206f6e6c792062652063616c6c656420627920466f7263654f726967696e30636c61696d5f7369676e656404011064657374d50501504f7074696f6e3c4d756c7469416464726573733e00060460436c61696d2066726f6d207369676e6564206f726967696e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed50504184f7074696f6e04045401d9010108104e6f6e6500000010536f6d650400d9010000010000d9050c5470616c6c65745f61697264726f705f636c61696d73147574696c73544d756c7469416464726573735369676e61747572650001080c45564d0400dd05013845636473615369676e6174757265000000184e61746976650400e1050140537232353531395369676e617475726500010000dd05105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733845636473615369676e617475726500000400650501205b75383b2036355d0000e1050c5470616c6c65745f61697264726f705f636c61696d73147574696c7340537232353531395369676e617475726500000400090301245369676e61747572650000e50504184f7074696f6e04045401e9050108104e6f6e6500000010536f6d650400e9050000010000e9050c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ed05045300000400f10501185665633c543e0000ed050000040c18183000f105000002ed0500f50504184f7074696f6e04045401f9050108104e6f6e6500000010536f6d650400f9050000010000f905085470616c6c65745f61697264726f705f636c61696d733453746174656d656e744b696e640001081c526567756c6172000000105361666500010000fd050c3070616c6c65745f70726f78791870616c6c65741043616c6c0404540001281470726f78790c01107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065010601504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000244d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f726973656420666f72207468726f75676830606164645f70726f7879602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e246164645f70726f78790c012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e0001244501526567697374657220612070726f7879206163636f756e7420666f72207468652073656e64657220746861742069732061626c6520746f206d616b652063616c6c73206f6e2069747320626568616c662e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a11012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f206d616b6520612070726f78792efc2d206070726f78795f74797065603a20546865207065726d697373696f6e7320616c6c6f77656420666f7220746869732070726f7879206163636f756e742e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e3072656d6f76655f70726f78790c012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00021ca8556e726567697374657220612070726f7879206163636f756e7420666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a25012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f2072656d6f766520617320612070726f78792e41012d206070726f78795f74797065603a20546865207065726d697373696f6e732063757272656e746c7920656e61626c656420666f72207468652072656d6f7665642070726f7879206163636f756e742e3872656d6f76655f70726f78696573000318b4556e726567697374657220616c6c2070726f7879206163636f756e747320666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0041015741524e494e473a2054686973206d61792062652063616c6c6564206f6e206163636f756e74732063726561746564206279206070757265602c20686f776576657220696620646f6e652c207468656e590174686520756e726573657276656420666565732077696c6c20626520696e61636365737369626c652e202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a2c6372656174655f707572650c012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e000114696e646578e901010c7531360004483901537061776e2061206672657368206e6577206163636f756e7420746861742069732067756172616e7465656420746f206265206f746865727769736520696e61636365737369626c652c20616e64fc696e697469616c697a65206974207769746820612070726f7879206f66206070726f78795f747970656020666f7220606f726967696e602073656e6465722e006c5265717569726573206120605369676e656460206f726967696e2e0051012d206070726f78795f74797065603a205468652074797065206f66207468652070726f78792074686174207468652073656e6465722077696c6c2062652072656769737465726564206173206f766572207468654d016e6577206163636f756e742e20546869732077696c6c20616c6d6f737420616c7761797320626520746865206d6f7374207065726d697373697665206050726f7879547970656020706f737369626c6520746f78616c6c6f7720666f72206d6178696d756d20666c65786962696c6974792e51012d2060696e646578603a204120646973616d626967756174696f6e20696e6465782c20696e206361736520746869732069732063616c6c6564206d756c7469706c652074696d657320696e207468652073616d655d017472616e73616374696f6e2028652e672e207769746820607574696c6974793a3a626174636860292e20556e6c65737320796f75277265207573696e67206062617463686020796f752070726f6261626c79206a7573744077616e7420746f20757365206030602e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e0051014661696c73207769746820604475706c69636174656020696620746869732068617320616c7265616479206265656e2063616c6c656420696e2074686973207472616e73616374696f6e2c2066726f6d207468659873616d652073656e6465722c2077697468207468652073616d6520706172616d65746572732e00e44661696c732069662074686572652061726520696e73756666696369656e742066756e647320746f2070617920666f72206465706f7369742e246b696c6c5f7075726514011c737061776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f787954797065000114696e646578e901010c7531360001186865696768742c0144426c6f636b4e756d626572466f723c543e0001246578745f696e6465786502010c753332000540a052656d6f76657320612070726576696f75736c7920737061776e656420707572652070726f78792e0049015741524e494e473a202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20416e792066756e64732068656c6420696e2069742077696c6c20626534696e61636365737369626c652e0059015265717569726573206120605369676e656460206f726967696e2c20616e64207468652073656e646572206163636f756e74206d7573742068617665206265656e206372656174656420627920612063616c6c20746f94607075726560207769746820636f72726573706f6e64696e6720706172616d65746572732e0039012d2060737061776e6572603a20546865206163636f756e742074686174206f726967696e616c6c792063616c6c65642060707572656020746f206372656174652074686973206163636f756e742e39012d2060696e646578603a2054686520646973616d626967756174696f6e20696e646578206f726967696e616c6c792070617373656420746f206070757265602e2050726f6261626c79206030602eec2d206070726f78795f74797065603a205468652070726f78792074797065206f726967696e616c6c792070617373656420746f206070757265602e29012d2060686569676874603a2054686520686569676874206f662074686520636861696e207768656e207468652063616c6c20746f20607075726560207761732070726f6365737365642e35012d20606578745f696e646578603a205468652065787472696e73696320696e64657820696e207768696368207468652063616c6c20746f20607075726560207761732070726f6365737365642e0035014661696c73207769746820604e6f5065726d697373696f6e6020696e2063617365207468652063616c6c6572206973206e6f7420612070726576696f75736c7920637265617465642070757265dc6163636f756e742077686f7365206070757265602063616c6c2068617320636f72726573706f6e64696e6720706172616d65746572732e20616e6e6f756e63650801107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e00063c05015075626c697368207468652068617368206f6620612070726f78792d63616c6c20746861742077696c6c206265206d61646520696e20746865206675747572652e005d0154686973206d7573742062652063616c6c656420736f6d65206e756d626572206f6620626c6f636b73206265666f72652074686520636f72726573706f6e64696e67206070726f78796020697320617474656d7074656425016966207468652064656c6179206173736f6369617465642077697468207468652070726f78792072656c6174696f6e736869702069732067726561746572207468616e207a65726f2e0011014e6f206d6f7265207468616e20604d617850656e64696e676020616e6e6f756e63656d656e7473206d6179206265206d61646520617420616e79206f6e652074696d652e000901546869732077696c6c2074616b652061206465706f736974206f662060416e6e6f756e63656d656e744465706f736974466163746f72602061732077656c6c206173190160416e6e6f756e63656d656e744465706f736974426173656020696620746865726520617265206e6f206f746865722070656e64696e6720616e6e6f756e63656d656e74732e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420612070726f7879206f6620607265616c602e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656d6f76655f616e6e6f756e63656d656e740801107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e0007287052656d6f7665206120676976656e20616e6e6f756e63656d656e742e0059014d61792062652063616c6c656420627920612070726f7879206163636f756e7420746f2072656d6f766520612063616c6c20746865792070726576696f75736c7920616e6e6f756e63656420616e642072657475726e30746865206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656a6563745f616e6e6f756e63656d656e7408012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e000828b052656d6f76652074686520676976656e20616e6e6f756e63656d656e74206f6620612064656c65676174652e0061014d61792062652063616c6c6564206279206120746172676574202870726f7869656429206163636f756e7420746f2072656d6f766520612063616c6c2074686174206f6e65206f662074686569722064656c6567617465732501286064656c656761746560292068617320616e6e6f756e63656420746865792077616e7420746f20657865637574652e20546865206465706f7369742069732072657475726e65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733af42d206064656c6567617465603a20546865206163636f756e7420746861742070726576696f75736c7920616e6e6f756e636564207468652063616c6c2ebc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652e3c70726f78795f616e6e6f756e63656410012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e0001107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065010601504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00092c4d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f72697a656420666f72207468726f75676830606164645f70726f7879602e00a852656d6f76657320616e7920636f72726573706f6e64696e6720616e6e6f756e63656d656e742873292e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e010604184f7074696f6e04045401e5010108104e6f6e6500000010536f6d650400e501000001000005060c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c65741043616c6c04045400015c386a6f696e5f6f70657261746f727304012c626f6e645f616d6f756e7418013042616c616e63654f663c543e000004f8416c6c6f777320616e206163636f756e7420746f206a6f696e20617320616e206f70657261746f722062792070726f766964696e672061207374616b652e607363686564756c655f6c656176655f6f70657261746f72730001047c5363686564756c657320616e206f70657261746f7220746f206c656176652e5863616e63656c5f6c656176655f6f70657261746f7273000204a843616e63656c732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e5c657865637574655f6c656176655f6f70657261746f7273000304ac45786563757465732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e486f70657261746f725f626f6e645f6d6f726504013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e000404ac416c6c6f777320616e206f70657261746f7220746f20696e637265617365207468656972207374616b652e647363686564756c655f6f70657261746f725f756e7374616b65040138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504b85363686564756c657320616e206f70657261746f7220746f206465637265617365207468656972207374616b652e60657865637574655f6f70657261746f725f756e7374616b65000604d045786563757465732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e5c63616e63656c5f6f70657261746f725f756e7374616b65000704cc43616e63656c732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e28676f5f6f66666c696e6500080484416c6c6f777320616e206f70657261746f7220746f20676f206f66666c696e652e24676f5f6f6e6c696e6500090480416c6c6f777320616e206f70657261746f7220746f20676f206f6e6c696e652e1c6465706f7369740c012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00012c65766d5f61646472657373090601304f7074696f6e3c483136303e000a0488416c6c6f77732061207573657220746f206465706f73697420616e2061737365742e447363686564756c655f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000b04785363686564756c657320616e20776974686472617720726571756573742e40657865637574655f776974686472617704012c65766d5f61646472657373090601304f7074696f6e3c483136303e000c049845786563757465732061207363686564756c656420776974686472617720726571756573742e3c63616e63656c5f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000d049443616e63656c732061207363686564756c656420776974686472617720726571756573742e2064656c65676174651001206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00014c626c75657072696e745f73656c656374696f6e0d0601d844656c656761746f72426c75657072696e7453656c656374696f6e3c543a3a4d617844656c656761746f72426c75657072696e74733e000e04fc416c6c6f77732061207573657220746f2064656c656761746520616e20616d6f756e74206f6620616e20617373657420746f20616e206f70657261746f722e687363686564756c655f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000f04c85363686564756c65732061207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e64657865637574655f64656c656761746f725f756e7374616b65001004ec45786563757465732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e6063616e63656c5f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e001104e843616e63656c732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e647365745f696e63656e746976655f6170795f616e645f6361700c01207661756c745f6964180128543a3a5661756c74496400010c617079f501014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e001218a853657473207468652041505920616e642063617020666f7220612073706563696669632061737365742e0101546865204150592069732074686520616e6e75616c2070657263656e74616765207969656c642074686174207468652061737365742077696c6c206561726e2e5901546865206361702069732074686520616d6f756e74206f662061737365747320726571756972656420746f206265206465706f736974656420746f20646973747269627574652074686520656e74697265204150592e110154686520415059206973206361707065642061742031302520616e642077696c6c20726571756972652072756e74696d65207570677261646520746f206368616e67652e0055015768696c652074686520636170206973206e6f74206d65742c20746865204150592064697374726962757465642077696c6c2062652060616d6f756e745f6465706f7369746564202f20636170202a20415059602e7c77686974656c6973745f626c75657072696e745f666f725f72657761726473040130626c75657072696e745f696410010c7533320013048c57686974656c69737473206120626c75657072696e7420666f7220726577617264732e546d616e6167655f61737365745f696e5f7661756c740c01207661756c745f6964180128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6ef901012c4173736574416374696f6e001404804d616e61676520617373657420696420746f207661756c742072657761726473406164645f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001604bc41646473206120626c75657072696e7420494420746f20612064656c656761746f7227732073656c656374696f6e2e4c72656d6f76655f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001704d052656d6f766573206120626c75657072696e742049442066726f6d20612064656c656761746f7227732073656c656374696f6e2e04c85468652063616c6c61626c652066756e6374696f6e73202865787472696e7369637329206f66207468652070616c6c65742e090604184f7074696f6e0404540191010108104e6f6e6500000010536f6d650400910100000100000d06107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f726c44656c656761746f72426c75657072696e7453656c656374696f6e04344d6178426c75657072696e74730111060108144669786564040015060198426f756e6465645665633c426c75657072696e7449642c204d6178426c75657072696e74733e0000000c416c6c000100001106085874616e676c655f746573746e65745f72756e74696d65584d617844656c656761746f72426c75657072696e74730000000015060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540130045300000400190601185665633c543e0000190600000230001d060c3c70616c6c65745f7365727669636573186d6f64756c651043616c6c040454000138406372656174655f626c75657072696e74040124626c75657072696e742106018053657276696365426c75657072696e743c543a3a436f6e73747261696e74733e0000207c4372656174652061206e6577207365727669636520626c75657072696e742e00590141205365727669636520426c75657072696e7420697320612074656d706c61746520666f722061207365727669636520746861742063616e20626520696e7374616e746961746564206c61746572206f6e206279206114757365722e00302320506172616d6574657273fc2d20606f726967696e603a20546865206163636f756e742074686174206973206372656174696e6720746865207365727669636520626c75657072696e742eb02d2060626c75657072696e74603a2054686520626c75657072696e74206f662074686520736572766963652e307072655f7265676973746572040130626c75657072696e745f69642c010c75363400012401015072652d7265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e005d015468652063616c6c65722063616e207072652d726567697374657220666f72206120626c75657072696e742c2077686963682077696c6c20656d697420612060507265526567697374726174696f6e60206576656e742e510154686973206576656e742063616e206265206c697374656e656420746f20627920746865206f70657261746f72206e6f646520746f20657865637574652074686520637573746f6d20626c75657072696e74277358726567697374726174696f6e2066756e6374696f6e2e00302320506172616d657465727329012d20606f726967696e603a20546865206163636f756e742074686174206973207072652d7265676973746572696e6720666f7220746865207365727669636520626c75657072696e742ec82d2060626c75657072696e745f6964603a20546865204944206f6620746865207365727669636520626c75657072696e742e207265676973746572100130626c75657072696e745f69642c010c75363400012c707265666572656e6365730102014c4f70657261746f72507265666572656e636573000144726567697374726174696f6e5f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e00011476616c75656d01013042616c616e63654f663c543e000210f05265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e0059015468652063616c6c6572206d6179207265717569726520616e20617070726f76616c206669727374206265666f726520746865792063616e2061636365707420746f2070726f7669646520746865207365727669636538666f72207468652075736572732e28756e7265676973746572040130626c75657072696e745f69642c010c7536340003141901556e7265676973746572207468652063616c6c65722066726f6d206265696e6720616e206f70657261746f7220666f7220746865207365727669636520626c75657072696e744901736f20746861742c206e6f206d6f72652073657276696365732077696c6c2061737369676e656420746f207468652063616c6c657220666f72207468697320737065636966696320626c75657072696e742e39014e6f746520746861742c207468652063616c6c6572206e6565647320746f206b6565702070726f766964696e67207365727669636520666f72206f746865722061637469766520736572766963656101746861742075736573207468697320626c75657072696e742c20756e74696c2074686520656e64206f6620736572766963652074696d652c206f74686572776973652074686579206d617920676574207265706f7274656430616e6420736c61736865642e507570646174655f70726963655f74617267657473080130626c75657072696e745f69642c010c75363400013470726963655f746172676574730902013050726963655461726765747300040c250155706461746520746865207072696365207461726765747320666f72207468652063616c6c657220666f722061207370656369666963207365727669636520626c75657072696e742e00b0536565205b6053656c663a3a7265676973746572605d20666f72206d6f726520696e666f726d6174696f6e2e1c7265717565737424012865766d5f6f726967696e090601304f7074696f6e3c483136303e000130626c75657072696e745f69642c010c7536340001447065726d69747465645f63616c6c6572733d0201445665633c543a3a4163636f756e7449643e0001246f70657261746f72733d0201445665633c543a3a4163636f756e7449643e000130726571756573745f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0001186173736574734102013c5665633c543a3a417373657449643e00010c74746c2c0144426c6f636b4e756d626572466f723c543e0001347061796d656e745f6173736574f101014441737365743c543a3a417373657449643e00011476616c75656d01013042616c616e63654f663c543e00050c4501526571756573742061206e6577207365727669636520746f20626520696e69746961746564207573696e67207468652070726f766964656420626c75657072696e7420776974682061206c697374206f6651016f70657261746f727320746861742077696c6c2072756e20796f757220736572766963652e204f7074696f6e616c6c792c20796f752063616e20637573746f6d697a652077686f206973207065726d6974746564490163616c6c6572206f66207468697320736572766963652c2062792064656661756c74206f6e6c79207468652063616c6c657220697320616c6c6f77656420746f2063616c6c2074686520736572766963652e1c617070726f7665080128726571756573745f69642c010c75363400014472657374616b696e675f70657263656e74e506011c50657263656e740006100101417070726f76652061207365727669636520726571756573742c20736f20746861742074686520736572766963652063616e20626520696e697469617465642e006101546865206072657374616b696e675f70657263656e7460206973207468652070657263656e74616765206f66207468652072657374616b656420746f6b656e7320746861742077696c6c206265206578706f73656420746f3074686520736572766963652e1872656a656374040128726571756573745f69642c010c75363400070c6452656a6563742061207365727669636520726571756573742e510154686520736572766963652077696c6c206e6f7420626520696e697469617465642c20616e6420746865207265717565737465722077696c6c206e65656420746f2075706461746520746865207365727669636520726571756573742e247465726d696e617465040128736572766963655f69642c010c753634000804cc5465726d696e6174657320746865207365727669636520627920746865206f776e6572206f662074686520736572766963652e1063616c6c0c0128736572766963655f69642c010c75363400010c6a6f62e90601087538000110617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0009086843616c6c2061204a6f6220696e2074686520736572766963652e1d015468652063616c6c6572206e6565647320746f20626520746865206f776e6572206f662074686520736572766963652c206f722061207065726d69747465642063616c6c65722e347375626d69745f726573756c740c0128736572766963655f69642c010c75363400011c63616c6c5f69642c010c753634000118726573756c740d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000a04e85375626d697420746865206a6f6220726573756c74206279207573696e6720746865207365727669636520494420616e642063616c6c2049442e14736c6173680c01206f6666656e646572000130543a3a4163636f756e744964000128736572766963655f69642c010c75363400011c70657263656e74e506011c50657263656e74000b184d01536c61736820616e206f70657261746f7220286f6666656e6465722920666f72206120736572766963652069642077697468206120676976656e2070657263656e74206f66207468656972206578706f7365645c7374616b6520666f72207468617420736572766963652e000d015468652063616c6c6572206e6565647320746f20626520616e20617574686f72697a656420536c617368204f726967696e20666f72207468697320736572766963652e5d014e6f74652074686174207468697320646f6573206e6f74206170706c792074686520736c617368206469726563746c792c2062757420696e7374656164207363686564756c657320612064656665727265642063616c6c94746f206170706c792074686520736c61736820627920616e6f7468657220656e746974792e1c6469737075746508010c6572616502010c753332000114696e6465786502010c753332000c10d84469737075746520616e205b556e6170706c696564536c6173685d20666f72206120676976656e2065726120616e6420696e6465782e0029015468652063616c6c6572206e6565647320746f20626520616e20617574686f72697a65642044697370757465204f726967696e20666f7220746865207365727669636520696e20746865445b556e6170706c696564536c6173685d2e9c7570646174655f6d61737465725f626c75657072696e745f736572766963655f6d616e6167657204011c616464726573739101011048313630000d0c1501416464732061206e6577204d617374657220426c75657072696e742053657276696365204d616e6167657220746f20746865206c697374206f66207265766973696f6e732e0051015468652063616c6c6572206e6565647320746f20626520616e20617574686f72697a6564204d617374657220426c75657072696e742053657276696365204d616e6167657220557064617465204f726967696e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e21060c4474616e676c655f7072696d6974697665732073657276696365734053657276696365426c75657072696e7404044300001c01206d6574616461746125060148536572766963654d657461646174613c433e0001106a6f6273350601c8426f756e6465645665633c4a6f62446566696e6974696f6e3c433e2c20433a3a4d61784a6f6273506572536572766963653e00014c726567697374726174696f6e5f706172616d734106018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000138726571756573745f706172616d734106018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e00011c6d616e616765725d06015c426c75657072696e74536572766963654d616e6167657200015c6d61737465725f6d616e616765725f7265766973696f6e610601944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000118676164676574650601244761646765743c433e000025060c4474616e676c655f7072696d6974697665732073657276696365733c536572766963654d6574616461746104044300002001106e616d652906018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000118617574686f72310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00012063617465676f7279310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00013c636f64655f7265706f7369746f7279310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e0001106c6f676f310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c77656273697465310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c6c6963656e7365310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00002906104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e67040453000004002d060144426f756e6465645665633c75382c20533e00002d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000310604184f7074696f6e0404540129060108104e6f6e6500000010536f6d6504002906000001000035060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013906045300000400590601185665633c543e000039060c4474616e676c655f7072696d697469766573207365727669636573344a6f62446566696e6974696f6e04044300000c01206d657461646174613d0601384a6f624d657461646174613c433e000118706172616d734106018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000118726573756c744106018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e00003d060c4474616e676c655f7072696d6974697665732073657276696365732c4a6f624d6574616461746104044300000801106e616d652906018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e310601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000041060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014506045300000400550601185665633c543e00004506104474616e676c655f7072696d697469766573207365727669636573146669656c64244669656c645479706500014410566f696400000010426f6f6c0001001455696e743800020010496e74380003001855696e74313600040014496e7431360005001855696e74333200060014496e7433320007001855696e74363400080014496e74363400090018537472696e67000a00144279746573000b00204f7074696f6e616c040045060138426f783c4669656c64547970653e000c00144172726179080030010c753634000045060138426f783c4669656c64547970653e000d00104c697374040045060138426f783c4669656c64547970653e000e0018537472756374080045060138426f783c4669656c64547970653e0000490601e8426f756e6465645665633c28426f783c4669656c64547970653e2c20426f783c4669656c64547970653e292c20436f6e73745533323c33323e3e000f00244163636f756e7449640064000049060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014d06045300000400510601185665633c543e00004d0600000408450645060051060000024d0600550600000245060059060000023906005d060c4474616e676c655f7072696d6974697665732073657276696365735c426c75657072696e74536572766963654d616e616765720001040c45766d04009101013473705f636f72653a3a483136300000000061060c4474616e676c655f7072696d697469766573207365727669636573944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000108184c6174657374000000205370656369666963040010010c7533320001000065060c4474616e676c655f7072696d6974697665732073657276696365731847616467657404044300010c105761736d0400690601345761736d4761646765743c433e000000184e61746976650400dd06013c4e61746976654761646765743c433e00010024436f6e7461696e65720400e1060148436f6e7461696e65724761646765743c433e0002000069060c4474616e676c655f7072696d697469766573207365727669636573285761736d476164676574040443000008011c72756e74696d656d06012c5761736d52756e74696d6500011c736f7572636573710601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e00006d060c4474616e676c655f7072696d6974697665732073657276696365732c5761736d52756e74696d65000108205761736d74696d65000000185761736d65720001000071060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017506045300000400d90601185665633c543e000075060c4474616e676c655f7072696d69746976657320736572766963657330476164676574536f75726365040443000004011c6665746368657279060158476164676574536f75726365466574636865723c433e000079060c4474616e676c655f7072696d6974697665732073657276696365734c476164676574536f7572636546657463686572040443000110104950465304007d060190426f756e6465645665633c75382c20433a3a4d617849706673486173684c656e6774683e00000018476974687562040081060140476974687562466574636865723c433e00010038436f6e7461696e6572496d6167650400b906015c496d6167655265676973747279466574636865723c433e0002001c54657374696e670400d506013854657374466574636865723c433e000300007d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000081060c4474616e676c655f7072696d697469766573207365727669636573344769746875624665746368657204044300001001146f776e65728506018c426f756e646564537472696e673c433a3a4d61784769744f776e65724c656e6774683e0001107265706f8d060188426f756e646564537472696e673c433a3a4d61784769745265706f4c656e6774683e00010c74616795060184426f756e646564537472696e673c433a3a4d61784769745461674c656e6774683e00012062696e61726965739d0601d0426f756e6465645665633c47616467657442696e6172793c433e2c20433a3a4d617842696e61726965735065724761646765743e00008506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040089060144426f756e6465645665633c75382c20533e000089060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00008d06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040091060144426f756e6465645665633c75382c20533e000091060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00009506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040099060144426f756e6465645665633c75382c20533e000099060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00009d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401a106045300000400b50601185665633c543e0000a1060c4474616e676c655f7072696d6974697665732073657276696365733047616467657442696e617279040443000010011061726368a50601304172636869746563747572650001086f73a906013c4f7065726174696e6753797374656d0001106e616d65ad060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e0001187368613235360401205b75383b2033325d0000a5060c4474616e676c655f7072696d69746976657320736572766963657330417263686974656374757265000128105761736d000000185761736d36340001001057617369000200185761736936340003000c416d6400040014416d6436340005000c41726d0006001441726d36340007001452697363560008001c5269736356363400090000a9060c4474616e676c655f7072696d6974697665732073657276696365733c4f7065726174696e6753797374656d0001141c556e6b6e6f776e000000144c696e75780001001c57696e646f7773000200144d61634f530003000c42534400040000ad06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400b1060144426f756e6465645665633c75382c20533e0000b1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000b506000002a10600b9060c4474616e676c655f7072696d69746976657320736572766963657350496d61676552656769737472794665746368657204044300000c01207265676973747279bd0601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e657252656769737472794c656e6774683e000114696d616765c50601b4426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167654e616d654c656e6774683e00010c746167cd0601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167655461674c656e6774683e0000bd06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c1060144426f756e6465645665633c75382c20533e0000c1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000c506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c9060144426f756e6465645665633c75382c20533e0000c9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000cd06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400d1060144426f756e6465645665633c75382c20533e0000d1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000d5060c4474616e676c655f7072696d6974697665732073657276696365732c546573744665746368657204044300000c0134636172676f5f7061636b616765ad060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124636172676f5f62696ead060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124626173655f706174682906018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e0000d906000002750600dd060c4474616e676c655f7072696d697469766573207365727669636573304e6174697665476164676574040443000004011c736f7572636573710601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000e1060c4474616e676c655f7072696d6974697665732073657276696365733c436f6e7461696e6572476164676574040443000004011c736f7572636573710601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000e506000006f50100e9060000060800ed060c4470616c6c65745f74616e676c655f6c73741870616c6c65741043616c6c040454000150106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002045015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f74650041012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726108011c706f6f6c5f6964100118506f6f6c49640001146578747261f106015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e18756e626f6e640c01386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640c01386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c75333200054c5501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500ec4966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e18637265617465180118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e0001106e616d65f50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6efd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f69641c0118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001106e616d65f50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6efd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f72733d0201445665633c543a3a4163636f756e7449643e00081c7c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e247365745f737461746508011c706f6f6c5f6964100118506f6f6c4964000114737461746549020124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731001346d696e5f6a6f696e5f626f6e6405070158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6405070158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7309070134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e0d070144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d75737420626514526f6f742e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f7411070158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f7211070158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e63657211070158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d1c704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720c01186d656d626572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001146578747261f106015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373416c6c60206f7220605065726d697373696f6e6c657373436f6d706f756e64602e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654d02019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6ccc69732061626c6520746f20636f6e6966696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef1060c4470616c6c65745f74616e676c655f6c737414747970657324426f6e644578747261041c42616c616e6365011801042c4672656542616c616e6365040018011c42616c616e636500000000f50604184f7074696f6e04045401f9060108104e6f6e6500000010536f6d650400f9060000010000f9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000fd0604184f7074696f6e0404540101070108104e6f6e6500000010536f6d6504000107000001000001070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000005070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f76650002000009070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200000d070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000011070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f76650002000015070c2c70616c6c65745f7375646f1870616c6c6574144572726f720404540001042c526571756972655375646f0000048053656e646572206d75737420626520746865205375646f206163636f756e742e04684572726f7220666f7220746865205375646f2070616c6c65742e19070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00001d070c3470616c6c65745f61737365747314747970657330417373657444657461696c730c1c42616c616e63650118244163636f756e7449640100384465706f73697442616c616e63650118003001146f776e65720001244163636f756e7449640001186973737565720001244163636f756e74496400011461646d696e0001244163636f756e74496400011c667265657a65720001244163636f756e744964000118737570706c7918011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500012c6d696e5f62616c616e636518011c42616c616e636500013469735f73756666696369656e74200110626f6f6c0001206163636f756e747310010c75333200012c73756666696369656e747310010c753332000124617070726f76616c7310010c7533320001187374617475732107012c4173736574537461747573000021070c3470616c6c65745f6173736574731474797065732c417373657453746174757300010c104c6976650000001846726f7a656e0001002844657374726f79696e670002000025070000040818000029070c3470616c6c65745f6173736574731474797065733041737365744163636f756e74101c42616c616e63650118384465706f73697442616c616e636501181445787472610184244163636f756e74496401000010011c62616c616e636518011c42616c616e63650001187374617475732d0701344163636f756e74537461747573000118726561736f6e310701a84578697374656e6365526561736f6e3c4465706f73697442616c616e63652c204163636f756e7449643e0001146578747261840114457874726100002d070c3470616c6c65745f617373657473147479706573344163636f756e7453746174757300010c184c69717569640000001846726f7a656e0001001c426c6f636b65640002000031070c3470616c6c65745f6173736574731474797065733c4578697374656e6365526561736f6e081c42616c616e63650118244163636f756e7449640100011420436f6e73756d65720000002853756666696369656e740001002c4465706f73697448656c64040018011c42616c616e63650002003c4465706f736974526566756e6465640003002c4465706f73697446726f6d08000001244163636f756e744964000018011c42616c616e63650004000035070000040c1800000039070c3470616c6c65745f61737365747314747970657320417070726f76616c081c42616c616e63650118384465706f73697442616c616e6365011800080118616d6f756e7418011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500003d070c3470616c6c65745f6173736574731474797065733441737365744d6574616461746108384465706f73697442616c616e6365011834426f756e646564537472696e670141070014011c6465706f7369741801384465706f73697442616c616e63650001106e616d6541070134426f756e646564537472696e6700011873796d626f6c41070134426f756e646564537472696e67000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000041070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000045070c3470616c6c65745f6173736574731870616c6c6574144572726f720804540004490001542842616c616e63654c6f7700000415014163636f756e742062616c616e6365206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865207472616e7366657220616d6f756e742e244e6f4163636f756e7400010490546865206163636f756e7420746f20616c74657220646f6573206e6f742065786973742e304e6f5065726d697373696f6e000204e8546865207369676e696e67206163636f756e7420686173206e6f207065726d697373696f6e20746f20646f20746865206f7065726174696f6e2e1c556e6b6e6f776e0003047854686520676976656e20617373657420494420697320756e6b6e6f776e2e1846726f7a656e00040474546865206f726967696e206163636f756e742069732066726f7a656e2e14496e5573650005047854686520617373657420494420697320616c72656164792074616b656e2e284261645769746e6573730006046c496e76616c6964207769746e657373206461746120676976656e2e384d696e42616c616e63655a65726f0007048c4d696e696d756d2062616c616e63652073686f756c64206265206e6f6e2d7a65726f2e4c556e617661696c61626c65436f6e73756d657200080c5901556e61626c6520746f20696e6372656d656e742074686520636f6e73756d6572207265666572656e636520636f756e74657273206f6e20746865206163636f756e742e20456974686572206e6f2070726f76696465724d017265666572656e63652065786973747320746f20616c6c6f772061206e6f6e2d7a65726f2062616c616e6365206f662061206e6f6e2d73656c662d73756666696369656e742061737365742c206f72206f6e65f06665776572207468656e20746865206d6178696d756d206e756d626572206f6620636f6e73756d65727320686173206265656e20726561636865642e2c4261644d657461646174610009045c496e76616c6964206d6574616461746120676976656e2e28556e617070726f766564000a04c44e6f20617070726f76616c20657869737473207468617420776f756c6420616c6c6f7720746865207472616e736665722e20576f756c64446965000b04350154686520736f75726365206163636f756e7420776f756c64206e6f74207375727669766520746865207472616e7366657220616e64206974206e6565647320746f207374617920616c6976652e34416c7265616479457869737473000c04845468652061737365742d6163636f756e7420616c7265616479206578697374732e244e6f4465706f736974000d04d45468652061737365742d6163636f756e7420646f65736e2774206861766520616e206173736f636961746564206465706f7369742e24576f756c644275726e000e04c4546865206f7065726174696f6e20776f756c6420726573756c7420696e2066756e6473206265696e67206275726e65642e244c6976654173736574000f0859015468652061737365742069732061206c69766520617373657420616e64206973206163746976656c79206265696e6720757365642e20557375616c6c7920656d697420666f72206f7065726174696f6e7320737563681d016173206073746172745f64657374726f796020776869636820726571756972652074686520617373657420746f20626520696e20612064657374726f79696e672073746174652e3041737365744e6f744c697665001004c8546865206173736574206973206e6f74206c6976652c20616e64206c696b656c79206265696e672064657374726f7965642e3c496e636f7272656374537461747573001104b054686520617373657420737461747573206973206e6f7420746865206578706563746564207374617475732e244e6f7446726f7a656e001204d85468652061737365742073686f756c642062652066726f7a656e206265666f72652074686520676976656e206f7065726174696f6e2e3843616c6c6261636b4661696c65640013048443616c6c6261636b20616374696f6e20726573756c74656420696e206572726f722842616441737365744964001404c8546865206173736574204944206d75737420626520657175616c20746f20746865205b604e65787441737365744964605d2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e49070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454014d07045300000400550701185665633c543e00004d070c3c70616c6c65745f62616c616e6365731474797065732c42616c616e63654c6f636b041c42616c616e63650118000c01086964a90201384c6f636b4964656e746966696572000118616d6f756e7418011c42616c616e636500011c726561736f6e735107011c526561736f6e73000051070c3c70616c6c65745f62616c616e6365731474797065731c526561736f6e7300010c0c466565000000104d6973630001000c416c6c0002000055070000024d070059070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454015d07045300000400610701185665633c543e00005d070c3c70616c6c65745f62616c616e6365731474797065732c52657365727665446174610844526573657276654964656e74696669657201a9021c42616c616e63650118000801086964a9020144526573657276654964656e746966696572000118616d6f756e7418011c42616c616e6365000061070000025d070065070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016907045300000400750701185665633c543e0000690714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e7408084964016d071c42616c616e636501180008010869646d0701084964000118616d6f756e7418011c42616c616e636500006d07085874616e676c655f746573746e65745f72756e74696d654452756e74696d65486f6c64526561736f6e00010420507265696d61676504007107016c70616c6c65745f707265696d6167653a3a486f6c64526561736f6e001a000071070c3c70616c6c65745f707265696d6167651870616c6c657428486f6c64526561736f6e00010420507265696d61676500000000750700000269070079070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017d070453000004008d0701185665633c543e00007d0714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e74080849640181071c42616c616e63650118000801086964810701084964000118616d6f756e7418011c42616c616e636500008107085874616e676c655f746573746e65745f72756e74696d654c52756e74696d65467265657a65526561736f6e0001083c4e6f6d696e6174696f6e506f6f6c7304008507019470616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a467265657a65526561736f6e0018000c4c737404008907017c70616c6c65745f74616e676c655f6c73743a3a467265657a65526561736f6e0034000085070c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e63650000000089070c4470616c6c65745f74616e676c655f6c73741870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e6365000000008d070000027d070091070c3c70616c6c65745f62616c616e6365731870616c6c6574144572726f720804540004490001303856657374696e6742616c616e63650000049c56657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75652e544c69717569646974795265737472696374696f6e73000104c84163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2e4c496e73756666696369656e7442616c616e63650002047842616c616e636520746f6f206c6f7720746f2073656e642076616c75652e484578697374656e7469616c4465706f736974000304ec56616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742e34457870656e646162696c697479000404905472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742e5c4578697374696e6756657374696e675363686564756c65000504cc412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e742e2c446561644163636f756e740006048c42656e6566696369617279206163636f756e74206d757374207072652d65786973742e3c546f6f4d616e795265736572766573000704b84e756d626572206f66206e616d65642072657365727665732065786365656420604d61785265736572766573602e30546f6f4d616e79486f6c6473000804f84e756d626572206f6620686f6c647320657863656564206056617269616e74436f756e744f663c543a3a52756e74696d65486f6c64526561736f6e3e602e38546f6f4d616e79467265657a6573000904984e756d626572206f6620667265657a65732065786365656420604d6178467265657a6573602e4c49737375616e63654465616374697661746564000a0401015468652069737375616e63652063616e6e6f74206265206d6f6469666965642073696e636520697420697320616c72656164792064656163746976617465642e2444656c74615a65726f000b04645468652064656c74612063616e6e6f74206265207a65726f2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e95070c3473705f61726974686d657469632c66697865645f706f696e7424466978656455313238000004001801107531323800009907086870616c6c65745f7472616e73616374696f6e5f7061796d656e742052656c6561736573000108245631416e6369656e74000000085632000100009d070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401a107045300000400a50701185665633c543e0000a10700000408d9023000a507000002a10700a9070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540104045300000400ad0701185665633c543e0000ad070000020400b10704184f7074696f6e04045401b5070108104e6f6e6500000010536f6d650400b5070000010000b5070c4473705f636f6e73656e7375735f626162651c646967657374732450726544696765737400010c1c5072696d6172790400b90701405072696d617279507265446967657374000100385365636f6e64617279506c61696e0400c107015c5365636f6e64617279506c61696e507265446967657374000200305365636f6e646172795652460400c50701545365636f6e6461727956524650726544696765737400030000b9070c4473705f636f6e73656e7375735f626162651c64696765737473405072696d61727950726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740001347672665f7369676e6174757265bd0701305672665369676e61747572650000bd07101c73705f636f72651c737232353531390c767266305672665369676e617475726500000801287072655f6f75747075740401305672665072654f757470757400011470726f6f660903012056726650726f6f660000c1070c4473705f636f6e73656e7375735f626162651c646967657374735c5365636f6e64617279506c61696e507265446967657374000008013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740000c5070c4473705f636f6e73656e7375735f626162651c64696765737473545365636f6e6461727956524650726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740001347672665f7369676e6174757265bd0701305672665369676e61747572650000c907084473705f636f6e73656e7375735f62616265584261626545706f6368436f6e66696775726174696f6e000008010463e9020128287536342c2075363429000134616c6c6f7765645f736c6f7473ed020130416c6c6f776564536c6f74730000cd070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540139010453000004005d0201185665633c543e0000d1070c2c70616c6c65745f626162651870616c6c6574144572726f7204045400011060496e76616c696445717569766f636174696f6e50726f6f660000043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c69644b65794f776e65727368697050726f6f66000104310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400020415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e50496e76616c6964436f6e66696775726174696f6e0003048c5375626d697474656420636f6e66696775726174696f6e20697320696e76616c69642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed507083870616c6c65745f6772616e6470612c53746f726564537461746504044e01300110104c6976650000003050656e64696e6750617573650801307363686564756c65645f61743001044e00011464656c61793001044e000100185061757365640002003450656e64696e67526573756d650801307363686564756c65645f61743001044e00011464656c61793001044e00030000d907083870616c6c65745f6772616e6470614c53746f72656450656e64696e674368616e676508044e0130144c696d697400001001307363686564756c65645f61743001044e00011464656c61793001044e0001406e6578745f617574686f726974696573dd07016c426f756e646564417574686f726974794c6973743c4c696d69743e000118666f726365647d0401244f7074696f6e3c4e3e0000dd070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401a4045300000400a001185665633c543e0000e1070c3870616c6c65745f6772616e6470611870616c6c6574144572726f7204045400011c2c50617573654661696c65640000080501417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665a42865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e30526573756d654661696c65640001081101417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e277420706175736564a028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e344368616e676550656e64696e67000204e8417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e1c546f6f536f6f6e000304bc43616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e60496e76616c69644b65794f776e65727368697050726f6f66000404310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c696445717569766f636174696f6e50726f6f660005043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400060415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee5070000040c00182000e9070c3870616c6c65745f696e64696365731870616c6c6574144572726f720404540001142c4e6f7441737369676e65640000048c54686520696e64657820776173206e6f7420616c72656164792061737369676e65642e204e6f744f776e6572000104a454686520696e6465782069732061737369676e656420746f20616e6f74686572206163636f756e742e14496e5573650002047054686520696e64657820776173206e6f7420617661696c61626c652e2c4e6f745472616e73666572000304c854686520736f7572636520616e642064657374696e6174696f6e206163636f756e747320617265206964656e746963616c2e245065726d616e656e74000404d054686520696e646578206973207065726d616e656e7420616e64206d6179206e6f742062652066726565642f6368616e6765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742eed070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401f107045300000400f50701185665633c543e0000f1070000040c1029030000f507000002f10700f9070000040859041800fd070c4070616c6c65745f64656d6f6372616379147479706573385265666572656e64756d496e666f0c2c426c6f636b4e756d62657201302050726f706f73616c0129031c42616c616e6365011801081c4f6e676f696e670400010801c05265666572656e64756d5374617475733c426c6f636b4e756d6265722c2050726f706f73616c2c2042616c616e63653e0000002046696e6973686564080120617070726f766564200110626f6f6c00010c656e6430012c426c6f636b4e756d6265720001000001080c4070616c6c65745f64656d6f6372616379147479706573405265666572656e64756d5374617475730c2c426c6f636b4e756d62657201302050726f706f73616c0129031c42616c616e636501180014010c656e6430012c426c6f636b4e756d62657200012070726f706f73616c2903012050726f706f73616c0001247468726573686f6c64b40134566f74655468726573686f6c6400011464656c617930012c426c6f636b4e756d62657200011474616c6c790508013854616c6c793c42616c616e63653e000005080c4070616c6c65745f64656d6f63726163791474797065731454616c6c79041c42616c616e63650118000c01106179657318011c42616c616e63650001106e61797318011c42616c616e636500011c7475726e6f757418011c42616c616e6365000009080c4070616c6c65745f64656d6f637261637910766f746518566f74696e67101c42616c616e63650118244163636f756e74496401002c426c6f636b4e756d6265720130204d6178566f746573000108184469726563740c0114766f7465730d0801f4426f756e6465645665633c285265666572656e64756d496e6465782c204163636f756e74566f74653c42616c616e63653e292c204d6178566f7465733e00012c64656c65676174696f6e731908015044656c65676174696f6e733c42616c616e63653e0001147072696f721d08017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0000002844656c65676174696e6714011c62616c616e636518011c42616c616e63650001187461726765740001244163636f756e744964000128636f6e76696374696f6e35030128436f6e76696374696f6e00012c64656c65676174696f6e731908015044656c65676174696f6e733c42616c616e63653e0001147072696f721d08017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e000100000d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454011108045300000400150801185665633c543e000011080000040810b800150800000211080019080c4070616c6c65745f64656d6f63726163791474797065732c44656c65676174696f6e73041c42616c616e6365011800080114766f74657318011c42616c616e636500011c6361706974616c18011c42616c616e636500001d080c4070616c6c65745f64656d6f637261637910766f7465245072696f724c6f636b082c426c6f636b4e756d62657201301c42616c616e6365011800080030012c426c6f636b4e756d626572000018011c42616c616e636500002108000004082903b4002508000004083059040029080c4070616c6c65745f64656d6f63726163791870616c6c6574144572726f720404540001602056616c75654c6f770000043456616c756520746f6f206c6f773c50726f706f73616c4d697373696e670001045c50726f706f73616c20646f6573206e6f742065786973743c416c726561647943616e63656c65640002049443616e6e6f742063616e63656c207468652073616d652070726f706f73616c207477696365444475706c696361746550726f706f73616c0003045450726f706f73616c20616c7265616479206d6164654c50726f706f73616c426c61636b6c69737465640004046850726f706f73616c207374696c6c20626c61636b6c6973746564444e6f7453696d706c654d616a6f72697479000504a84e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792c496e76616c69644861736800060430496e76616c69642068617368284e6f50726f706f73616c000704504e6f2065787465726e616c2070726f706f73616c34416c72656164795665746f6564000804984964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365445265666572656e64756d496e76616c696400090484566f746520676976656e20666f7220696e76616c6964207265666572656e64756d2c4e6f6e6557616974696e67000a04504e6f2070726f706f73616c732077616974696e67204e6f74566f746572000b04c454686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e304e6f5065726d697373696f6e000c04c8546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e44416c726561647944656c65676174696e67000d0488546865206163636f756e7420697320616c72656164792064656c65676174696e672e44496e73756666696369656e7446756e6473000e04fc546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e344e6f7444656c65676174696e67000f04a0546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e28566f74657345786973740010085501546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696ce87468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e44496e7374616e744e6f74416c6c6f776564001104d854686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e204e6f6e73656e73650012049444656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e3c57726f6e675570706572426f756e6400130450496e76616c696420757070657220626f756e642e3c4d6178566f74657352656163686564001404804d6178696d756d206e756d626572206f6620766f74657320726561636865642e1c546f6f4d616e79001504804d6178696d756d206e756d626572206f66206974656d7320726561636865642e3c566f74696e67506572696f644c6f7700160454566f74696e6720706572696f6420746f6f206c6f7740507265696d6167654e6f7445786973740017047054686520707265696d61676520646f6573206e6f742065786973742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e2d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00003108084470616c6c65745f636f6c6c65637469766514566f74657308244163636f756e74496401002c426c6f636b4e756d626572013000140114696e64657810013450726f706f73616c496e6465780001247468726573686f6c6410012c4d656d626572436f756e74000110617965733d0201385665633c4163636f756e7449643e0001106e6179733d0201385665633c4163636f756e7449643e00010c656e6430012c426c6f636b4e756d626572000035080c4470616c6c65745f636f6c6c6563746976651870616c6c6574144572726f7208045400044900012c244e6f744d656d6265720000045c4163636f756e74206973206e6f742061206d656d626572444475706c696361746550726f706f73616c0001047c4475706c69636174652070726f706f73616c73206e6f7420616c6c6f7765643c50726f706f73616c4d697373696e670002044c50726f706f73616c206d7573742065786973742857726f6e67496e646578000304404d69736d61746368656420696e646578344475706c6963617465566f7465000404584475706c696361746520766f74652069676e6f72656448416c7265616479496e697469616c697a6564000504804d656d626572732061726520616c726561647920696e697469616c697a65642120546f6f4561726c79000604010154686520636c6f73652063616c6c20776173206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e40546f6f4d616e7950726f706f73616c73000704fc54686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e4c57726f6e6750726f706f73616c576569676874000804d054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e4c57726f6e6750726f706f73616c4c656e677468000904d054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e545072696d654163636f756e744e6f744d656d626572000a04745072696d65206163636f756e74206973206e6f742061206d656d626572048054686520604572726f726020656e756d206f6620746869732070616c6c65742e39080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540149030453000004003d0801185665633c543e00003d080000024903004108083870616c6c65745f76657374696e672052656c65617365730001080856300000000856310001000045080c3870616c6c65745f76657374696e671870616c6c6574144572726f72040454000114284e6f7456657374696e6700000484546865206163636f756e7420676976656e206973206e6f742076657374696e672e5441744d617856657374696e675363686564756c65730001082501546865206163636f756e7420616c72656164792068617320604d617856657374696e675363686564756c65736020636f756e74206f66207363686564756c657320616e642074687573510163616e6e6f742061646420616e6f74686572206f6e652e20436f6e7369646572206d657267696e67206578697374696e67207363686564756c657320696e206f7264657220746f2061646420616e6f746865722e24416d6f756e744c6f770002040501416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e605363686564756c65496e6465784f75744f66426f756e6473000304d0416e20696e64657820776173206f7574206f6620626f756e6473206f66207468652076657374696e67207363686564756c65732e54496e76616c69645363686564756c65506172616d730004040d014661696c656420746f206372656174652061206e6577207363686564756c65206265636175736520736f6d6520706172616d657465722077617320696e76616c69642e04744572726f7220666f72207468652076657374696e672070616c6c65742e49080000024d08004d08086470616c6c65745f656c656374696f6e735f70687261676d656e2853656174486f6c64657208244163636f756e74496401001c42616c616e63650118000c010c77686f0001244163636f756e7449640001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e636500005108086470616c6c65745f656c656374696f6e735f70687261676d656e14566f74657208244163636f756e74496401001c42616c616e63650118000c0114766f7465733d0201385665633c4163636f756e7449643e0001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e6365000055080c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144572726f7204045400014430556e61626c65546f566f7465000004c043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e1c4e6f566f746573000104944d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e30546f6f4d616e79566f7465730002048443616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e504d6178696d756d566f74657345786365656465640003049843616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e284c6f7742616c616e6365000404c443616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e3c556e61626c65546f506179426f6e6400050478566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2c4d7573744265566f746572000604404d757374206265206120766f7465722e4c4475706c69636174656443616e646964617465000704804475706c6963617465642063616e646964617465207375626d697373696f6e2e44546f6f4d616e7943616e6469646174657300080498546f6f206d616e792063616e646964617465732068617665206265656e20637265617465642e304d656d6265725375626d6974000904884d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e3852756e6e657255705375626d6974000a048852756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e68496e73756666696369656e7443616e64696461746546756e6473000b049443616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e244e6f744d656d626572000c04344e6f742061206d656d6265722e48496e76616c69645769746e65737344617461000d04e05468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e40496e76616c6964566f7465436f756e74000e04cc5468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e44496e76616c696452656e6f756e63696e67000f04fc5468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e48496e76616c69645265706c6163656d656e74001004fc50726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e5908089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365345265616479536f6c7574696f6e08244163636f756e74496400284d617857696e6e65727300000c0120737570706f7274735d080198426f756e646564537570706f7274733c4163636f756e7449642c204d617857696e6e6572733e00011473636f7265e00134456c656374696f6e53636f726500011c636f6d70757465dc013c456c656374696f6e436f6d7075746500005d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013504045300000400310401185665633c543e00006108089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736534526f756e64536e617073686f7408244163636f756e7449640100304461746150726f766964657201650800080118766f746572736d0801445665633c4461746150726f76696465723e00011c746172676574733d0201385665633c4163636f756e7449643e000065080000040c003069080069080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e00006d0800000265080071080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017508045300000400790801185665633c543e000075080000040ce030100079080000027508007d080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365187369676e6564405369676e65645375626d697373696f6e0c244163636f756e74496401001c42616c616e6365011820536f6c7574696f6e015d030010010c77686f0001244163636f756e74496400011c6465706f73697418011c42616c616e63650001307261775f736f6c7574696f6e59030154526177536f6c7574696f6e3c536f6c7574696f6e3e00012063616c6c5f66656518011c42616c616e6365000081080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144572726f7204045400013c6850726544697370617463684561726c795375626d697373696f6e000004645375626d697373696f6e2077617320746f6f206561726c792e6c507265446973706174636857726f6e6757696e6e6572436f756e740001048857726f6e67206e756d626572206f662077696e6e6572732070726573656e7465642e6450726544697370617463685765616b5375626d697373696f6e000204905375626d697373696f6e2077617320746f6f207765616b2c2073636f72652d776973652e3c5369676e6564517565756546756c6c0003044901546865207175657565207761732066756c6c2c20616e642074686520736f6c7574696f6e20776173206e6f7420626574746572207468616e20616e79206f6620746865206578697374696e67206f6e65732e585369676e656443616e6e6f745061794465706f73697400040494546865206f726967696e206661696c656420746f2070617920746865206465706f7369742e505369676e6564496e76616c69645769746e657373000504a05769746e657373206461746120746f20646973706174636861626c6520697320696e76616c69642e4c5369676e6564546f6f4d756368576569676874000604b8546865207369676e6564207375626d697373696f6e20636f6e73756d657320746f6f206d756368207765696768743c4f637743616c6c57726f6e67457261000704984f4357207375626d697474656420736f6c7574696f6e20666f722077726f6e6720726f756e645c4d697373696e67536e617073686f744d65746164617461000804a8536e617073686f74206d657461646174612073686f756c6420657869737420627574206469646e27742e58496e76616c69645375626d697373696f6e496e646578000904d06053656c663a3a696e736572745f7375626d697373696f6e602072657475726e656420616e20696e76616c696420696e6465782e3843616c6c4e6f74416c6c6f776564000a04985468652063616c6c206973206e6f7420616c6c6f776564206174207468697320706f696e742e3846616c6c6261636b4661696c6564000b044c5468652066616c6c6261636b206661696c65642c426f756e644e6f744d6574000c0448536f6d6520626f756e64206e6f74206d657438546f6f4d616e7957696e6e657273000d049c5375626d697474656420736f6c7574696f6e2068617320746f6f206d616e792077696e6e657273645072654469737061746368446966666572656e74526f756e64000e04b85375626d697373696f6e2077617320707265706172656420666f72206120646966666572656e7420726f756e642e040d014572726f72206f66207468652070616c6c657420746861742063616e2062652072657475726e656420696e20726573706f6e736520746f20646973706174636865732e8508083870616c6c65745f7374616b696e67345374616b696e674c656467657204045400001401147374617368000130543a3a4163636f756e744964000114746f74616c6d01013042616c616e63654f663c543e0001186163746976656d01013042616c616e63654f663c543e000124756e6c6f636b696e67650401f0426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a4d6178556e6c6f636b696e674368756e6b733e0001586c65676163795f636c61696d65645f7265776172647389080194426f756e6465645665633c457261496e6465782c20543a3a486973746f727944657074683e000089080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e00008d08083870616c6c65745f7374616b696e672c4e6f6d696e6174696f6e7304045400000c011c74617267657473690801b4426f756e6465645665633c543a3a4163636f756e7449642c204d61784e6f6d696e6174696f6e734f663c543e3e0001307375626d69747465645f696e100120457261496e64657800012873757070726573736564200110626f6f6c00009108083870616c6c65745f7374616b696e6734416374697665457261496e666f0000080114696e646578100120457261496e64657800011473746172747d04012c4f7074696f6e3c7536343e00009508000004081000009908082873705f7374616b696e675450616765644578706f737572654d65746164617461041c42616c616e6365011800100114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e636500013c6e6f6d696e61746f725f636f756e7410010c753332000128706167655f636f756e741001105061676500009d080000040c10001000a108082873705f7374616b696e67304578706f737572655061676508244163636f756e74496401001c42616c616e6365011800080128706167655f746f74616c6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e0000a508083870616c6c65745f7374616b696e673c457261526577617264506f696e747304244163636f756e744964010000080114746f74616c10012c526577617264506f696e74000128696e646976696475616ca908018042547265654d61703c4163636f756e7449642c20526577617264506f696e743e0000a908042042547265654d617008044b010004560110000400ad08000000ad08000002b10800b10800000408001000b508000002b90800b908083870616c6c65745f7374616b696e6738556e6170706c696564536c61736808244163636f756e74496401001c42616c616e636501180014012476616c696461746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f72746572733d0201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000bd08000002c10800c10800000408101000c50800000408f41800c9080c3870616c6c65745f7374616b696e6720736c617368696e6734536c617368696e675370616e7300001001287370616e5f696e6465781001245370616e496e6465780001286c6173745f7374617274100120457261496e6465780001486c6173745f6e6f6e7a65726f5f736c617368100120457261496e6465780001147072696f72450401345665633c457261496e6465783e0000cd080c3870616c6c65745f7374616b696e6720736c617368696e67285370616e5265636f7264041c42616c616e636501180008011c736c617368656418011c42616c616e6365000120706169645f6f757418011c42616c616e63650000d108103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144572726f7204045400017c344e6f74436f6e74726f6c6c6572000004644e6f74206120636f6e74726f6c6c6572206163636f756e742e204e6f745374617368000104504e6f742061207374617368206163636f756e742e34416c7265616479426f6e64656400020460537461736820697320616c726561647920626f6e6465642e34416c726561647950616972656400030474436f6e74726f6c6c657220697320616c7265616479207061697265642e30456d7074795461726765747300040460546172676574732063616e6e6f7420626520656d7074792e384475706c6963617465496e646578000504404475706c696361746520696e6465782e44496e76616c6964536c617368496e64657800060484536c617368207265636f726420696e646578206f7574206f6620626f756e64732e40496e73756666696369656e74426f6e6400070c590143616e6e6f74206861766520612076616c696461746f72206f72206e6f6d696e61746f7220726f6c652c20776974682076616c7565206c657373207468616e20746865206d696e696d756d20646566696e65642062793d01676f7665726e616e6365202873656520604d696e56616c696461746f72426f6e646020616e6420604d696e4e6f6d696e61746f72426f6e6460292e20496620756e626f6e64696e67206973207468651501696e74656e74696f6e2c20606368696c6c6020666972737420746f2072656d6f7665206f6e65277320726f6c652061732076616c696461746f722f6e6f6d696e61746f722e304e6f4d6f72654368756e6b730008049043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e344e6f556e6c6f636b4368756e6b000904a043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e3046756e646564546172676574000a04c8417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e48496e76616c6964457261546f526577617264000b0458496e76616c69642065726120746f207265776172642e68496e76616c69644e756d6265724f664e6f6d696e6174696f6e73000c0478496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e484e6f74536f72746564416e64556e69717565000d04804974656d7320617265206e6f7420736f7274656420616e6420756e697175652e38416c7265616479436c61696d6564000e0409015265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e2c496e76616c696450616765000f04844e6f206e6f6d696e61746f7273206578697374206f6e207468697320706167652e54496e636f7272656374486973746f72794465707468001004c0496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e58496e636f7272656374536c617368696e675370616e73001104b0496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e2042616453746174650012043901496e7465726e616c20737461746520686173206265636f6d6520736f6d65686f7720636f7272757074656420616e6420746865206f7065726174696f6e2063616e6e6f7420636f6e74696e75652e38546f6f4d616e795461726765747300130494546f6f206d616e79206e6f6d696e6174696f6e207461726765747320737570706c6965642e244261645461726765740014043d0141206e6f6d696e6174696f6e207461726765742077617320737570706c69656420746861742077617320626c6f636b6564206f72206f7468657277697365206e6f7420612076616c696461746f722e4043616e6e6f744368696c6c4f74686572001504550154686520757365722068617320656e6f75676820626f6e6420616e6420746875732063616e6e6f74206265206368696c6c656420666f72636566756c6c7920627920616e2065787465726e616c20706572736f6e2e44546f6f4d616e794e6f6d696e61746f72730016084d0154686572652061726520746f6f206d616e79206e6f6d696e61746f727320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865207374616b696e67b473657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e44546f6f4d616e7956616c696461746f7273001708550154686572652061726520746f6f206d616e792076616c696461746f722063616e6469646174657320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865d47374616b696e672073657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e40436f6d6d697373696f6e546f6f4c6f77001804e0436f6d6d697373696f6e20697320746f6f206c6f772e204d757374206265206174206c6561737420604d696e436f6d6d697373696f6e602e2c426f756e644e6f744d657400190458536f6d6520626f756e64206973206e6f74206d65742e50436f6e74726f6c6c657244657072656361746564001a04010155736564207768656e20617474656d7074696e6720746f20757365206465707265636174656420636f6e74726f6c6c6572206163636f756e74206c6f6769632e4c43616e6e6f74526573746f72654c6564676572001b045843616e6e6f742072657365742061206c65646765722e6c52657761726444657374696e6174696f6e52657374726963746564001c04ac50726f7669646564207265776172642064657374696e6174696f6e206973206e6f7420616c6c6f7765642e384e6f74456e6f75676846756e6473001d049c4e6f7420656e6f7567682066756e647320617661696c61626c6520746f2077697468647261772e5c5669727475616c5374616b65724e6f74416c6c6f776564001e04a84f7065726174696f6e206e6f7420616c6c6f77656420666f72207669727475616c207374616b6572732e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed508000002d90800d9080000040800750400dd0800000408e1083800e1080c1c73705f636f72651863727970746f244b65795479706549640000040048011c5b75383b20345d0000e5080c3870616c6c65745f73657373696f6e1870616c6c6574144572726f7204045400011430496e76616c696450726f6f6600000460496e76616c6964206f776e6572736869702070726f6f662e5c4e6f4173736f63696174656456616c696461746f7249640001049c4e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e344475706c6963617465644b65790002046452656769737465726564206475706c6963617465206b65792e184e6f4b657973000304a44e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e244e6f4163636f756e7400040419014b65792073657474696e67206163636f756e74206973206e6f74206c6976652c20736f206974277320696d706f737369626c6520746f206173736f6369617465206b6579732e04744572726f7220666f72207468652073657373696f6e2070616c6c65742ee90800000408341000ed08083c70616c6c65745f74726561737572792050726f706f73616c08244163636f756e74496401001c42616c616e636501180010012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500012c62656e65666963696172790001244163636f756e744964000110626f6e6418011c42616c616e63650000f1080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e0000f508083c70616c6c65745f74726561737572792c5370656e64537461747573142441737365744b696e64018430417373657442616c616e636501182c42656e656669636961727901002c426c6f636b4e756d6265720130245061796d656e74496401840018012861737365745f6b696e6484012441737365744b696e64000118616d6f756e74180130417373657442616c616e636500012c62656e656669636961727900012c42656e656669636961727900012876616c69645f66726f6d30012c426c6f636b4e756d6265720001246578706972655f617430012c426c6f636b4e756d626572000118737461747573f908015c5061796d656e7453746174653c5061796d656e7449643e0000f908083c70616c6c65745f7472656173757279305061796d656e745374617465040849640184010c1c50656e64696e6700000024417474656d7074656404010869648401084964000100184661696c656400020000fd0808346672616d655f737570706f72742050616c6c6574496400000400a902011c5b75383b20385d000001090c3c70616c6c65745f74726561737572791870616c6c6574144572726f7208045400044900012c30496e76616c6964496e646578000004ac4e6f2070726f706f73616c2c20626f756e7479206f72207370656e64206174207468617420696e6465782e40546f6f4d616e79417070726f76616c7300010480546f6f206d616e7920617070726f76616c7320696e207468652071756575652e58496e73756666696369656e745065726d697373696f6e0002084501546865207370656e64206f726967696e2069732076616c6964206275742074686520616d6f756e7420697420697320616c6c6f77656420746f207370656e64206973206c6f776572207468616e207468654c616d6f756e7420746f206265207370656e742e4c50726f706f73616c4e6f74417070726f7665640003047c50726f706f73616c20686173206e6f74206265656e20617070726f7665642e584661696c6564546f436f6e7665727442616c616e636500040451015468652062616c616e6365206f6620746865206173736574206b696e64206973206e6f7420636f6e7665727469626c6520746f207468652062616c616e6365206f6620746865206e61746976652061737365742e305370656e6445787069726564000504b0546865207370656e6420686173206578706972656420616e642063616e6e6f7420626520636c61696d65642e2c4561726c795061796f7574000604a4546865207370656e64206973206e6f742079657420656c696769626c6520666f72207061796f75742e40416c7265616479417474656d707465640007049c546865207061796d656e742068617320616c7265616479206265656e20617474656d707465642e2c5061796f75744572726f72000804cc54686572652077617320736f6d65206973737565207769746820746865206d656368616e69736d206f66207061796d656e742e304e6f74417474656d70746564000904a4546865207061796f757420776173206e6f742079657420617474656d707465642f636c61696d65642e30496e636f6e636c7573697665000a04c4546865207061796d656e7420686173206e656974686572206661696c6564206e6f7220737563636565646564207965742e04784572726f7220666f72207468652074726561737572792070616c6c65742e0509083c70616c6c65745f626f756e7469657318426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d62657201300018012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000110626f6e6418011c42616c616e636500011873746174757309090190426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00000909083c70616c6c65745f626f756e7469657330426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001182050726f706f73656400000020417070726f7665640001001846756e6465640002003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640003001841637469766508011c63757261746f720001244163636f756e7449640001287570646174655f64756530012c426c6f636b4e756d6265720004003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d626572000500000d090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000011090c3c70616c6c65745f626f756e746965731870616c6c6574144572726f7208045400044900012c70496e73756666696369656e7450726f706f7365727342616c616e63650000047850726f706f73657227732062616c616e636520697320746f6f206c6f772e30496e76616c6964496e646578000104904e6f2070726f706f73616c206f7220626f756e7479206174207468617420696e6465782e30526561736f6e546f6f4269670002048454686520726561736f6e20676976656e206973206a75737420746f6f206269672e40556e65787065637465645374617475730003048054686520626f756e74792073746174757320697320756e65787065637465642e385265717569726543757261746f720004045c5265717569726520626f756e74792063757261746f722e30496e76616c696456616c756500050454496e76616c696420626f756e74792076616c75652e28496e76616c69644665650006044c496e76616c696420626f756e7479206665652e3450656e64696e675061796f75740007086c4120626f756e7479207061796f75742069732070656e64696e672ef8546f2063616e63656c2074686520626f756e74792c20796f75206d75737420756e61737369676e20616e6420736c617368207468652063757261746f722e245072656d6174757265000804450154686520626f756e746965732063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e504861734163746976654368696c64426f756e7479000904050154686520626f756e74792063616e6e6f7420626520636c6f73656420626563617573652069742068617320616374697665206368696c6420626f756e746965732e34546f6f4d616e79517565756564000a0498546f6f206d616e7920617070726f76616c732061726520616c7265616479207175657565642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e1509085470616c6c65745f6368696c645f626f756e746965732c4368696c64426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d626572013000140134706172656e745f626f756e747910012c426f756e7479496e64657800011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000118737461747573190901a44368696c64426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00001909085470616c6c65745f6368696c645f626f756e74696573444368696c64426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001101441646465640000003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640001001841637469766504011c63757261746f720001244163636f756e7449640002003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d626572000300001d090c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144572726f7204045400010c54506172656e74426f756e74794e6f74416374697665000004a454686520706172656e7420626f756e7479206973206e6f7420696e206163746976652073746174652e64496e73756666696369656e74426f756e747942616c616e6365000104e454686520626f756e74792062616c616e6365206973206e6f7420656e6f75676820746f20616464206e6577206368696c642d626f756e74792e50546f6f4d616e794368696c64426f756e746965730002040d014e756d626572206f66206368696c6420626f756e746965732065786365656473206c696d697420604d61784163746976654368696c64426f756e7479436f756e74602e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e21090c4070616c6c65745f626167735f6c697374106c697374104e6f646508045400044900001401086964000130543a3a4163636f756e744964000110707265768801504f7074696f6e3c543a3a4163636f756e7449643e0001106e6578748801504f7074696f6e3c543a3a4163636f756e7449643e0001246261675f7570706572300120543a3a53636f726500011473636f7265300120543a3a53636f7265000025090c4070616c6c65745f626167735f6c697374106c6973740c4261670804540004490000080110686561648801504f7074696f6e3c543a3a4163636f756e7449643e0001107461696c8801504f7074696f6e3c543a3a4163636f756e7449643e000029090c4070616c6c65745f626167735f6c6973741870616c6c6574144572726f72080454000449000104104c69737404002d0901244c6973744572726f72000004b441206572726f7220696e20746865206c69737420696e7465726661636520696d706c656d656e746174696f6e2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e2d090c4070616c6c65745f626167735f6c697374106c697374244c6973744572726f72000110244475706c6963617465000000284e6f7448656176696572000100304e6f74496e53616d65426167000200304e6f64654e6f74466f756e64000300003109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328506f6f6c4d656d626572040454000010011c706f6f6c5f6964100118506f6f6c4964000118706f696e747318013042616c616e63654f663c543e0001706c6173745f7265636f726465645f7265776172645f636f756e74657295070140543a3a526577617264436f756e746572000138756e626f6e64696e675f65726173350901e0426f756e64656442547265654d61703c457261496e6465782c2042616c616e63654f663c543e2c20543a3a4d6178556e626f6e64696e673e000035090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601180453000004003909013842547265654d61703c4b2c20563e00003909042042547265654d617008044b0110045601180004003d090000003d090000024109004109000004081018004509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c426f6e646564506f6f6c496e6e65720404540000140128636f6d6d697373696f6e49090134436f6d6d697373696f6e3c543e0001386d656d6265725f636f756e74657210010c753332000118706f696e747318013042616c616e63654f663c543e000114726f6c65735509015c506f6f6c526f6c65733c543a3a4163636f756e7449643e00011473746174651d010124506f6f6c537461746500004909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784d09013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f72617465510901bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e00004d0904184f7074696f6e04045401f40108104e6f6e6500000010536f6d650400f40000010000510904184f7074696f6e0404540129010108104e6f6e6500000010536f6d650400290100000100005509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e00005909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e74657295070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e00005d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320537562506f6f6c7304045400000801186e6f5f65726161090134556e626f6e64506f6f6c3c543e000120776974685f6572616509010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e00006109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e000065090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b011004560161090453000004006909013842547265654d61703c4b2c20563e00006909042042547265654d617008044b011004560161090004006d090000006d090000027109007109000004081061090075090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144572726f7204045400019030506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e644163636f756e7442656c6f6e6773546f4f74686572506f6f6c0004084d01416e206163636f756e7420697320616c72656164792064656c65676174696e6720696e20616e6f7468657220706f6f6c2e20416e206163636f756e74206d6179206f6e6c792062656c6f6e6720746f206f6e653c706f6f6c20617420612074696d652e3846756c6c79556e626f6e64696e670005083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740006040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790007044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000814290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0009042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e67000a085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000b04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000c043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000d047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000e04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000f049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e676553746174650010048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001104b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001204ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e73697665040079090138446566656e736976654572726f720013083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001404bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640015041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001604ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001704e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400180409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640019040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001a04a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001b048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001c0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001d049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001e04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001f04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e384e6f7468696e67546f536c617368002004cc4e6f20736c6173682070656e64696e6720746861742063616e206265206170706c69656420746f20746865206d656d6265722e3c416c72656164794d69677261746564002104150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e2068617320616c7265616479206d6967726174656420746f2064656c6567617465207374616b652e2c4e6f744d69677261746564002204150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e20686173206e6f74206d696772617465642079657420746f2064656c6567617465207374616b652e304e6f74537570706f72746564002304f0546869732063616c6c206973206e6f7420616c6c6f77656420696e207468652063757272656e74207374617465206f66207468652070616c6c65742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e79090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657438446566656e736976654572726f7200011c684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c790004005444656c65676174696f6e556e737570706f727465640005003c536c6173684e6f744170706c696564000600007d090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454018109045300000400890901185665633c543e0000810904184f7074696f6e0404540185090108104e6f6e6500000010536f6d650400850900000100008509084070616c6c65745f7363686564756c6572245363686564756c656414104e616d6501041043616c6c0129032c426c6f636b4e756d62657201303450616c6c6574734f726967696e017105244163636f756e7449640100001401206d617962655f69643d0101304f7074696f6e3c4e616d653e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6c2903011043616c6c0001386d617962655f706572696f646963ad0401944f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d6265723e3e0001186f726967696e7105013450616c6c6574734f726967696e000089090000028109008d09084070616c6c65745f7363686564756c65722c5265747279436f6e6669670418506572696f640130000c0134746f74616c5f72657472696573080108753800012472656d61696e696e670801087538000118706572696f64300118506572696f64000091090c4070616c6c65745f7363686564756c65721870616c6c6574144572726f72040454000114404661696c6564546f5363686564756c65000004644661696c656420746f207363686564756c6520612063616c6c204e6f74466f756e640001047c43616e6e6f742066696e6420746865207363686564756c65642063616c6c2e5c546172676574426c6f636b4e756d626572496e50617374000204a4476976656e2074617267657420626c6f636b206e756d62657220697320696e2074686520706173742e4852657363686564756c654e6f4368616e6765000304f052657363686564756c65206661696c6564206265636175736520697420646f6573206e6f74206368616e6765207363686564756c65642074696d652e144e616d6564000404d0417474656d707420746f207573652061206e6f6e2d6e616d65642066756e6374696f6e206f6e2061206e616d6564207461736b2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e9509083c70616c6c65745f707265696d616765404f6c645265717565737453746174757308244163636f756e74496401001c42616c616e6365011801082c556e72657175657374656408011c6465706f736974d40150284163636f756e7449642c2042616c616e63652900010c6c656e10010c753332000000245265717565737465640c011c6465706f736974990901704f7074696f6e3c284163636f756e7449642c2042616c616e6365293e000114636f756e7410010c75333200010c6c656e3903012c4f7074696f6e3c7533323e00010000990904184f7074696f6e04045401d40108104e6f6e6500000010536f6d650400d400000100009d09083c70616c6c65745f707265696d616765345265717565737453746174757308244163636f756e7449640100185469636b6574018401082c556e7265717565737465640801187469636b6574a109014c284163636f756e7449642c205469636b65742900010c6c656e10010c753332000000245265717565737465640c01306d617962655f7469636b6574a509016c4f7074696f6e3c284163636f756e7449642c205469636b6574293e000114636f756e7410010c7533320001246d617962655f6c656e3903012c4f7074696f6e3c7533323e00010000a10900000408008400a50904184f7074696f6e04045401a1090108104e6f6e6500000010536f6d650400a1090000010000a9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000ad090c3c70616c6c65745f707265696d6167651870616c6c6574144572726f7204045400012418546f6f426967000004a0507265696d61676520697320746f6f206c6172676520746f2073746f7265206f6e2d636861696e2e30416c72656164794e6f746564000104a4507265696d6167652068617320616c7265616479206265656e206e6f746564206f6e2d636861696e2e344e6f74417574686f72697a6564000204c85468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e2e204e6f744e6f746564000304fc54686520707265696d6167652063616e6e6f742062652072656d6f7665642073696e636520697420686173206e6f7420796574206265656e206e6f7465642e2452657175657374656400040409014120707265696d616765206d6179206e6f742062652072656d6f766564207768656e20746865726520617265206f75747374616e64696e672072657175657374732e304e6f745265717565737465640005042d0154686520707265696d61676520726571756573742063616e6e6f742062652072656d6f7665642073696e6365206e6f206f75747374616e64696e672072657175657374732065786973742e1c546f6f4d616e7900060455014d6f7265207468616e20604d41585f484153485f555047524144455f42554c4b5f434f554e54602068617368657320776572652072657175657374656420746f206265207570677261646564206174206f6e63652e18546f6f466577000704e4546f6f206665772068617368657320776572652072657175657374656420746f2062652075706772616465642028692e652e207a65726f292e184e6f436f737400080459014e6f207469636b65742077697468206120636f7374207761732072657475726e6564206279205b60436f6e6669673a3a436f6e73696465726174696f6e605d20746f2073746f72652074686520707265696d6167652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742eb1090c2873705f7374616b696e671c6f6666656e6365384f6666656e636544657461696c7308205265706f727465720100204f6666656e646572016501000801206f6666656e646572650101204f6666656e6465720001247265706f72746572733d0201345665633c5265706f727465723e0000b5090000040849013800b9090c3c70616c6c65745f74785f70617573651870616c6c6574144572726f720404540001102049735061757365640000044c5468652063616c6c206973207061757365642e284973556e706175736564000104545468652063616c6c20697320756e7061757365642e28556e7061757361626c65000204b45468652063616c6c2069732077686974656c697374656420616e642063616e6e6f74206265207061757365642e204e6f74466f756e64000300048054686520604572726f726020656e756d206f6620746869732070616c6c65742ebd090c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454015d01045300000400c10901185665633c543e0000c1090000025d0100c5090c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144572726f7204045400010828496e76616c69644b6579000004604e6f6e206578697374656e74207075626c6963206b65792e4c4475706c696361746564486561727462656174000104544475706c696361746564206865617274626561742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ec90900000408cd09dd0900cd090c3c70616c6c65745f6964656e7469747914747970657330526567697374726174696f6e0c1c42616c616e63650118344d61784a756467656d656e747300304964656e74697479496e666f01c904000c01286a756467656d656e7473d10901fc426f756e6465645665633c28526567697374726172496e6465782c204a756467656d656e743c42616c616e63653e292c204d61784a756467656d656e74733e00011c6465706f73697418011c42616c616e6365000110696e666fc90401304964656e74697479496e666f0000d1090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d509045300000400d90901185665633c543e0000d5090000040810590500d909000002d50900dd0904184f7074696f6e040454017d010108104e6f6e6500000010536f6d6504007d010000010000e1090000040818e50900e5090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e0000e9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ed09045300000400f50901185665633c543e0000ed0904184f7074696f6e04045401f1090108104e6f6e6500000010536f6d650400f1090000010000f1090c3c70616c6c65745f6964656e7469747914747970657334526567697374726172496e666f0c1c42616c616e63650118244163636f756e74496401001c49644669656c640130000c011c6163636f756e740001244163636f756e74496400010c66656518011c42616c616e63650001186669656c647330011c49644669656c640000f509000002ed0900f9090c3c70616c6c65745f6964656e746974791474797065734c417574686f7269747950726f70657274696573041853756666697801fd0900080118737566666978fd090118537566666978000128616c6c6f636174696f6e100128416c6c6f636174696f6e0000fd090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000010a00000408003000050a0c3c70616c6c65745f6964656e746974791870616c6c6574144572726f7204045400016848546f6f4d616e795375624163636f756e74730000045c546f6f206d616e7920737562732d6163636f756e74732e204e6f74466f756e64000104504163636f756e742069736e277420666f756e642e204e6f744e616d6564000204504163636f756e742069736e2774206e616d65642e28456d707479496e64657800030430456d70747920696e6465782e284665654368616e6765640004043c466565206973206368616e6765642e284e6f4964656e74697479000504484e6f206964656e7469747920666f756e642e3c537469636b794a756467656d656e7400060444537469636b79206a756467656d656e742e384a756467656d656e74476976656e000704404a756467656d656e7420676976656e2e40496e76616c69644a756467656d656e7400080448496e76616c6964206a756467656d656e742e30496e76616c6964496e6465780009045454686520696e64657820697320696e76616c69642e34496e76616c6964546172676574000a04585468652074617267657420697320696e76616c69642e44546f6f4d616e7952656769737472617273000b04e84d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e38416c7265616479436c61696d6564000c04704163636f756e7420494420697320616c7265616479206e616d65642e184e6f74537562000d047053656e646572206973206e6f742061207375622d6163636f756e742e204e6f744f776e6564000e04885375622d6163636f756e742069736e2774206f776e65642062792073656e6465722e744a756467656d656e74466f72446966666572656e744964656e74697479000f04d05468652070726f7669646564206a756467656d656e742077617320666f72206120646966666572656e74206964656e746974792e584a756467656d656e745061796d656e744661696c6564001004f84572726f722074686174206f6363757273207768656e20746865726520697320616e20697373756520706179696e6720666f72206a756467656d656e742e34496e76616c6964537566666978001104805468652070726f76696465642073756666697820697320746f6f206c6f6e672e504e6f74557365726e616d65417574686f72697479001204e05468652073656e64657220646f6573206e6f742068617665207065726d697373696f6e20746f206973737565206120757365726e616d652e304e6f416c6c6f636174696f6e001304c454686520617574686f726974792063616e6e6f7420616c6c6f6361746520616e79206d6f726520757365726e616d65732e40496e76616c69645369676e6174757265001404a8546865207369676e6174757265206f6e206120757365726e616d6520776173206e6f742076616c69642e4452657175697265735369676e6174757265001504090153657474696e67207468697320757365726e616d652072657175697265732061207369676e61747572652c20627574206e6f6e65207761732070726f76696465642e3c496e76616c6964557365726e616d65001604b054686520757365726e616d6520646f6573206e6f74206d6565742074686520726571756972656d656e74732e34557365726e616d6554616b656e0017047854686520757365726e616d6520697320616c72656164792074616b656e2e284e6f557365726e616d65001804985468652072657175657374656420757365726e616d6520646f6573206e6f742065786973742e284e6f74457870697265640019042d0154686520757365726e616d652063616e6e6f7420626520666f72636566756c6c792072656d6f76656420626563617573652069742063616e207374696c6c2062652061636365707465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e090a0c3870616c6c65745f7574696c6974791870616c6c6574144572726f7204045400010430546f6f4d616e7943616c6c730000045c546f6f206d616e792063616c6c7320626174636865642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e0d0a00000408000400110a083c70616c6c65745f6d756c7469736967204d756c7469736967102c426c6f636b4e756d62657201301c42616c616e63650118244163636f756e7449640100304d6178417070726f76616c7300001001107768656e8901015854696d65706f696e743c426c6f636b4e756d6265723e00011c6465706f73697418011c42616c616e63650001246465706f7369746f720001244163636f756e744964000124617070726f76616c735904018c426f756e6465645665633c4163636f756e7449642c204d6178417070726f76616c733e0000150a0c3c70616c6c65745f6d756c74697369671870616c6c6574144572726f72040454000138404d696e696d756d5468726573686f6c640000047c5468726573686f6c64206d7573742062652032206f7220677265617465722e3c416c7265616479417070726f766564000104ac43616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e444e6f417070726f76616c734e65656465640002049c43616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e44546f6f4665775369676e61746f72696573000304a854686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e48546f6f4d616e795369676e61746f72696573000404ac54686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e545369676e61746f726965734f75744f664f726465720005040d01546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e4c53656e646572496e5369676e61746f726965730006040d015468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e204e6f74466f756e64000704dc4d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e204e6f744f776e65720008042d014f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e2c4e6f54696d65706f696e740009041d014e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e3857726f6e6754696d65706f696e74000a042d014120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e4c556e657870656374656454696d65706f696e74000b04f4412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e3c4d6178576569676874546f6f4c6f77000c04d0546865206d6178696d756d2077656967687420696e666f726d6174696f6e2070726f76696465642077617320746f6f206c6f772e34416c726561647953746f726564000d04a0546865206461746120746f2062652073746f72656420697320616c72656164792073746f7265642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e190a0000021d0a001d0a0000040c8d05210a310a00210a081866705f727063445472616e73616374696f6e53746174757300001c01407472616e73616374696f6e5f68617368340110483235360001447472616e73616374696f6e5f696e64657810010c75333200011066726f6d9101011c41646472657373000108746f0906013c4f7074696f6e3c416464726573733e000140636f6e74726163745f616464726573730906013c4f7074696f6e3c416464726573733e0001106c6f6773250a01205665633c4c6f673e0001286c6f67735f626c6f6f6d290a0114426c6f6f6d0000250a000002bd0100290a0820657468626c6f6f6d14426c6f6f6d000004002d0a01405b75383b20424c4f4f4d5f53495a455d00002d0a000003000100000800310a0c20657468657265756d1c726563656970742452656365697074563300010c184c65676163790400350a014445495036353852656365697074446174610000001c454950323933300400350a01484549503239333052656365697074446174610001001c454950313535390400350a014845495031353539526563656970744461746100020000350a0c20657468657265756d1c72656365697074444549503635385265636569707444617461000010012c7374617475735f636f64650801087538000120757365645f676173c9010110553235360001286c6f67735f626c6f6f6d290a0114426c6f6f6d0001106c6f6773250a01205665633c4c6f673e0000390a0c20657468657265756d14626c6f636b14426c6f636b040454018d05000c01186865616465723d0a01184865616465720001307472616e73616374696f6e73450a01185665633c543e0001186f6d6d657273490a012c5665633c4865616465723e00003d0a0c20657468657265756d186865616465721848656164657200003c012c706172656e745f686173683401104832353600012c6f6d6d6572735f686173683401104832353600012c62656e6566696369617279910101104831363000012873746174655f726f6f74340110483235360001447472616e73616374696f6e735f726f6f743401104832353600013472656365697074735f726f6f74340110483235360001286c6f67735f626c6f6f6d290a0114426c6f6f6d000128646966666963756c7479c9010110553235360001186e756d626572c9010110553235360001246761735f6c696d6974c9010110553235360001206761735f75736564c90101105532353600012474696d657374616d7030010c75363400012865787472615f6461746138011442797465730001206d69785f68617368340110483235360001146e6f6e6365410a010c4836340000410a0c38657468657265756d5f747970657310686173680c48363400000400a902011c5b75383b20385d0000450a0000028d0500490a0000023d0a004d0a000002310a00510a000002210a00550a0c3c70616c6c65745f657468657265756d1870616c6c6574144572726f7204045400010840496e76616c69645369676e6174757265000004545369676e617475726520697320696e76616c69642e305072654c6f67457869737473000104d85072652d6c6f672069732070726573656e742c207468657265666f7265207472616e73616374206973206e6f7420616c6c6f7765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e590a082870616c6c65745f65766d30436f64654d65746164617461000008011073697a6530010c753634000110686173683401104832353600005d0a0000040891013400610a0c2870616c6c65745f65766d1870616c6c6574144572726f720404540001342842616c616e63654c6f77000004904e6f7420656e6f7567682062616c616e636520746f20706572666f726d20616374696f6e2c4665654f766572666c6f770001048043616c63756c6174696e6720746f74616c20666565206f766572666c6f7765643c5061796d656e744f766572666c6f770002049043616c63756c6174696e6720746f74616c207061796d656e74206f766572666c6f7765643857697468647261774661696c65640003044c576974686472617720666565206661696c6564384761735072696365546f6f4c6f770004045447617320707269636520697320746f6f206c6f772e30496e76616c69644e6f6e6365000504404e6f6e636520697320696e76616c6964384761734c696d6974546f6f4c6f7700060454476173206c696d697420697320746f6f206c6f772e3c4761734c696d6974546f6f4869676800070458476173206c696d697420697320746f6f20686967682e38496e76616c6964436861696e49640008046054686520636861696e20696420697320696e76616c69642e40496e76616c69645369676e617475726500090464746865207369676e617475726520697320696e76616c69642e285265656e7472616e6379000a043845564d207265656e7472616e6379685472616e73616374696f6e4d757374436f6d6546726f6d454f41000b04244549502d333630372c24556e646566696e6564000c0440556e646566696e6564206572726f722e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e650a0c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c6574144572726f720404540001045c4d617841646472657373436f756e744578636565646564000004784d6178696d756d206164647265737320636f756e74206578636565646564048054686520604572726f726020656e756d206f6620746869732070616c6c65742e690a0000040830d901006d0a0c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144572726f7204045400012060496e76616c6964457468657265756d5369676e61747572650000046c496e76616c696420457468657265756d207369676e61747572652e58496e76616c69644e61746976655369676e617475726500010488496e76616c6964204e617469766520287372323535313929207369676e617475726550496e76616c69644e61746976654163636f756e740002047c496e76616c6964204e6174697665206163636f756e74206465636f64696e67405369676e65724861734e6f436c61696d00030478457468657265756d206164647265737320686173206e6f20636c61696d2e4053656e6465724861734e6f436c61696d000404b04163636f756e742049442073656e64696e67207472616e73616374696f6e20686173206e6f20636c61696d2e30506f74556e646572666c6f77000508490154686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061306c6f676963206572726f722e40496e76616c696453746174656d656e740006049041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e4c56657374656442616c616e6365457869737473000704a4546865206163636f756e7420616c7265616479206861732061207665737465642062616c616e63652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e710a00000408750a1800750a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401790a0453000004007d0a01185665633c543e0000790a083070616c6c65745f70726f78793c50726f7879446566696e6974696f6e0c244163636f756e74496401002450726f78795479706501e5012c426c6f636b4e756d6265720130000c012064656c65676174650001244163636f756e74496400012870726f78795f74797065e501012450726f78795479706500011464656c617930012c426c6f636b4e756d62657200007d0a000002790a00810a00000408850a1800850a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401890a0453000004008d0a01185665633c543e0000890a083070616c6c65745f70726f787930416e6e6f756e63656d656e740c244163636f756e7449640100104861736801342c426c6f636b4e756d6265720130000c01107265616c0001244163636f756e74496400012463616c6c5f686173683401104861736800011868656967687430012c426c6f636b4e756d62657200008d0a000002890a00910a0c3070616c6c65745f70726f78791870616c6c6574144572726f720404540001201c546f6f4d616e79000004210154686572652061726520746f6f206d616e792070726f786965732072656769737465726564206f7220746f6f206d616e7920616e6e6f756e63656d656e74732070656e64696e672e204e6f74466f756e640001047450726f787920726567697374726174696f6e206e6f7420666f756e642e204e6f7450726f7879000204cc53656e646572206973206e6f7420612070726f7879206f6620746865206163636f756e7420746f2062652070726f786965642e2c556e70726f787961626c650003042101412063616c6c20776869636820697320696e636f6d70617469626c652077697468207468652070726f7879207479706527732066696c7465722077617320617474656d707465642e244475706c69636174650004046c4163636f756e7420697320616c726561647920612070726f78792e304e6f5065726d697373696f6e000504150143616c6c206d6179206e6f74206265206d6164652062792070726f78792062656361757365206974206d617920657363616c617465206974732070726976696c656765732e2c556e616e6e6f756e636564000604d0416e6e6f756e63656d656e742c206966206d61646520617420616c6c2c20776173206d61646520746f6f20726563656e746c792e2c4e6f53656c6650726f78790007046443616e6e6f74206164642073656c662061732070726f78792e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e950a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f724d6574616461746114244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301990a344d6178426c75657072696e7473019d0a001801147374616b6518011c42616c616e636500014064656c65676174696f6e5f636f756e7410010c75333200011c72657175657374a10a01a04f7074696f6e3c4f70657261746f72426f6e644c657373526571756573743c42616c616e63653e3e00012c64656c65676174696f6e73a90a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e000118737461747573b50a01384f70657261746f72537461747573000134626c75657072696e745f696473b90a0178426f756e6465645665633c7533322c204d6178426c75657072696e74733e0000990a085874616e676c655f746573746e65745f72756e74696d65384d617844656c65676174696f6e73000000009d0a085874616e676c655f746573746e65745f72756e74696d65544d61784f70657261746f72426c75657072696e747300000000a10a04184f7074696f6e04045401a50a0108104e6f6e6500000010536f6d650400a50a0000010000a50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f725c4f70657261746f72426f6e644c65737352657175657374041c42616c616e6365011800080118616d6f756e7418011c42616c616e6365000130726571756573745f74696d65100128526f756e64496e6465780000a90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ad0a045300000400b10a01185665633c543e0000ad0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f723444656c656761746f72426f6e640c244163636f756e74496401001c42616c616e636501181c417373657449640118000c012464656c656761746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e0000b10a000002ad0a00b50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72384f70657261746f7253746174757300010c1841637469766500000020496e6163746976650001001c4c656176696e670400100128526f756e64496e64657800020000b90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e0000bd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f72536e617073686f7410244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301990a000801147374616b6518011c42616c616e636500012c64656c65676174696f6e73a90a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e0000c10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f724444656c656761746f724d657461646174611c244163636f756e74496401001c42616c616e636501181c4173736574496401184c4d61785769746864726177526571756573747301c50a384d617844656c65676174696f6e7301990a484d6178556e7374616b65526571756573747301c90a344d6178426c75657072696e7473011106001401206465706f73697473cd0a018442547265654d61703c41737365743c417373657449643e2c2042616c616e63653e00014477697468647261775f7265717565737473d90a010901426f756e6465645665633c5769746864726177526571756573743c417373657449642c2042616c616e63653e2c204d6178576974686472617752657175657374733e00012c64656c65676174696f6e73e50a016901426f756e6465645665633c426f6e64496e666f44656c656761746f723c4163636f756e7449642c2042616c616e63652c20417373657449642c204d6178426c75657072696e74733e0a2c204d617844656c65676174696f6e733e00016864656c656761746f725f756e7374616b655f7265717565737473f10a016d01426f756e6465645665633c426f6e644c657373526571756573743c4163636f756e7449642c20417373657449642c2042616c616e63652c204d6178426c75657072696e74733e2c0a4d6178556e7374616b6552657175657374733e000118737461747573fd0a013c44656c656761746f725374617475730000c50a085874616e676c655f746573746e65745f72756e74696d654c4d61785769746864726177526571756573747300000000c90a085874616e676c655f746573746e65745f72756e74696d65484d6178556e7374616b65526571756573747300000000cd0a042042547265654d617008044b01f10104560118000400d10a000000d10a000002d50a00d50a00000408f1011800d90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401dd0a045300000400e10a01185665633c543e0000dd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c576974686472617752657175657374081c4173736574496401181c42616c616e63650118000c012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e6465780000e10a000002dd0a00e50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e90a045300000400ed0a01185665633c543e0000e90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f7244426f6e64496e666f44656c656761746f7210244163636f756e74496401001c42616c616e636501181c417373657449640118344d6178426c75657072696e7473011106001001206f70657261746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e00014c626c75657072696e745f73656c656374696f6e0d0601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000ed0a000002e90a00f10a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401f50a045300000400f90a01185665633c543e0000f50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c426f6e644c6573735265717565737410244163636f756e74496401001c4173736574496401181c42616c616e63650118344d6178426c75657072696e7473011106001401206f70657261746f720001244163636f756e74496400012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e64657800014c626c75657072696e745f73656c656374696f6e0d0601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000f90a000002f50a00fd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c44656c656761746f7253746174757300010818416374697665000000404c656176696e675363686564756c65640400100128526f756e64496e64657800010000010b000002f10100050b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647330526577617264436f6e666967081c5661756c74496401181c42616c616e636501180008011c636f6e66696773090b01d442547265654d61703c5661756c7449642c20526577617264436f6e666967466f7241737365745661756c743c42616c616e63653e3e00016477686974656c69737465645f626c75657072696e745f696473450401205665633c7533323e0000090b042042547265654d617008044b01180456010d0b000400110b0000000d0b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647364526577617264436f6e666967466f7241737365745661756c74041c42616c616e636501180008010c617079f501011c50657263656e7400010c63617018011c42616c616e63650000110b000002150b00150b00000408180d0b00190b0c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144572726f720404540001c83c416c72656164794f70657261746f720000048c546865206163636f756e7420697320616c726561647920616e206f70657261746f722e28426f6e64546f6f4c6f7700010470546865207374616b6520616d6f756e7420697320746f6f206c6f772e344e6f74416e4f70657261746f720002047c546865206163636f756e74206973206e6f7420616e206f70657261746f722e2843616e6e6f744578697400030460546865206163636f756e742063616e6e6f7420657869742e38416c72656164794c656176696e6700040480546865206f70657261746f7220697320616c7265616479206c656176696e672e484e6f744c656176696e674f70657261746f72000504a8546865206163636f756e74206973206e6f74206c656176696e6720617320616e206f70657261746f722e3c4e6f744c656176696e67526f756e64000604cc54686520726f756e6420646f6573206e6f74206d6174636820746865207363686564756c6564206c6561766520726f756e642e584c656176696e67526f756e644e6f7452656163686564000704644c656176696e6720726f756e64206e6f7420726561636865644c4e6f5363686564756c6564426f6e644c657373000804985468657265206973206e6f207363686564756c656420756e7374616b6520726571756573742e6c426f6e644c657373526571756573744e6f745361746973666965640009049454686520756e7374616b652072657175657374206973206e6f74207361746973666965642e444e6f744163746976654f70657261746f72000a046c546865206f70657261746f72206973206e6f74206163746976652e484e6f744f66666c696e654f70657261746f72000b0470546865206f70657261746f72206973206e6f74206f66666c696e652e40416c726561647944656c656761746f72000c048c546865206163636f756e7420697320616c726561647920612064656c656761746f722e304e6f7444656c656761746f72000d047c546865206163636f756e74206973206e6f7420612064656c656761746f722e70576974686472617752657175657374416c7265616479457869737473000e048841207769746864726177207265717565737420616c7265616479206578697374732e4c496e73756666696369656e7442616c616e6365000f0494546865206163636f756e742068617320696e73756666696369656e742062616c616e63652e444e6f576974686472617752657175657374001004745468657265206973206e6f20776974686472617720726571756573742e444e6f426f6e644c65737352657175657374001104705468657265206973206e6f20756e7374616b6520726571756573742e40426f6e644c6573734e6f7452656164790012048454686520756e7374616b652072657175657374206973206e6f742072656164792e70426f6e644c65737352657175657374416c7265616479457869737473001304844120756e7374616b65207265717565737420616c7265616479206578697374732e6041637469766553657276696365735573696e674173736574001404a854686572652061726520616374697665207365727669636573207573696e67207468652061737365742e484e6f41637469766544656c65676174696f6e001504785468657265206973206e6f74206163746976652064656c65676174696f6e4c41737365744e6f7457686974656c697374656400160470546865206173736574206973206e6f742077686974656c6973746564344e6f74417574686f72697a6564001704cc546865206f726967696e206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e544d6178426c75657072696e74734578636565646564001804944d6178696d756d206e756d626572206f6620626c75657072696e74732065786365656465643441737365744e6f74466f756e6400190464546865206173736574204944206973206e6f7420666f756e646c426c75657072696e74416c726561647957686974656c6973746564001a049c54686520626c75657072696e7420494420697320616c72656164792077686974656c6973746564484e6f77697468647261775265717565737473001b04684e6f20776974686472617720726571756573747320666f756e64644e6f4d61746368696e67776974686472617752657175657374001c04884e6f206d61746368696e67207769746864726177207265716573747320666f756e644c4173736574416c7265616479496e5661756c74001d0498417373657420616c72656164792065786973747320696e206120726577617264207661756c743c41737365744e6f74496e5661756c74001e047c4173736574206e6f7420666f756e6420696e20726577617264207661756c74345661756c744e6f74466f756e64001f047c54686520726577617264207661756c7420646f6573206e6f74206578697374504475706c6963617465426c75657072696e74496400200415014572726f722072657475726e6564207768656e20747279696e6720746f20616464206120626c75657072696e74204944207468617420616c7265616479206578697374732e4c426c75657072696e7449644e6f74466f756e640021041d014572726f722072657475726e6564207768656e20747279696e6720746f2072656d6f7665206120626c75657072696e74204944207468617420646f65736e27742065786973742e384e6f74496e46697865644d6f64650022043d014572726f722072657475726e6564207768656e20747279696e6720746f206164642f72656d6f766520626c75657072696e7420494473207768696c65206e6f7420696e204669786564206d6f64652e584d617844656c65676174696f6e73457863656564656400230409014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662064656c65676174696f6e732069732065786365656465642e684d6178556e7374616b65526571756573747345786365656465640024041d014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f6620756e7374616b652072657175657374732069732065786365656465642e6c4d617857697468647261775265717565737473457863656564656400250421014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662077697468647261772072657175657374732069732065786365656465642e3c4465706f7369744f766572666c6f770026045c4465706f73697420616d6f756e74206f766572666c6f7754556e7374616b65416d6f756e74546f6f4c6172676500270444556e7374616b6520756e646572666c6f77345374616b654f766572666c6f770028046c4f766572666c6f77207768696c6520616464696e67207374616b6568496e73756666696369656e745374616b6552656d61696e696e6700290478556e646572666c6f77207768696c65207265647563696e67207374616b6544415059457863656564734d6178696d756d002a04b04150592065786365656473206d6178696d756d20616c6c6f776564206279207468652065787472696e7369633c43617043616e6e6f7442655a65726f002b04484361702063616e6e6f74206265207a65726f5443617045786365656473546f74616c537570706c79002c0484436170206578636565647320746f74616c20737570706c79206f662061737365746c50656e64696e67556e7374616b6552657175657374457869737473002d0494416e20756e7374616b65207265717565737420697320616c72656164792070656e64696e6750426c75657072696e744e6f7453656c6563746564002e047454686520626c75657072696e74206973206e6f742073656c65637465644c45524332305472616e736665724661696c6564002f04544572633230207472616e73666572206661696c65643045564d416269456e636f64650030044045564d20656e636f6465206572726f723045564d4162694465636f64650031044045564d206465636f6465206572726f7204744572726f727320656d6974746564206279207468652070616c6c65742e1d0b0000040800210600210b00000408300000250b0c4474616e676c655f7072696d69746976657320736572766963657338536572766963655265717565737410044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273290b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e0001186173736574732d0b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d62657200011061726773310b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0001746f70657261746f72735f776974685f617070726f76616c5f7374617465350b010501426f756e6465645665633c284163636f756e7449642c20417070726f76616c5374617465292c20433a3a4d61784f70657261746f7273506572536572766963653e0000290b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e00002d0b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540118045300000400410201185665633c543e0000310b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540111020453000004000d0201185665633c543e0000350b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401390b045300000400410b01185665633c543e0000390b00000408003d0b003d0b0c4474616e676c655f7072696d69746976657320736572766963657334417070726f76616c537461746500010c1c50656e64696e6700000020417070726f76656404014472657374616b696e675f70657263656e74f501011c50657263656e740001002052656a656374656400020000410b000002390b00450b0c4474616e676c655f7072696d6974697665732073657276696365731c5365727669636510044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0108696430010c753634000124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273290b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e0001246f70657261746f7273490b01ec426f756e6465645665633c284163636f756e7449642c2050657263656e74292c20433a3a4d61784f70657261746f7273506572536572766963653e0001186173736574732d0b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d6265720000490b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014d0b045300000400510b01185665633c543e00004d0b0000040800f50100510b0000024d0b00550b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400590b012c42547265655365743c543e0000590b04204254726565536574040454013000040019060000005d0b0c4474616e676c655f7072696d6974697665732073657276696365731c4a6f6243616c6c08044300244163636f756e7449640100000c0128736572766963655f696430010c75363400010c6a6f62080108753800011061726773310b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0000610b0c4474616e676c655f7072696d697469766573207365727669636573344a6f6243616c6c526573756c7408044300244163636f756e7449640100000c0128736572766963655f696430010c75363400011c63616c6c5f696430010c753634000118726573756c74310b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0000650b0c3c70616c6c65745f736572766963657314747970657338556e6170706c696564536c61736808244163636f756e74496401001c42616c616e6365011800180128736572766963655f696430010c7536340001206f70657261746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f72746572733d0201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000690b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019101045300000400cd0501185665633c543e00006d0b0c4474616e676c655f7072696d6974697665732073657276696365733c4f70657261746f7250726f66696c6504044300000801207365727669636573710b01bc426f756e64656442547265655365743c7536342c20433a3a4d617853657276696365735065724f70657261746f723e000128626c75657072696e7473750b01c4426f756e64656442547265655365743c7536342c20433a3a4d6178426c75657072696e74735065724f70657261746f723e0000710b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400590b012c42547265655365743c543e0000750b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400590b012c42547265655365743c543e0000790b0c4474616e676c655f7072696d6974697665732073657276696365735453746167696e67536572766963655061796d656e740c244163636f756e74496401001c4173736574496401181c42616c616e6365011800100128726571756573745f696430010c753634000124726566756e645f746f7d0b01484163636f756e743c4163636f756e7449643e0001146173736574f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500007d0b0c4474616e676c655f7072696d6974697665731474797065731c4163636f756e7404244163636f756e7449640100010808496404000001244163636f756e7449640000001c4164647265737304009101013473705f636f72653a3a4831363000010000810b0c3c70616c6c65745f7365727669636573186d6f64756c65144572726f720404540001ac44426c75657072696e744e6f74466f756e6400000490546865207365727669636520626c75657072696e7420776173206e6f7420666f756e642e70426c75657072696e744372656174696f6e496e74657272757074656400010488426c75657072696e74206372656174696f6e20697320696e7465727275707465642e44416c726561647952656769737465726564000204bc5468652063616c6c657220697320616c726561647920726567697374657265642061732061206f70657261746f722e60496e76616c6964526567697374726174696f6e496e707574000304ec5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2062652061206f70657261746f722e584e6f74416c6c6f776564546f556e7265676973746572000404a8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f20756e72656769737465722e784e6f74416c6c6f776564546f557064617465507269636554617267657473000504e8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f2075706461746520746865697220707269636520746172676574732e4c496e76616c696452657175657374496e707574000604fc5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2072657175657374206120736572766963652e4c496e76616c69644a6f6243616c6c496e707574000704e05468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2063616c6c2061206a6f622e40496e76616c69644a6f62526573756c74000804a85468652063616c6c65722070726f766964656420616e20696e76616c6964206a6f6220726573756c742e344e6f7452656769737465726564000904ac5468652063616c6c6572206973206e6f7420726567697374657265642061732061206f70657261746f722e4c417070726f76616c496e746572727570746564000a0480417070726f76616c2050726f6365737320697320696e7465727275707465642e5052656a656374696f6e496e746572727570746564000b048452656a656374696f6e2050726f6365737320697320696e7465727275707465642e5853657276696365526571756573744e6f74466f756e64000c04885468652073657276696365207265717565737420776173206e6f7420666f756e642e8053657276696365496e697469616c697a6174696f6e496e746572727570746564000d048c5365727669636520496e697469616c697a6174696f6e20696e7465727275707465642e3c536572766963654e6f74466f756e64000e0468546865207365727669636520776173206e6f7420666f756e642e585465726d696e6174696f6e496e746572727570746564000f04bc546865207465726d696e6174696f6e206f662074686520736572766963652077617320696e7465727275707465642e2454797065436865636b0400850b013854797065436865636b4572726f72001004fc416e206572726f72206f63637572726564207768696c65207479706520636865636b696e67207468652070726f766964656420696e70757420696e7075742e6c4d61785065726d697474656443616c6c65727345786365656465640011041901546865206d6178696d756d206e756d626572206f66207065726d69747465642063616c6c65727320706572207365727669636520686173206265656e2065786365656465642e6c4d61785365727669636550726f7669646572734578636565646564001204f8546865206d6178696d756d206e756d626572206f66206f70657261746f727320706572207365727669636520686173206265656e2065786365656465642e684d61785365727669636573506572557365724578636565646564001304e8546865206d6178696d756d206e756d626572206f6620736572766963657320706572207573657220686173206265656e2065786365656465642e444d61784669656c64734578636565646564001404ec546865206d6178696d756d206e756d626572206f66206669656c647320706572207265717565737420686173206265656e2065786365656465642e50417070726f76616c4e6f74526571756573746564001504f054686520617070726f76616c206973206e6f742072657175657374656420666f7220746865206f70657261746f7220287468652063616c6c6572292e544a6f62446566696e6974696f6e4e6f74466f756e6400160cb054686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f742065786973742e590154686973206572726f722069732072657475726e6564207768656e2074686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f7420657869737420696e20746865207365727669636528626c75657072696e742e60536572766963654f724a6f6243616c6c4e6f74466f756e64001704c4456974686572207468652073657276696365206f7220746865206a6f622063616c6c20776173206e6f7420666f756e642e544a6f6243616c6c526573756c744e6f74466f756e64001804a454686520726573756c74206f6620746865206a6f622063616c6c20776173206e6f7420666f756e642e3045564d416269456e636f6465001904b4416e206572726f72206f63637572726564207768696c6520656e636f64696e67207468652045564d204142492e3045564d4162694465636f6465001a04b4416e206572726f72206f63637572726564207768696c65206465636f64696e67207468652045564d204142492e5c4f70657261746f7250726f66696c654e6f74466f756e64001b046c4f70657261746f722070726f66696c65206e6f7420666f756e642e784d6178536572766963657350657250726f76696465724578636565646564001c04c04d6178696d756d206e756d626572206f66207365727669636573207065722050726f766964657220726561636865642e444f70657261746f724e6f74416374697665001d045901546865206f70657261746f72206973206e6f74206163746976652c20656e73757265206f70657261746f72207374617475732069732041435449564520696e206d756c74692d61737365742d64656c65676174696f6e404e6f41737365747350726f7669646564001e040d014e6f206173736574732070726f766964656420666f722074686520736572766963652c206174206c65617374206f6e652061737365742069732072657175697265642e6c4d6178417373657473506572536572766963654578636565646564001f04ec546865206d6178696d756d206e756d626572206f662061737365747320706572207365727669636520686173206265656e2065786365656465642e4c4f6666656e6465724e6f744f70657261746f72002004984f6666656e646572206973206e6f7420612072656769737465726564206f70657261746f722e644f6666656e6465724e6f744163746976654f70657261746f720021048c4f6666656e646572206973206e6f7420616e20616374697665206f70657261746f722e404e6f536c617368696e674f726967696e0022042101546865205365727669636520426c75657072696e7420646964206e6f742072657475726e206120736c617368696e67206f726967696e20666f72207468697320736572766963652e3c4e6f446973707574654f726967696e0023041d01546865205365727669636520426c75657072696e7420646964206e6f742072657475726e20612064697370757465206f726967696e20666f72207468697320736572766963652e58556e6170706c696564536c6173684e6f74466f756e640024048854686520556e6170706c69656420536c61736820617265206e6f7420666f756e642eb44d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64002504110154686520537570706c696564204d617374657220426c75657072696e742053657276696365204d616e61676572205265766973696f6e206973206e6f7420666f756e642ec04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e73457863656564656400260415014d6178696d756d206e756d626572206f66204d617374657220426c75657072696e742053657276696365204d616e61676572207265766973696f6e7320726561636865642e4c45524332305472616e736665724661696c656400270468546865204552433230207472616e73666572206661696c65642e404d697373696e6745564d4f726967696e002804a44d697373696e672045564d204f726967696e20666f72207468652045564d20657865637574696f6e2e48457870656374656445564d41646472657373002904a8457870656374656420746865206163636f756e7420746f20626520616e2045564d20616464726573732e4445787065637465644163636f756e744964002a04a4457870656374656420746865206163636f756e7420746f20626520616e206163636f756e742049442e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e850b0c4474616e676c655f7072696d6974697665732073657276696365733854797065436865636b4572726f7200010c50417267756d656e74547970654d69736d617463680c0114696e64657808010875380001206578706563746564450601244669656c645479706500011861637475616c450601244669656c6454797065000000484e6f74456e6f756768417267756d656e74730801206578706563746564080108753800011861637475616c080108753800010048526573756c74547970654d69736d617463680c0114696e64657808010875380001206578706563746564450601244669656c645479706500011861637475616c450601244669656c645479706500020000890b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c3c426f6e646564506f6f6c496e6e65720404540000100128636f6d6d697373696f6e8d0b0134436f6d6d697373696f6e3c543e000114726f6c6573950b015c506f6f6c526f6c65733c543a3a4163636f756e7449643e000114737461746549020124506f6f6c53746174650001206d65746164617461990b013c506f6f6c4d657461646174613c543e00008d0b104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e28436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784d09013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f72617465910b01bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e0000910b04184f7074696f6e040454014d020108104e6f6e6500000010536f6d6504004d020000010000950b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e0000990b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c30506f6f6c4d6574616461746104045400000801106e616d65f50601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6efd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e00009d0b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e74657295070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e0000a10b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7320537562506f6f6c7304045400000801186e6f5f657261a50b0134556e626f6e64506f6f6c3c543e000120776974685f657261a90b010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e0000a50b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e0000a90b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601a50b045300000400ad0b013842547265654d61703c4b2c20563e0000ad0b042042547265654d617008044b0110045601a50b000400b10b000000b10b000002b50b00b50b0000040810a50b00b90b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000bd0b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7328506f6f6c4d656d6265720404540000040138756e626f6e64696e675f65726173c10b010901426f756e64656442547265654d61703c457261496e6465782c2028506f6f6c49642c2042616c616e63654f663c543e292c20543a3a4d6178556e626f6e64696e673e0000c10b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b01100456014109045300000400c50b013842547265654d61703c4b2c20563e0000c50b042042547265654d617008044b01100456014109000400c90b000000c90b000002cd0b00cd0b0000040810410900d10b0c4470616c6c65745f74616e676c655f6c73741474797065733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000d50b0c4470616c6c65745f74616e676c655f6c73741870616c6c6574144572726f7204045400018430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e3846756c6c79556e626f6e64696e670004083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740005040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790006044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000714290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0008042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e670009085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000a04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000b043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000c047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000d04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000e049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e67655374617465000f048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001004b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001104ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e736976650400d90b0138446566656e736976654572726f720012083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001304bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640014041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001504ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001604e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400170409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640018040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001904a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001a048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001b0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001c049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001d04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001e04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e5c506f6f6c546f6b656e4372656174696f6e4661696c6564001f046c506f6f6c20746f6b656e206372656174696f6e206661696c65642e444e6f42616c616e6365546f556e626f6e64002004544e6f2062616c616e636520746f20756e626f6e642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed90b0c4470616c6c65745f74616e676c655f6c73741870616c6c657438446566656e736976654572726f72000114684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c7900040000dd0b0c4466705f73656c665f636f6e7461696e65644c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c1021043616c6c01b902245369676e617475726501610514457874726101e10b000400110c01250173705f72756e74696d653a3a67656e657269633a3a556e636865636b656445787472696e7369633c416464726573732c2043616c6c2c205369676e61747572652c2045787472610a3e0000e10b00000424e50be90bed0bf10bf50bfd0b010c050c090c00e50b10306672616d655f73797374656d28657874656e73696f6e7354636865636b5f6e6f6e5f7a65726f5f73656e64657248436865636b4e6f6e5a65726f53656e64657204045400000000e90b10306672616d655f73797374656d28657874656e73696f6e7348636865636b5f737065635f76657273696f6e40436865636b5370656356657273696f6e04045400000000ed0b10306672616d655f73797374656d28657874656e73696f6e7340636865636b5f74785f76657273696f6e38436865636b547856657273696f6e04045400000000f10b10306672616d655f73797374656d28657874656e73696f6e7334636865636b5f67656e6573697330436865636b47656e6573697304045400000000f50b10306672616d655f73797374656d28657874656e73696f6e733c636865636b5f6d6f7274616c69747938436865636b4d6f7274616c69747904045400000400f90b010c4572610000f90b102873705f72756e74696d651c67656e657269630c6572610c4572610001010420496d6d6f7274616c0000001c4d6f7274616c31040008000001001c4d6f7274616c32040008000002001c4d6f7274616c33040008000003001c4d6f7274616c34040008000004001c4d6f7274616c35040008000005001c4d6f7274616c36040008000006001c4d6f7274616c37040008000007001c4d6f7274616c38040008000008001c4d6f7274616c3904000800000900204d6f7274616c313004000800000a00204d6f7274616c313104000800000b00204d6f7274616c313204000800000c00204d6f7274616c313304000800000d00204d6f7274616c313404000800000e00204d6f7274616c313504000800000f00204d6f7274616c313604000800001000204d6f7274616c313704000800001100204d6f7274616c313804000800001200204d6f7274616c313904000800001300204d6f7274616c323004000800001400204d6f7274616c323104000800001500204d6f7274616c323204000800001600204d6f7274616c323304000800001700204d6f7274616c323404000800001800204d6f7274616c323504000800001900204d6f7274616c323604000800001a00204d6f7274616c323704000800001b00204d6f7274616c323804000800001c00204d6f7274616c323904000800001d00204d6f7274616c333004000800001e00204d6f7274616c333104000800001f00204d6f7274616c333204000800002000204d6f7274616c333304000800002100204d6f7274616c333404000800002200204d6f7274616c333504000800002300204d6f7274616c333604000800002400204d6f7274616c333704000800002500204d6f7274616c333804000800002600204d6f7274616c333904000800002700204d6f7274616c343004000800002800204d6f7274616c343104000800002900204d6f7274616c343204000800002a00204d6f7274616c343304000800002b00204d6f7274616c343404000800002c00204d6f7274616c343504000800002d00204d6f7274616c343604000800002e00204d6f7274616c343704000800002f00204d6f7274616c343804000800003000204d6f7274616c343904000800003100204d6f7274616c353004000800003200204d6f7274616c353104000800003300204d6f7274616c353204000800003400204d6f7274616c353304000800003500204d6f7274616c353404000800003600204d6f7274616c353504000800003700204d6f7274616c353604000800003800204d6f7274616c353704000800003900204d6f7274616c353804000800003a00204d6f7274616c353904000800003b00204d6f7274616c363004000800003c00204d6f7274616c363104000800003d00204d6f7274616c363204000800003e00204d6f7274616c363304000800003f00204d6f7274616c363404000800004000204d6f7274616c363504000800004100204d6f7274616c363604000800004200204d6f7274616c363704000800004300204d6f7274616c363804000800004400204d6f7274616c363904000800004500204d6f7274616c373004000800004600204d6f7274616c373104000800004700204d6f7274616c373204000800004800204d6f7274616c373304000800004900204d6f7274616c373404000800004a00204d6f7274616c373504000800004b00204d6f7274616c373604000800004c00204d6f7274616c373704000800004d00204d6f7274616c373804000800004e00204d6f7274616c373904000800004f00204d6f7274616c383004000800005000204d6f7274616c383104000800005100204d6f7274616c383204000800005200204d6f7274616c383304000800005300204d6f7274616c383404000800005400204d6f7274616c383504000800005500204d6f7274616c383604000800005600204d6f7274616c383704000800005700204d6f7274616c383804000800005800204d6f7274616c383904000800005900204d6f7274616c393004000800005a00204d6f7274616c393104000800005b00204d6f7274616c393204000800005c00204d6f7274616c393304000800005d00204d6f7274616c393404000800005e00204d6f7274616c393504000800005f00204d6f7274616c393604000800006000204d6f7274616c393704000800006100204d6f7274616c393804000800006200204d6f7274616c393904000800006300244d6f7274616c31303004000800006400244d6f7274616c31303104000800006500244d6f7274616c31303204000800006600244d6f7274616c31303304000800006700244d6f7274616c31303404000800006800244d6f7274616c31303504000800006900244d6f7274616c31303604000800006a00244d6f7274616c31303704000800006b00244d6f7274616c31303804000800006c00244d6f7274616c31303904000800006d00244d6f7274616c31313004000800006e00244d6f7274616c31313104000800006f00244d6f7274616c31313204000800007000244d6f7274616c31313304000800007100244d6f7274616c31313404000800007200244d6f7274616c31313504000800007300244d6f7274616c31313604000800007400244d6f7274616c31313704000800007500244d6f7274616c31313804000800007600244d6f7274616c31313904000800007700244d6f7274616c31323004000800007800244d6f7274616c31323104000800007900244d6f7274616c31323204000800007a00244d6f7274616c31323304000800007b00244d6f7274616c31323404000800007c00244d6f7274616c31323504000800007d00244d6f7274616c31323604000800007e00244d6f7274616c31323704000800007f00244d6f7274616c31323804000800008000244d6f7274616c31323904000800008100244d6f7274616c31333004000800008200244d6f7274616c31333104000800008300244d6f7274616c31333204000800008400244d6f7274616c31333304000800008500244d6f7274616c31333404000800008600244d6f7274616c31333504000800008700244d6f7274616c31333604000800008800244d6f7274616c31333704000800008900244d6f7274616c31333804000800008a00244d6f7274616c31333904000800008b00244d6f7274616c31343004000800008c00244d6f7274616c31343104000800008d00244d6f7274616c31343204000800008e00244d6f7274616c31343304000800008f00244d6f7274616c31343404000800009000244d6f7274616c31343504000800009100244d6f7274616c31343604000800009200244d6f7274616c31343704000800009300244d6f7274616c31343804000800009400244d6f7274616c31343904000800009500244d6f7274616c31353004000800009600244d6f7274616c31353104000800009700244d6f7274616c31353204000800009800244d6f7274616c31353304000800009900244d6f7274616c31353404000800009a00244d6f7274616c31353504000800009b00244d6f7274616c31353604000800009c00244d6f7274616c31353704000800009d00244d6f7274616c31353804000800009e00244d6f7274616c31353904000800009f00244d6f7274616c3136300400080000a000244d6f7274616c3136310400080000a100244d6f7274616c3136320400080000a200244d6f7274616c3136330400080000a300244d6f7274616c3136340400080000a400244d6f7274616c3136350400080000a500244d6f7274616c3136360400080000a600244d6f7274616c3136370400080000a700244d6f7274616c3136380400080000a800244d6f7274616c3136390400080000a900244d6f7274616c3137300400080000aa00244d6f7274616c3137310400080000ab00244d6f7274616c3137320400080000ac00244d6f7274616c3137330400080000ad00244d6f7274616c3137340400080000ae00244d6f7274616c3137350400080000af00244d6f7274616c3137360400080000b000244d6f7274616c3137370400080000b100244d6f7274616c3137380400080000b200244d6f7274616c3137390400080000b300244d6f7274616c3138300400080000b400244d6f7274616c3138310400080000b500244d6f7274616c3138320400080000b600244d6f7274616c3138330400080000b700244d6f7274616c3138340400080000b800244d6f7274616c3138350400080000b900244d6f7274616c3138360400080000ba00244d6f7274616c3138370400080000bb00244d6f7274616c3138380400080000bc00244d6f7274616c3138390400080000bd00244d6f7274616c3139300400080000be00244d6f7274616c3139310400080000bf00244d6f7274616c3139320400080000c000244d6f7274616c3139330400080000c100244d6f7274616c3139340400080000c200244d6f7274616c3139350400080000c300244d6f7274616c3139360400080000c400244d6f7274616c3139370400080000c500244d6f7274616c3139380400080000c600244d6f7274616c3139390400080000c700244d6f7274616c3230300400080000c800244d6f7274616c3230310400080000c900244d6f7274616c3230320400080000ca00244d6f7274616c3230330400080000cb00244d6f7274616c3230340400080000cc00244d6f7274616c3230350400080000cd00244d6f7274616c3230360400080000ce00244d6f7274616c3230370400080000cf00244d6f7274616c3230380400080000d000244d6f7274616c3230390400080000d100244d6f7274616c3231300400080000d200244d6f7274616c3231310400080000d300244d6f7274616c3231320400080000d400244d6f7274616c3231330400080000d500244d6f7274616c3231340400080000d600244d6f7274616c3231350400080000d700244d6f7274616c3231360400080000d800244d6f7274616c3231370400080000d900244d6f7274616c3231380400080000da00244d6f7274616c3231390400080000db00244d6f7274616c3232300400080000dc00244d6f7274616c3232310400080000dd00244d6f7274616c3232320400080000de00244d6f7274616c3232330400080000df00244d6f7274616c3232340400080000e000244d6f7274616c3232350400080000e100244d6f7274616c3232360400080000e200244d6f7274616c3232370400080000e300244d6f7274616c3232380400080000e400244d6f7274616c3232390400080000e500244d6f7274616c3233300400080000e600244d6f7274616c3233310400080000e700244d6f7274616c3233320400080000e800244d6f7274616c3233330400080000e900244d6f7274616c3233340400080000ea00244d6f7274616c3233350400080000eb00244d6f7274616c3233360400080000ec00244d6f7274616c3233370400080000ed00244d6f7274616c3233380400080000ee00244d6f7274616c3233390400080000ef00244d6f7274616c3234300400080000f000244d6f7274616c3234310400080000f100244d6f7274616c3234320400080000f200244d6f7274616c3234330400080000f300244d6f7274616c3234340400080000f400244d6f7274616c3234350400080000f500244d6f7274616c3234360400080000f600244d6f7274616c3234370400080000f700244d6f7274616c3234380400080000f800244d6f7274616c3234390400080000f900244d6f7274616c3235300400080000fa00244d6f7274616c3235310400080000fb00244d6f7274616c3235320400080000fc00244d6f7274616c3235330400080000fd00244d6f7274616c3235340400080000fe00244d6f7274616c3235350400080000ff0000fd0b10306672616d655f73797374656d28657874656e73696f6e732c636865636b5f6e6f6e636528436865636b4e6f6e63650404540000040065020120543a3a4e6f6e63650000010c10306672616d655f73797374656d28657874656e73696f6e7330636865636b5f7765696768742c436865636b57656967687404045400000000050c086870616c6c65745f7472616e73616374696f6e5f7061796d656e74604368617267655472616e73616374696f6e5061796d656e74040454000004006d01013042616c616e63654f663c543e0000090c08746672616d655f6d657461646174615f686173685f657874656e73696f6e44436865636b4d657461646174614861736804045400000401106d6f64650d0c01104d6f646500000d0c08746672616d655f6d657461646174615f686173685f657874656e73696f6e104d6f64650001082044697361626c65640000001c456e61626c656400010000110c102873705f72756e74696d651c67656e657269634c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c1021043616c6c01b902245369676e617475726501610514457874726101e10b00040038000000150c085874616e676c655f746573746e65745f72756e74696d651c52756e74696d6500000000ac1853797374656d011853797374656d481c4163636f756e7401010402000c4101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008004e8205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e3845787472696e736963436f756e74000010040004b820546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e40496e686572656e74734170706c696564010020040004a4205768657468657220616c6c20696e686572656e74732068617665206265656e206170706c6965642e2c426c6f636b576569676874010024180000000000000488205468652063757272656e742077656967687420666f722074686520626c6f636b2e40416c6c45787472696e736963734c656e000010040004410120546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e24426c6f636b486173680101040530348000000000000000000000000000000000000000000000000000000000000000000498204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e3445787472696e736963446174610101040510380400043d012045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e184e756d626572010030200000000000000000040901205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e28506172656e744861736801003480000000000000000000000000000000000000000000000000000000000000000004702048617368206f66207468652070726576696f757320626c6f636b2e1844696765737401003c040004f020446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e184576656e747301004c04001ca0204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e001d01204e4f54453a20546865206974656d20697320756e626f756e6420616e642073686f756c64207468657265666f7265206e657665722062652072656164206f6e20636861696e2ed020497420636f756c64206f746865727769736520696e666c6174652074686520506f562073697a65206f66206120626c6f636b2e002d01204576656e747320686176652061206c6172676520696e2d6d656d6f72792073697a652e20426f7820746865206576656e747320746f206e6f7420676f206f75742d6f662d6d656d6f7279fc206a75737420696e206361736520736f6d656f6e65207374696c6c207265616473207468656d2066726f6d2077697468696e207468652072756e74696d652e284576656e74436f756e74010010100000000004b820546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e2c4576656e74546f7069637301010402345d020400282501204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e646578657394206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e00510120416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e2054686973450120616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e64e420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e005901205468652076616c756520686173207468652074797065206028426c6f636b4e756d626572466f723c543e2c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573744d012074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b0101206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e484c61737452756e74696d65557067726164650000610204000455012053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e545570677261646564546f553332526566436f756e740100200400044d012054727565206966207765206861766520757067726164656420736f207468617420607479706520526566436f756e74602069732060753332602e2046616c7365202864656661756c7429206966206e6f742e605570677261646564546f547269706c65526566436f756e740100200400085d012054727565206966207765206861766520757067726164656420736f2074686174204163636f756e74496e666f20636f6e7461696e73207468726565207479706573206f662060526566436f756e74602e2046616c736548202864656661756c7429206966206e6f742e38457865637574696f6e506861736500005902040004882054686520657865637574696f6e207068617365206f662074686520626c6f636b2e44417574686f72697a65645570677261646500006902040004b82060536f6d6560206966206120636f6465207570677261646520686173206265656e20617574686f72697a65642e016d0201581830426c6f636b576569676874737d02f901624d186c000b00204aa9d10113ffffffffffffffff4247871900010b30f6a7a72e011366666666666666a6010b0098f73e5d0113ffffffffffffffbf0100004247871900010b307efa11a3011366666666666666e6010b00204aa9d10113ffffffffffffffff01070088526a74130000000000000040424787190000000004d020426c6f636b20262065787472696e7369637320776569676874733a20626173652076616c75657320616e64206c696d6974732e2c426c6f636b4c656e6774688d023000003c00000050000000500004a820546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e38426c6f636b48617368436f756e7430200001000000000000045501204d6178696d756d206e756d626572206f6620626c6f636b206e756d62657220746f20626c6f636b2068617368206d617070696e677320746f206b65657020286f6c64657374207072756e6564206669727374292e20446257656967687495024040787d010000000000e1f505000000000409012054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e1c56657273696f6e9902c1033874616e676c652d746573746e65743874616e676c652d746573746e657401000000b30400000100000040df6acb689907609b0500000037e397fc7c91f5e40200000040fe3ad401f8959a060000009bbaa777b4c15fc401000000582211f65bb14b8905000000e65b00e46cedd0aa02000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000cbca25e39f14238702000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000ed99c5acb25eedf503000000bd78255d4feeea1f06000000a33d43f58731ad8402000000fbc577b9d747efd60100000001000000000484204765742074686520636861696e277320696e2d636f64652076657273696f6e2e2853533538507265666978e901082a0014a8205468652064657369676e61746564205353353820707265666978206f66207468697320636861696e2e0039012054686973207265706c6163657320746865202273733538466f726d6174222070726f7065727479206465636c6172656420696e2074686520636861696e20737065632e20526561736f6e20697331012074686174207468652072756e74696d652073686f756c64206b6e6f772061626f7574207468652070726566697820696e206f7264657220746f206d616b6520757365206f662069742061737020616e206964656e746966696572206f662074686520636861696e2e01ad02012454696d657374616d70012454696d657374616d70080c4e6f7701003020000000000000000004a0205468652063757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e24446964557064617465010020040010d82057686574686572207468652074696d657374616d7020686173206265656e207570646174656420696e207468697320626c6f636b2e00550120546869732076616c7565206973207570646174656420746f206074727565602075706f6e207375636365737366756c207375626d697373696f6e206f6620612074696d657374616d702062792061206e6f64652e4501204974206973207468656e20636865636b65642061742074686520656e64206f66206561636820626c6f636b20657865637574696f6e20696e2074686520606f6e5f66696e616c697a656020686f6f6b2e01b1020004344d696e696d756d506572696f643020b80b000000000000188c20546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e004d012042652061776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e4901206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f61012064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20466f72206578616d706c652c20696e2074686520417572612070616c6c65742069742077696c6c20626520646f75626c6520746869737020706572696f64206f6e2064656661756c742073657474696e67732e0002105375646f01105375646f040c4b6579000000040004842054686520604163636f756e74496460206f6620746865207375646f206b65792e01b502017c00011507036052616e646f6d6e657373436f6c6c656374697665466c6970016052616e646f6d6e657373436f6c6c656374697665466c6970043852616e646f6d4d6174657269616c0100190704000c610120536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e2054686973610120697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f664420746865206f6c6465737420686173682e00000000041841737365747301184173736574731414417373657400010402181d07040004542044657461696c73206f6620616e2061737365742e1c4163636f756e74000108020225072907040004e42054686520686f6c64696e6773206f662061207370656369666963206163636f756e7420666f7220612073706563696669632061737365742e24417070726f76616c7300010c0202023507390704000c590120417070726f7665642062616c616e6365207472616e73666572732e2046697273742062616c616e63652069732074686520616d6f756e7420617070726f76656420666f72207472616e736665722e205365636f6e64e82069732074686520616d6f756e74206f662060543a3a43757272656e63796020726573657276656420666f722073746f72696e6720746869732e4901204669727374206b6579206973207468652061737365742049442c207365636f6e64206b657920697320746865206f776e657220616e64207468697264206b6579206973207468652064656c65676174652e204d6574616461746101010402183d075000000000000000000000000000000000000000000458204d65746164617461206f6620616e2061737365742e2c4e657874417373657449640000180400246d012054686520617373657420494420656e666f7263656420666f7220746865206e657874206173736574206372656174696f6e2c20696620616e792070726573656e742e204f74686572776973652c20746869732073746f7261676550206974656d20686173206e6f206566666563742e00650120546869732063616e2062652075736566756c20666f722073657474696e6720757020636f6e73747261696e747320666f7220494473206f6620746865206e6577206173736574732e20466f72206578616d706c652c20627969012070726f766964696e6720616e20696e697469616c205b604e65787441737365744964605d20616e64207573696e6720746865205b6063726174653a3a4175746f496e6341737365744964605d2063616c6c6261636b2c20616ee8206175746f2d696e6372656d656e74206d6f64656c2063616e206265206170706c69656420746f20616c6c206e6577206173736574204944732e0021012054686520696e697469616c206e6578742061737365742049442063616e20626520736574207573696e6720746865205b6047656e65736973436f6e666967605d206f72207468652101205b5365744e657874417373657449645d28606d6967726174696f6e3a3a6e6578745f61737365745f69643a3a5365744e657874417373657449646029206d6967726174696f6e2e01bd02018c1c4052656d6f76654974656d734c696d69741010e80300000c5101204d6178206e756d626572206f66206974656d7320746f2064657374726f7920706572206064657374726f795f6163636f756e74736020616e64206064657374726f795f617070726f76616c73602063616c6c2e003901204d75737420626520636f6e6669677572656420746f20726573756c7420696e2061207765696768742074686174206d616b657320656163682063616c6c2066697420696e206120626c6f636b2e3041737365744465706f73697418400000e8890423c78a000000000000000004f82054686520626173696320616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f7220616e2061737365742e4c41737365744163636f756e744465706f73697418400000e8890423c78a00000000000000000845012054686520616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f722061206e6f6e2d70726f7669646572206173736574206163636f756e7420746f20626530206d61696e7461696e65642e4c4d657461646174614465706f736974426173651840000054129336377505000000000000000451012054686520626173696320616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e20616464696e67206d6574616461746120746f20796f75722061737365742e584d657461646174614465706f7369745065724279746518400000c16ff2862300000000000000000008550120546865206164646974696f6e616c2066756e64732074686174206d75737420626520726573657276656420666f7220746865206e756d626572206f6620627974657320796f752073746f726520696e20796f757228206d657461646174612e3c417070726f76616c4465706f736974184000e40b540200000000000000000000000421012054686520616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e206372656174696e672061206e657720617070726f76616c2e2c537472696e674c696d697410103200000004e020546865206d6178696d756d206c656e677468206f662061206e616d65206f722073796d626f6c2073746f726564206f6e2d636861696e2e014507052042616c616e636573012042616c616e6365731c34546f74616c49737375616e6365010018400000000000000000000000000000000004982054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e40496e61637469766549737375616e636501001840000000000000000000000000000000000409012054686520746f74616c20756e697473206f66206f75747374616e64696e672064656163746976617465642062616c616e636520696e207468652073797374656d2e1c4163636f756e74010104020014010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080600901205468652042616c616e6365732070616c6c6574206578616d706c65206f662073746f72696e67207468652062616c616e6365206f6620616e206163636f756e742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b19022020202074797065204163636f756e7453746f7265203d2053746f726167654d61705368696d3c53656c663a3a4163636f756e743c52756e74696d653e2c206672616d655f73797374656d3a3a50726f76696465723c52756e74696d653e2c204163636f756e7449642c2053656c663a3a4163636f756e74446174613c42616c616e63653e3e0c20207d102060606000150120596f752063616e20616c736f2073746f7265207468652062616c616e6365206f6620616e206163636f756e7420696e20746865206053797374656d602070616c6c65742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b7420202074797065204163636f756e7453746f7265203d2053797374656d0c20207d102060606000510120427574207468697320636f6d657320776974682074726164656f6666732c2073746f72696e67206163636f756e742062616c616e63657320696e207468652073797374656d2070616c6c65742073746f7265736d0120606672616d655f73797374656d60206461746120616c6f6e677369646520746865206163636f756e74206461746120636f6e747261727920746f2073746f72696e67206163636f756e742062616c616e63657320696e207468652901206042616c616e636573602070616c6c65742c20776869636820757365732061206053746f726167654d61706020746f2073746f72652062616c616e6365732064617461206f6e6c792e4101204e4f54453a2054686973206973206f6e6c79207573656420696e207468652063617365207468617420746869732070616c6c6574206973207573656420746f2073746f72652062616c616e6365732e144c6f636b7301010402004907040010b820416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2501204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602052657365727665730101040200590704000ca4204e616d6564207265736572766573206f6e20736f6d65206163636f756e742062616c616e6365732e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f6014486f6c6473010104020065070400046c20486f6c6473206f6e206163636f756e742062616c616e6365732e1c467265657a6573010104020079070400048820467265657a65206c6f636b73206f6e206163636f756e742062616c616e6365732e01c502019010484578697374656e7469616c4465706f736974184000e40b5402000000000000000000000020410120546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e204d5553542042452047524541544552205448414e205a45524f2100590120496620796f75202a7265616c6c792a206e65656420697420746f206265207a65726f2c20796f752063616e20656e61626c652074686520666561747572652060696e7365637572655f7a65726f5f65646020666f72610120746869732070616c6c65742e20486f77657665722c20796f7520646f20736f20617420796f7572206f776e207269736b3a20746869732077696c6c206f70656e2075702061206d616a6f7220446f5320766563746f722e590120496e206361736520796f752068617665206d756c7469706c6520736f7572636573206f662070726f7669646572207265666572656e6365732c20796f75206d617920616c736f2067657420756e65787065637465648c206265686176696f757220696620796f7520736574207468697320746f207a65726f2e00f020426f74746f6d206c696e653a20446f20796f757273656c662061206661766f757220616e64206d616b65206974206174206c65617374206f6e6521204d61784c6f636b7310103200000010f420546865206d6178696d756d206e756d626572206f66206c6f636b7320746861742073686f756c64206578697374206f6e20616e206163636f756e742edc204e6f74207374726963746c7920656e666f726365642c20627574207573656420666f722077656967687420657374696d6174696f6e2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602c4d617852657365727665731010320000000c0d0120546865206d6178696d756d206e756d626572206f66206e616d656420726573657276657320746861742063616e206578697374206f6e20616e206163636f756e742e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f60284d6178467265657a657310103200000004610120546865206d6178696d756d206e756d626572206f6620696e646976696475616c20667265657a65206c6f636b7320746861742063616e206578697374206f6e20616e206163636f756e7420617420616e792074696d652e01910706485472616e73616374696f6e5061796d656e7401485472616e73616374696f6e5061796d656e7408444e6578744665654d756c7469706c6965720100950740000064a7b3b6e00d0000000000000000003853746f7261676556657273696f6e0100990704000000019804604f7065726174696f6e616c4665654d756c7469706c696572080405545901204120666565206d756c7469706c69657220666f7220604f7065726174696f6e616c602065787472696e7369637320746f20636f6d7075746520227669727475616c207469702220746f20626f6f73742074686569722c20607072696f726974796000510120546869732076616c7565206973206d756c7469706c69656420627920746865206066696e616c5f6665656020746f206f627461696e206120227669727475616c20746970222074686174206973206c61746572f420616464656420746f20612074697020636f6d706f6e656e7420696e20726567756c617220607072696f72697479602063616c63756c6174696f6e732e4d01204974206d65616e732074686174206120604e6f726d616c60207472616e73616374696f6e2063616e2066726f6e742d72756e20612073696d696c61726c792d73697a656420604f7065726174696f6e616c6041012065787472696e736963202877697468206e6f20746970292c20627920696e636c7564696e672061207469702076616c75652067726561746572207468616e20746865207669727475616c207469702e003c20606060727573742c69676e6f726540202f2f20466f7220604e6f726d616c608c206c6574207072696f72697479203d207072696f726974795f63616c6328746970293b0054202f2f20466f7220604f7065726174696f6e616c601101206c6574207669727475616c5f746970203d2028696e636c7573696f6e5f666565202b2074697029202a204f7065726174696f6e616c4665654d756c7469706c6965723bc4206c6574207072696f72697479203d207072696f726974795f63616c6328746970202b207669727475616c5f746970293b1020606060005101204e6f746520746861742073696e636520776520757365206066696e616c5f6665656020746865206d756c7469706c696572206170706c69657320616c736f20746f2074686520726567756c61722060746970605d012073656e74207769746820746865207472616e73616374696f6e2e20536f2c206e6f74206f6e6c7920646f657320746865207472616e73616374696f6e206765742061207072696f726974792062756d702062617365646101206f6e207468652060696e636c7573696f6e5f666565602c2062757420776520616c736f20616d706c6966792074686520696d70616374206f662074697073206170706c69656420746f20604f7065726174696f6e616c6038207472616e73616374696f6e732e000728417574686f72736869700128417574686f72736869700418417574686f720000000400046420417574686f72206f662063757272656e7420626c6f636b2e00000000081042616265011042616265442845706f6368496e64657801003020000000000000000004542043757272656e742065706f636820696e6465782e2c417574686f72697469657301009d070400046c2043757272656e742065706f636820617574686f7269746965732e2c47656e65736973536c6f740100dd0220000000000000000008f82054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e205468697320697320309020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2c43757272656e74536c6f740100dd0220000000000000000004542043757272656e7420736c6f74206e756d6265722e2852616e646f6d6e65737301000480000000000000000000000000000000000000000000000000000000000000000028b8205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e002c20232053656375726974790005012054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061f8206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e7915012063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d6265727320746861742074686973150120286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e206265050120757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e0d01206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e6050656e64696e6745706f6368436f6e6669674368616e67650000e50204000461012050656e64696e672065706f636820636f6e66696775726174696f6e206368616e676520746861742077696c6c206265206170706c696564207768656e20746865206e6578742065706f636820697320656e61637465642e384e65787452616e646f6d6e657373010004800000000000000000000000000000000000000000000000000000000000000000045c204e6578742065706f63682072616e646f6d6e6573732e3c4e657874417574686f72697469657301009d0704000460204e6578742065706f636820617574686f7269746965732e305365676d656e74496e6465780100101000000000247c2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e00f8205765206d616b6520612074726164652d6f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e01012057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f942060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e00ec204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e090120576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572791c2065706f63682e44556e646572436f6e737472756374696f6e0101040510a90704000415012054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2c496e697469616c697a65640000b10704000801012054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d65601d01206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e4c417574686f7256726652616e646f6d6e65737301003d0104001015012054686973206669656c642073686f756c6420616c7761797320626520706f70756c6174656420647572696e6720626c6f636b2070726f63657373696e6720756e6c6573731901207365636f6e6461727920706c61696e20736c6f74732061726520656e61626c65642028776869636820646f6e277420636f6e7461696e206120565246206f7574707574292e0049012049742069732073657420696e20606f6e5f66696e616c697a65602c206265666f72652069742077696c6c20636f6e7461696e207468652076616c75652066726f6d20746865206c61737420626c6f636b2e2845706f636853746172740100e9024000000000000000000000000000000000145d012054686520626c6f636b206e756d62657273207768656e20746865206c61737420616e642063757272656e742065706f6368206861766520737461727465642c20726573706563746976656c7920604e2d316020616e641420604e602e4901204e4f54453a20576520747261636b207468697320697320696e206f7264657220746f20616e6e6f746174652074686520626c6f636b206e756d626572207768656e206120676976656e20706f6f6c206f66590120656e74726f7079207761732066697865642028692e652e20697420776173206b6e6f776e20746f20636861696e206f6273657276657273292e2053696e63652065706f6368732061726520646566696e656420696e590120736c6f74732c207768696368206d617920626520736b69707065642c2074686520626c6f636b206e756d62657273206d6179206e6f74206c696e6520757020776974682074686520736c6f74206e756d626572732e204c6174656e65737301003020000000000000000014d820486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e001501205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e65642075701101206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636bb020657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2c45706f6368436f6e6669670000c90704000861012054686520636f6e66696775726174696f6e20666f72207468652063757272656e742065706f63682e2053686f756c64206e6576657220626520604e6f6e656020617320697420697320696e697469616c697a656420696e242067656e657369732e3c4e65787445706f6368436f6e6669670000c9070400082d012054686520636f6e66696775726174696f6e20666f7220746865206e6578742065706f63682c20604e6f6e65602069662074686520636f6e6669672077696c6c206e6f74206368616e6765e82028796f752063616e2066616c6c6261636b20746f206045706f6368436f6e6669676020696e737465616420696e20746861742063617365292e34536b697070656445706f6368730100cd0704002029012041206c697374206f6620746865206c6173742031303020736b69707065642065706f63687320616e642074686520636f72726573706f6e64696e672073657373696f6e20696e64657870207768656e207468652065706f63682077617320736b69707065642e0031012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f663501206d75737420636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e656564206139012077617920746f2074696520746f6765746865722073657373696f6e7320616e642065706f636820696e64696365732c20692e652e207765206e65656420746f2076616c69646174652074686174290120612076616c696461746f722077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e64207768617420746865b0206163746976652065706f636820696e6465782077617320647572696e6720746861742073657373696f6e2e01cd0200103445706f63684475726174696f6e3020b0040000000000000cec2054686520616d6f756e74206f662074696d652c20696e20736c6f74732c207468617420656163682065706f63682073686f756c64206c6173742e1901204e4f54453a2043757272656e746c79206974206973206e6f7420706f737369626c6520746f206368616e6765207468652065706f6368206475726174696f6e20616674657221012074686520636861696e2068617320737461727465642e20417474656d7074696e6720746f20646f20736f2077696c6c20627269636b20626c6f636b2070726f64756374696f6e2e444578706563746564426c6f636b54696d653020701700000000000014050120546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e67110120626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f75740501207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f740901206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473a0207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e384d6178417574686f7269746965731010e80300000488204d6178206e756d626572206f6620617574686f72697469657320616c6c6f776564344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e01d107091c4772616e647061011c4772616e6470611c1453746174650100d50704000490205374617465206f66207468652063757272656e7420617574686f72697479207365742e3450656e64696e674368616e67650000d907040004c42050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e284e657874466f72636564000030040004bc206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e1c5374616c6c65640000e9020400049020607472756560206966207765206172652063757272656e746c79207374616c6c65642e3043757272656e745365744964010030200000000000000000085d0120546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c697469657329c420696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e30536574496453657373696f6e00010405301004002859012041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f722077686963682069747368206d656d62657273207765726520726573706f6e7369626c652e0045012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f66206d7573744d0120636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e65656420612077617920746f20746965450120746f6765746865722073657373696f6e7320616e64204752414e44504120736574206964732c20692e652e207765206e65656420746f2076616c6964617465207468617420612076616c696461746f7241012077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e642077686174207468652061637469766520736574204944207761735420647572696e6720746861742073657373696f6e2e00b82054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e2c417574686f7269746965730100dd0704000484205468652063757272656e74206c697374206f6620617574686f7269746965732e01f102019c0c384d6178417574686f7269746965731010e8030000045c204d617820417574686f72697469657320696e20757365344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e584d6178536574496453657373696f6e456e74726965733020000000000000000018390120546865206d6178696d756d206e756d626572206f6620656e747269657320746f206b65657020696e207468652073657420696420746f2073657373696f6e20696e646578206d617070696e672e0031012053696e6365207468652060536574496453657373696f6e60206d6170206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e73207468697329012076616c75652073686f756c642072656c61746520746f2074686520626f6e64696e67206475726174696f6e206f66207768617465766572207374616b696e672073797374656d2069733501206265696e6720757365642028696620616e79292e2049662065717569766f636174696f6e2068616e646c696e67206973206e6f7420656e61626c6564207468656e20746869732076616c7565342063616e206265207a65726f2e01e1070a1c496e6469636573011c496e646963657304204163636f756e74730001040210e5070400048820546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e01210301ac041c4465706f7369741840000064a7b3b6e00d000000000000000004ac20546865206465706f736974206e656564656420666f7220726573657276696e6720616e20696e6465782e01e9070b2444656d6f6372616379012444656d6f6372616379303c5075626c696350726f70436f756e74010010100000000004f420546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e2c5075626c696350726f70730100ed07040004050120546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c2e244465706f7369744f660001040510f90704000c842054686f73652077686f2068617665206c6f636b65642061206465706f7369742e00d82054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e3c5265666572656e64756d436f756e74010010100000000004310120546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e344c6f77657374556e62616b6564010010100000000008250120546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746fdc20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e405265666572656e64756d496e666f4f660001040510fd0704000cb420496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e0009012054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20566f74696e674f6601010405000908e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105d0120416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077655d012068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e00e82054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e544c6173745461626c656457617345787465726e616c0100200400085901205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c6963282070726f706f73616c2e304e65787445787465726e616c00002108040010590120546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e550120546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743aa4202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f7268202d20605075626c696350726f70736020697320656d7074792e24426c61636b6c6973740001040634250804000851012041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d626572e82028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e3443616e63656c6c6174696f6e730101040634200400042901205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e284d657461646174614f6600010402c034040018ec2047656e6572616c20696e666f726d6174696f6e20636f6e6365726e696e6720616e792070726f706f73616c206f72207265666572656e64756d2e490120546865206048617368602072656665727320746f2074686520707265696d616765206f66207468652060507265696d61676573602070726f76696465722077686963682063616e2062652061204a534f4e882064756d70206f7220495046532068617368206f662061204a534f4e2066696c652e00750120436f6e73696465722061206761726261676520636f6c6c656374696f6e20666f722061206d65746164617461206f662066696e6973686564207265666572656e64756d7320746f2060756e7265717565737460202872656d6f76652944206c6172676520707265696d616765732e01250301b0303c456e6163746d656e74506572696f643020c0a800000000000014e82054686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e0031012049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e737572652074686174510120766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365b4207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e304c61756e6368506572696f643020201c00000000000004e420486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e30566f74696e67506572696f643020c08901000000000004b820486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e44566f74654c6f636b696e67506572696f643020c0a8000000000000109020546865206d696e696d756d20706572696f64206f6620766f7465206c6f636b696e672e0065012049742073686f756c64206265206e6f2073686f72746572207468616e20656e6163746d656e7420706572696f6420746f20656e73757265207468617420696e207468652063617365206f6620616e20617070726f76616c2c49012074686f7365207375636365737366756c20766f7465727320617265206c6f636b656420696e746f2074686520636f6e73657175656e636573207468617420746865697220766f74657320656e7461696c2e384d696e696d756d4465706f73697418400000a0dec5adc935360000000000000004350120546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e38496e7374616e74416c6c6f7765642004010c550120496e64696361746f7220666f72207768657468657220616e20656d657267656e6379206f726967696e206973206576656e20616c6c6f77656420746f2068617070656e2e20536f6d6520636861696e73206d617961012077616e7420746f207365742074686973207065726d616e656e746c7920746f206066616c7365602c206f7468657273206d61792077616e7420746f20636f6e646974696f6e206974206f6e207468696e67732073756368a020617320616e207570677261646520686176696e672068617070656e656420726563656e746c792e5446617374547261636b566f74696e67506572696f643020807000000000000004ec204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f72206120666173742d747261636b207265666572656e64756d2e34436f6f6c6f6666506572696f643020c0a800000000000004610120506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d6178566f74657310106400000010b020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e00d420416c736f207573656420746f20636f6d70757465207765696768742c20616e206f7665726c79206269672076616c75652063616e1501206c65616420746f2065787472696e7369632077697468207665727920626967207765696768743a20736565206064656c65676174656020666f7220696e7374616e63652e304d617850726f706f73616c73101064000000040d0120546865206d6178696d756d206e756d626572206f66207075626c69632070726f706f73616c7320746861742063616e20657869737420617420616e792074696d652e2c4d61784465706f73697473101064000000041d0120546865206d6178696d756d206e756d626572206f66206465706f736974732061207075626c69632070726f706f73616c206d6179206861766520617420616e792074696d652e384d6178426c61636b6c697374656410106400000004d820546865206d6178696d756d206e756d626572206f66206974656d732077686963682063616e20626520626c61636b6c69737465642e0129080c1c436f756e63696c011c436f756e63696c182450726f706f73616c7301002d08040004902054686520686173686573206f6620746865206163746976652070726f706f73616c732e2850726f706f73616c4f660001040634b902040004cc2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e18566f74696e6700010406343108040004b420566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e3450726f706f73616c436f756e74010010100000000004482050726f706f73616c7320736f206661722e1c4d656d6265727301003d020400043901205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e145072696d65000000040004610120546865207072696d65206d656d62657220746861742068656c70732064657465726d696e65207468652064656661756c7420766f7465206265686176696f7220696e2063617365206f662061627374656e74696f6e732e01410301c404444d617850726f706f73616c576569676874283c070010a5d4e813ffffffffffffff7f04250120546865206d6178696d756d20776569676874206f6620612064697370617463682063616c6c20746861742063616e2062652070726f706f73656420616e642065786563757465642e0135080d1c56657374696e67011c56657374696e67081c56657374696e6700010402003908040004d820496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e3853746f7261676556657273696f6e0100410804000c7c2053746f726167652076657273696f6e206f66207468652070616c6c65742e003101204e6577206e6574776f726b732073746172742077697468206c61746573742076657273696f6e2c2061732064657465726d696e6564206279207468652067656e65736973206275696c642e01450301c808444d696e5665737465645472616e736665721840000010632d5ec76b050000000000000004e820546865206d696e696d756d20616d6f756e74207472616e7366657272656420746f2063616c6c20607665737465645f7472616e73666572602e4c4d617856657374696e675363686564756c657310101c000000000145080e24456c656374696f6e730124456c656374696f6e73141c4d656d626572730100490804000c74205468652063757272656e7420656c6563746564206d656d626572732e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e2452756e6e65727355700100490804001084205468652063757272656e742072657365727665642072756e6e6572732d75702e00590120496e76617269616e743a20416c7761797320736f72746564206261736564206f6e2072616e6b2028776f72736520746f2062657374292e2055706f6e2072656d6f76616c206f662061206d656d6265722c20746865bc206c6173742028692e652e205f626573745f292072756e6e65722d75702077696c6c206265207265706c616365642e2843616e646964617465730100d00400185901205468652070726573656e742063616e646964617465206c6973742e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f72d020616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e007c205365636f6e6420656c656d656e7420697320746865206465706f7369742e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e38456c656374696f6e526f756e647301001010000000000441012054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e18566f74696e6701010405005108840000000000000000000000000000000000000000000000000000000000000000000cb820566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e00c42054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682e014d0301cc282050616c6c65744964a90220706872656c65637404d0204964656e74696669657220666f722074686520656c656374696f6e732d70687261676d656e2070616c6c65742773206c6f636b3443616e646964616379426f6e6418400000a0dec5adc935360000000000000004050120486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e38566f74696e67426f6e6442617365184000005053c91aa974050000000000000010942042617365206465706f736974206173736f636961746564207769746820766f74696e672e00550120546869732073686f756c642062652073656e7369626c79206869676820746f2065636f6e6f6d6963616c6c7920656e73757265207468652070616c6c65742063616e6e6f742062652061747461636b656420627994206372656174696e67206120676967616e746963206e756d626572206f6620766f7465732e40566f74696e67426f6e64466163746f721840000020f84dde700400000000000000000411012054686520616d6f756e74206f6620626f6e642074686174206e65656420746f206265206c6f636b656420666f72206561636820766f746520283332206279746573292e38446573697265644d656d626572731010050000000470204e756d626572206f66206d656d6265727320746f20656c6563742e404465736972656452756e6e65727355701010030000000478204e756d626572206f662072756e6e6572735f757020746f206b6565702e305465726d4475726174696f6e3020c0890100000000000c510120486f77206c6f6e6720656163682073656174206973206b6570742e205468697320646566696e657320746865206e65787420626c6f636b206e756d62657220617420776869636820616e20656c656374696f6e5d0120726f756e642077696c6c2068617070656e2e2049662073657420746f207a65726f2c206e6f20656c656374696f6e732061726520657665722074726967676572656420616e6420746865206d6f64756c652077696c6c5020626520696e2070617373697665206d6f64652e344d617843616e6469646174657310104000000018e420546865206d6178696d756d206e756d626572206f662063616e6469646174657320696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e003101205768656e2074686973206c696d69742069732072656163686564206e6f206d6f72652063616e646964617465732061726520616363657074656420696e2074686520656c656374696f6e2e244d6178566f7465727310100002000018f820546865206d6178696d756d206e756d626572206f6620766f7465727320746f20616c6c6f7720696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e00d8205768656e20746865206c696d6974206973207265616368656420746865206e657720766f74657273206172652069676e6f7265642e404d6178566f746573506572566f7465721010640000001090204d6178696d756d206e756d62657273206f6620766f7465732070657220766f7465722e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e0155080f68456c656374696f6e50726f76696465724d756c746950686173650168456c656374696f6e50726f76696465724d756c746950686173652814526f756e64010010100100000018ac20496e7465726e616c20636f756e74657220666f7220746865206e756d626572206f6620726f756e64732e00550120546869732069732075736566756c20666f722064652d6475706c69636174696f6e206f66207472616e73616374696f6e73207375626d697474656420746f2074686520706f6f6c2c20616e642067656e6572616c6c20646961676e6f7374696373206f66207468652070616c6c65742e004d012054686973206973206d6572656c7920696e6372656d656e746564206f6e6365207065722065766572792074696d65207468617420616e20757073747265616d2060656c656374602069732063616c6c65642e3043757272656e7450686173650100e40400043c2043757272656e742070686173652e38517565756564536f6c7574696f6e0000590804000c3d012043757272656e74206265737420736f6c7574696f6e2c207369676e6564206f7220756e7369676e65642c2071756575656420746f2062652072657475726e65642075706f6e2060656c656374602e006020416c7761797320736f727465642062792073636f72652e20536e617073686f74000061080400107020536e617073686f742064617461206f662074686520726f756e642e005d01205468697320697320637265617465642061742074686520626567696e6e696e67206f6620746865207369676e656420706861736520616e6420636c65617265642075706f6e2063616c6c696e672060656c656374602e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e384465736972656454617267657473000010040010cc2044657369726564206e756d626572206f66207461726765747320746f20656c65637420666f72207468697320726f756e642e00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e40536e617073686f744d65746164617461000029040400109820546865206d65746164617461206f6620746865205b60526f756e64536e617073686f74605d00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e645369676e65645375626d697373696f6e4e657874496e646578010010100000000024010120546865206e65787420696e64657820746f2062652061737369676e656420746f20616e20696e636f6d696e67207369676e6564207375626d697373696f6e2e007501204576657279206163636570746564207375626d697373696f6e2069732061737369676e6564206120756e6971756520696e6465783b207468617420696e64657820697320626f756e6420746f207468617420706172746963756c61726501207375626d697373696f6e20666f7220746865206475726174696f6e206f662074686520656c656374696f6e2e204f6e20656c656374696f6e2066696e616c697a6174696f6e2c20746865206e65787420696e6465782069733020726573657420746f20302e0069012057652063616e2774206a7573742075736520605369676e65645375626d697373696f6e496e64696365732e6c656e2829602c206265636175736520746861742773206120626f756e646564207365743b20706173742069747359012063617061636974792c2069742077696c6c2073696d706c792073617475726174652e2057652063616e2774206a7573742069746572617465206f76657220605369676e65645375626d697373696f6e734d6170602cf4206265636175736520697465726174696f6e20697320736c6f772e20496e73746561642c2077652073746f7265207468652076616c756520686572652e5c5369676e65645375626d697373696f6e496e6469636573010071080400186d01204120736f727465642c20626f756e64656420766563746f72206f6620602873636f72652c20626c6f636b5f6e756d6265722c20696e64657829602c20776865726520656163682060696e6465786020706f696e747320746f2061782076616c756520696e20605369676e65645375626d697373696f6e73602e007101205765206e65766572206e65656420746f2070726f63657373206d6f7265207468616e20612073696e676c65207369676e6564207375626d697373696f6e20617420612074696d652e205369676e6564207375626d697373696f6e7375012063616e206265207175697465206c617267652c20736f2077652772652077696c6c696e6720746f207061792074686520636f7374206f66206d756c7469706c6520646174616261736520616363657373657320746f206163636573732101207468656d206f6e6520617420612074696d6520696e7374656164206f662072656164696e6720616e64206465636f64696e6720616c6c206f66207468656d206174206f6e63652e505369676e65645375626d697373696f6e734d617000010405107d0804001c7420556e636865636b65642c207369676e656420736f6c7574696f6e732e00690120546f676574686572207769746820605375626d697373696f6e496e6469636573602c20746869732073746f726573206120626f756e64656420736574206f6620605369676e65645375626d697373696f6e7360207768696c65ec20616c6c6f77696e6720757320746f206b656570206f6e6c7920612073696e676c65206f6e6520696e206d656d6f727920617420612074696d652e0069012054776f78206e6f74653a20746865206b6579206f6620746865206d617020697320616e206175746f2d696e6372656d656e74696e6720696e6465782077686963682075736572732063616e6e6f7420696e7370656374206f72f4206166666563743b2077652073686f756c646e2774206e65656420612063727970746f67726170686963616c6c7920736563757265206861736865722e544d696e696d756d556e7472757374656453636f72650000e00400105d0120546865206d696e696d756d2073636f7265207468617420656163682027756e747275737465642720736f6c7574696f6e206d7573742061747461696e20696e206f7264657220746f20626520636f6e7369646572656428206665617369626c652e00b82043616e206265207365742076696120607365745f6d696e696d756d5f756e747275737465645f73636f7265602e01550301d838544265747465725369676e65645468726573686f6c64f41000000000084d0120546865206d696e696d756d20616d6f756e74206f6620696d70726f76656d656e7420746f2074686520736f6c7574696f6e2073636f7265207468617420646566696e6573206120736f6c7574696f6e2061737820226265747465722220696e20746865205369676e65642070686173652e384f6666636861696e5265706561743020050000000000000010b42054686520726570656174207468726573686f6c64206f6620746865206f6666636861696e20776f726b65722e00610120466f72206578616d706c652c20696620697420697320352c2074686174206d65616e732074686174206174206c65617374203520626c6f636b732077696c6c20656c61707365206265747765656e20617474656d7074738420746f207375626d69742074686520776f726b6572277320736f6c7574696f6e2e3c4d696e657254785072696f726974793020feffffffffffff7f04250120546865207072696f72697479206f662074686520756e7369676e6564207472616e73616374696f6e207375626d697474656420696e2074686520756e7369676e65642d7068617365505369676e65644d61785375626d697373696f6e7310100a0000001ce4204d6178696d756d206e756d626572206f66207369676e6564207375626d697373696f6e7320746861742063616e206265207175657565642e005501204974206973206265737420746f2061766f69642061646a757374696e67207468697320647572696e6720616e20656c656374696f6e2c20617320697420696d706163747320646f776e73747265616d2064617461650120737472756374757265732e20496e20706172746963756c61722c20605369676e65645375626d697373696f6e496e64696365733c543e6020697320626f756e646564206f6e20746869732076616c75652e20496620796f75f42075706461746520746869732076616c756520647572696e6720616e20656c656374696f6e2c20796f75205f6d7573745f20656e7375726520746861744d0120605369676e65645375626d697373696f6e496e64696365732e6c656e282960206973206c657373207468616e206f7220657175616c20746f20746865206e65772076616c75652e204f74686572776973652cf020617474656d70747320746f207375626d6974206e657720736f6c7574696f6e73206d617920636175736520612072756e74696d652070616e69632e3c5369676e65644d617857656967687428400bd8e2a18c2e011366666666666666a61494204d6178696d756d20776569676874206f662061207369676e656420736f6c7574696f6e2e005d01204966205b60436f6e6669673a3a4d696e6572436f6e666967605d206973206265696e6720696d706c656d656e74656420746f207375626d6974207369676e656420736f6c7574696f6e7320286f757473696465206f663d0120746869732070616c6c6574292c207468656e205b604d696e6572436f6e6669673a3a736f6c7574696f6e5f776569676874605d206973207573656420746f20636f6d7061726520616761696e73743020746869732076616c75652e405369676e65644d6178526566756e647310100300000004190120546865206d6178696d756d20616d6f756e74206f6620756e636865636b656420736f6c7574696f6e7320746f20726566756e64207468652063616c6c2066656520666f722e405369676e6564526577617264426173651840000064a7b3b6e00d0000000000000000048820426173652072657761726420666f722061207369676e656420736f6c7574696f6e445369676e65644465706f73697442797465184000008a5d78456301000000000000000004a0205065722d62797465206465706f73697420666f722061207369676e656420736f6c7574696f6e2e4c5369676e65644465706f73697457656967687418400000000000000000000000000000000004a8205065722d776569676874206465706f73697420666f722061207369676e656420736f6c7574696f6e2e284d617857696e6e6572731010e803000010350120546865206d6178696d756d206e756d626572206f662077696e6e65727320746861742063616e20626520656c656374656420627920746869732060456c656374696f6e50726f7669646572604020696d706c656d656e746174696f6e2e005101204e6f74653a2054686973206d75737420616c776179732062652067726561746572206f7220657175616c20746f2060543a3a4461746150726f76696465723a3a646573697265645f746172676574732829602e384d696e65724d61784c656e67746810100000360000384d696e65724d617857656967687428400bd8e2a18c2e011366666666666666a600544d696e65724d6178566f746573506572566f746572101010000000003c4d696e65724d617857696e6e6572731010e803000000018108101c5374616b696e67011c5374616b696e67ac3856616c696461746f72436f756e740100101000000000049c2054686520696465616c206e756d626572206f66206163746976652076616c696461746f72732e544d696e696d756d56616c696461746f72436f756e740100101000000000044101204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e34496e76756c6e657261626c657301003d0204000c590120416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e636520746865792772654d01206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f7572ac20696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e18426f6e64656400010405000004000c0101204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e404d696e4e6f6d696e61746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f662061206e6f6d696e61746f722e404d696e56616c696461746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f6620612076616c696461746f722e484d696e696d756d4163746976655374616b65010018400000000000000000000000000000000004110120546865206d696e696d756d20616374697665206e6f6d696e61746f72207374616b65206f6620746865206c617374207375636365737366756c20656c656374696f6e2e344d696e436f6d6d697373696f6e0100f410000000000ce820546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e20746861742076616c696461746f72732063616e207365742e00802049662073657420746f206030602c206e6f206c696d6974206578697374732e184c6564676572000104020085080400104501204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e007501204e6f74653a20416c6c2074686520726561647320616e64206d75746174696f6e7320746f20746869732073746f72616765202a4d5553542a20626520646f6e65207468726f75676820746865206d6574686f6473206578706f736564e8206279205b605374616b696e674c6564676572605d20746f20656e73757265206461746120616e64206c6f636b20636f6e73697374656e63792e1450617965650001040500f004000ce42057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e2856616c696461746f72730101040500f80800000c450120546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f7256616c696461746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d617856616c696461746f7273436f756e7400001004000c310120546865206d6178696d756d2076616c696461746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e284e6f6d696e61746f727300010405008d0804004c750120546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f207468656972206e6f6d696e6174696f6e20707265666572656e6365732c206e616d656c79207468652076616c696461746f72732074686174582074686579207769736820746f20737570706f72742e003901204e6f7465207468617420746865206b657973206f6620746869732073746f72616765206d6170206d69676874206265636f6d65206e6f6e2d6465636f6461626c6520696e2063617365207468652d01206163636f756e742773205b604e6f6d696e6174696f6e7351756f74613a3a4d61784e6f6d696e6174696f6e73605d20636f6e66696775726174696f6e206973206465637265617365642e9020496e2074686973207261726520636173652c207468657365206e6f6d696e61746f7273650120617265207374696c6c206578697374656e7420696e2073746f726167652c207468656972206b657920697320636f727265637420616e64207265747269657661626c652028692e652e2060636f6e7461696e735f6b657960710120696e6469636174657320746861742074686579206578697374292c206275742074686569722076616c75652063616e6e6f74206265206465636f6465642e205468657265666f72652c20746865206e6f6e2d6465636f6461626c656d01206e6f6d696e61746f72732077696c6c206566666563746976656c79206e6f742d65786973742c20756e74696c20746865792072652d7375626d697420746865697220707265666572656e6365732073756368207468617420697401012069732077697468696e2074686520626f756e6473206f6620746865206e65776c79207365742060436f6e6669673a3a4d61784e6f6d696e6174696f6e73602e006101205468697320696d706c696573207468617420603a3a697465725f6b65797328292e636f756e7428296020616e6420603a3a6974657228292e636f756e74282960206d696768742072657475726e20646966666572656e746d012076616c75657320666f722074686973206d61702e204d6f72656f7665722c20746865206d61696e20603a3a636f756e7428296020697320616c69676e656420776974682074686520666f726d65722c206e616d656c79207468656c206e756d626572206f66206b65797320746861742065786973742e006d01204c6173746c792c20696620616e79206f6620746865206e6f6d696e61746f7273206265636f6d65206e6f6e2d6465636f6461626c652c20746865792063616e206265206368696c6c656420696d6d6564696174656c7920766961b8205b6043616c6c3a3a6368696c6c5f6f74686572605d20646973706174636861626c6520627920616e796f6e652e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f724e6f6d696e61746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170385669727475616c5374616b657273000104050084040018c8205374616b6572732077686f73652066756e647320617265206d616e61676564206279206f746865722070616c6c6574732e00750120546869732070616c6c657420646f6573206e6f74206170706c7920616e79206c6f636b73206f6e207468656d2c207468657265666f7265207468657920617265206f6e6c79207669727475616c6c7920626f6e6465642e20546865796d012061726520657870656374656420746f206265206b65796c657373206163636f756e747320616e642068656e63652073686f756c64206e6f7420626520616c6c6f77656420746f206d7574617465207468656972206c65646765727101206469726563746c792076696120746869732070616c6c65742e20496e73746561642c207468657365206163636f756e747320617265206d616e61676564206279206f746865722070616c6c65747320616e64206163636573736564290120766961206c6f77206c6576656c20617069732e205765206b65657020747261636b206f66207468656d20746f20646f206d696e696d616c20696e7465677269747920636865636b732e60436f756e746572466f725669727475616c5374616b657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d61784e6f6d696e61746f7273436f756e7400001004000c310120546865206d6178696d756d206e6f6d696e61746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e2843757272656e744572610000100400105c205468652063757272656e742065726120696e6465782e006501205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f7280207365742c206974206d6967687420626520616374697665206f72206e6f742e2441637469766545726100009108040010d820546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e0059012054686520616374697665206572612069732074686520657261206265696e672063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d757374206265ac20657175616c20746f205b6053657373696f6e496e746572666163653a3a76616c696461746f7273605d2e5445726173537461727453657373696f6e496e6465780001040510100400105501205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e006101204e6f74653a205468697320747261636b7320746865207374617274696e672073657373696f6e2028692e652e2073657373696f6e20696e646578207768656e20657261207374617274206265696e672061637469766529f020666f7220746865206572617320696e20605b43757272656e74457261202d20484953544f52595f44455054482c2043757272656e744572615d602e2c457261735374616b6572730101080505950869010c0000002078204578706f73757265206f662076616c696461746f72206174206572612e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e4c457261735374616b6572734f76657276696577000108050595089908040030b82053756d6d617279206f662076616c696461746f72206578706f73757265206174206120676976656e206572612e007101205468697320636f6e7461696e732074686520746f74616c207374616b6520696e20737570706f7274206f66207468652076616c696461746f7220616e64207468656972206f776e207374616b652e20496e206164646974696f6e2c75012069742063616e20616c736f206265207573656420746f2067657420746865206e756d626572206f66206e6f6d696e61746f7273206261636b696e6720746869732076616c696461746f7220616e6420746865206e756d626572206f666901206578706f73757265207061676573207468657920617265206469766964656420696e746f2e20546865207061676520636f756e742069732075736566756c20746f2064657465726d696e6520746865206e756d626572206f66ac207061676573206f6620726577617264732074686174206e6565647320746f20626520636c61696d65642e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742eac2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206f766572766965772069732072657475726e65642e48457261735374616b657273436c69707065640101080505950869010c000000409820436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e006501204e6f74653a205468697320697320646570726563617465642c2073686f756c64206265207573656420617320726561642d6f6e6c7920616e642077696c6c2062652072656d6f76656420696e20746865206675747572652e3101204e657720604578706f737572656073206172652073746f72656420696e2061207061676564206d616e6e657220696e2060457261735374616b65727350616765646020696e73746561642e00590120546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f20746865a82060543a3a4d61784578706f737572655061676553697a65602062696767657374207374616b6572732e1d0120284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292ef42054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e005d012054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e40457261735374616b657273506167656400010c0505059d08a108040018c020506167696e61746564206578706f73757265206f6620612076616c696461746f7220617420676976656e206572612e0071012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e2c207468656e207374617368206163636f756e7420616e642066696e616c6c79d42074686520706167652e2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00d4205468697320697320636c6561726564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e38436c61696d656452657761726473010108050595084504040018dc20486973746f7279206f6620636c61696d656420706167656420726577617264732062792065726120616e642076616c696461746f722e0069012054686973206973206b657965642062792065726120616e642076616c696461746f72207374617368207768696368206d61707320746f2074686520736574206f66207061676520696e6465786573207768696368206861766538206265656e20636c61696d65642e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e484572617356616c696461746f72507265667301010805059508f80800001411012053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4c4572617356616c696461746f7252657761726400010405101804000c2d012054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e0021012045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e4045726173526577617264506f696e74730101040510a50814000000000008d0205265776172647320666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e250120496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e3845726173546f74616c5374616b6501010405101840000000000000000000000000000000000811012054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e1d0120496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e20466f7263654572610100010104000454204d6f6465206f662065726120666f7263696e672e404d61785374616b6564526577617264730000f50104000c1901204d6178696d756d207374616b656420726577617264732c20692e652e207468652070657263656e74616765206f66207468652065726120696e666c6174696f6e20746861746c206973207573656420666f72207374616b6520726577617264732eac20536565205b457261207061796f75745d282e2f696e6465782e68746d6c236572612d7061796f7574292e4c536c6173685265776172644672616374696f6e0100f410000000000cf8205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e00e4205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e4c43616e63656c6564536c6173685061796f757401001840000000000000000000000000000000000815012054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e7420776869636820776173ec2063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e40556e6170706c696564536c61736865730101040510b508040004c420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e28426f6e646564457261730100bd0804001025012041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e00c8204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653abc20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d604c56616c696461746f72536c617368496e45726100010805059508c508040008450120416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e7020616e6420736c6173682076616c7565206f6620746865206572612e4c4e6f6d696e61746f72536c617368496e4572610001080505950818040004610120416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e34536c617368696e675370616e730001040500c9080400048c20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e245370616e536c61736801010405b108cd08800000000000000000000000000000000000000000000000000000000000000000083d01205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2cb82061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e5443757272656e74506c616e6e656453657373696f6e01001010000000000ce820546865206c61737420706c616e6e65642073657373696f6e207363686564756c6564206279207468652073657373696f6e2070616c6c65742e0071012054686973206973206261736963616c6c7920696e2073796e632077697468207468652063616c6c20746f205b6070616c6c65745f73657373696f6e3a3a53657373696f6e4d616e616765723a3a6e65775f73657373696f6e605d2e4844697361626c656456616c696461746f72730100450404001c750120496e6469636573206f662076616c696461746f727320746861742068617665206f6666656e64656420696e2074686520616374697665206572612e20546865206f6666656e64657273206172652064697361626c656420666f72206169012077686f6c65206572612e20466f72207468697320726561736f6e207468657920617265206b6570742068657265202d206f6e6c79207374616b696e672070616c6c6574206b6e6f77732061626f757420657261732e20546865550120696d706c656d656e746f72206f66205b6044697361626c696e675374726174656779605d20646566696e657320696620612076616c696461746f722073686f756c642062652064697361626c65642077686963686d0120696d706c696369746c79206d65616e7320746861742074686520696d706c656d656e746f7220616c736f20636f6e74726f6c7320746865206d6178206e756d626572206f662064697361626c65642076616c696461746f72732e006d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f72206861732070726576696f75736c7978206f6666656e646564207573696e672062696e617279207365617263682e384368696c6c5468726573686f6c640000f50104000c510120546865207468726573686f6c6420666f72207768656e2075736572732063616e2073746172742063616c6c696e6720606368696c6c5f6f746865726020666f72206f746865722076616c696461746f7273202f5901206e6f6d696e61746f72732e20546865207468726573686f6c6420697320636f6d706172656420746f207468652061637475616c206e756d626572206f662076616c696461746f7273202f206e6f6d696e61746f72732901202860436f756e74466f722a602920696e207468652073797374656d20636f6d706172656420746f2074686520636f6e66696775726564206d61782028604d61782a436f756e7460292e013d0401ec1830486973746f72794465707468101050000000508c204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e00e820466f6c6c6f77696e6720696e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d090120486973746f727944657074682c2063757272656e745f6572615d603a2060457261735374616b657273602c2060457261735374616b657273436c6970706564602c050120604572617356616c696461746f725072656673602c20604572617356616c696461746f72526577617264602c206045726173526577617264506f696e7473602c4501206045726173546f74616c5374616b65602c206045726173537461727453657373696f6e496e646578602c2060436c61696d656452657761726473602c2060457261735374616b6572735061676564602c5c2060457261735374616b6572734f76657276696577602e00e4204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e2ef820492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203ec42063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e001101204966206d6967726174696e6720616e206578697374696e672070616c6c65742066726f6d2073746f726167652076616c756520746f20636f6e6669672076616c75652cec20746869732073686f756c642062652073657420746f2073616d652076616c7565206f72206772656174657220617320696e2073746f726167652e001501204e6f74653a2060486973746f727944657074686020697320757365642061732074686520757070657220626f756e6420666f72207468652060426f756e646564566563602d01206974656d20605374616b696e674c65646765722e6c65676163795f636c61696d65645f72657761726473602e2053657474696e6720746869732076616c7565206c6f776572207468616ed820746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865150120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e2061206d6967726174696f6e2ef020546865207465737420607265647563696e675f686973746f72795f64657074685f616272757074602073686f77732074686973206566666563742e3853657373696f6e735065724572611010030000000470204e756d626572206f662073657373696f6e7320706572206572612e3c426f6e64696e674475726174696f6e10100e00000004e4204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e48536c61736844656665724475726174696f6e10100a000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e4c4d61784578706f737572655061676553697a651010400000002cb020546865206d6178696d756d2073697a65206f6620656163682060543a3a4578706f7375726550616765602e00290120416e20604578706f737572655061676560206973207765616b6c7920626f756e64656420746f2061206d6178696d756d206f6620604d61784578706f737572655061676553697a656030206e6f6d696e61746f72732e00210120466f72206f6c646572206e6f6e2d7061676564206578706f737572652c206120726577617264207061796f757420776173207265737472696374656420746f2074686520746f70210120604d61784578706f737572655061676553697a6560206e6f6d696e61746f72732e205468697320697320746f206c696d69742074686520692f6f20636f737420666f722074686548206e6f6d696e61746f72207061796f75742e005901204e6f74653a20604d61784578706f737572655061676553697a6560206973207573656420746f20626f756e642060436c61696d6564526577617264736020616e6420697320756e7361666520746f207265647563659020776974686f75742068616e646c696e6720697420696e2061206d6967726174696f6e2e484d6178556e6c6f636b696e674368756e6b7310102000000028050120546865206d6178696d756d206e756d626572206f662060756e6c6f636b696e6760206368756e6b732061205b605374616b696e674c6564676572605d2063616e090120686176652e204566666563746976656c792064657465726d696e657320686f77206d616e7920756e6971756520657261732061207374616b6572206d61792062653820756e626f6e64696e6720696e2e00f8204e6f74653a20604d6178556e6c6f636b696e674368756e6b736020697320757365642061732074686520757070657220626f756e6420666f722074686501012060426f756e64656456656360206974656d20605374616b696e674c65646765722e756e6c6f636b696e67602e2053657474696e6720746869732076616c75650501206c6f776572207468616e20746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865090120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e20612072756e74696d650501206d6967726174696f6e2e20546865207465737420607265647563696e675f6d61785f756e6c6f636b696e675f6368756e6b735f616272757074602073686f7773342074686973206566666563742e01d108111c53657373696f6e011c53657373696f6e1c2856616c696461746f727301003d020400047c205468652063757272656e7420736574206f662076616c696461746f72732e3043757272656e74496e646578010010100000000004782043757272656e7420696e646578206f66207468652073657373696f6e2e345175657565644368616e676564010020040008390120547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f7273a420686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e285175657565644b6579730100d5080400083d012054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b657973e02077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e4844697361626c656456616c696461746f7273010045040400148020496e6469636573206f662064697361626c65642076616c696461746f72732e003d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f722069733d012064697361626c6564207573696e672062696e617279207365617263682e204974206765747320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e73642061206e657720736574206f66206964656e7469746965732e204e6578744b657973000104050075040400049c20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e204b65794f776e657200010405dd0800040004090120546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e0171040105010001e5081228486973746f726963616c0128486973746f726963616c0848486973746f726963616c53657373696f6e730001040510e9080400045d01204d617070696e672066726f6d20686973746f726963616c2073657373696f6e20696e646963657320746f2073657373696f6e2d6461746120726f6f74206861736820616e642076616c696461746f7220636f756e742e2c53746f72656452616e67650000c108040004e4205468652072616e6765206f6620686973746f726963616c2073657373696f6e732077652073746f72652e205b66697273742c206c61737429000000001320547265617375727901205472656173757279183450726f706f73616c436f756e74010010100000000004a4204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e2450726f706f73616c730001040510ed080400047c2050726f706f73616c7320746861742068617665206265656e206d6164652e2c4465616374697661746564010018400000000000000000000000000000000004f02054686520616d6f756e7420776869636820686173206265656e207265706f7274656420617320696e61637469766520746f2043757272656e63792e24417070726f76616c730100f108040004f82050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e285370656e64436f756e74010010100000000004a42054686520636f756e74206f66207370656e647320746861742068617665206265656e206d6164652e185370656e64730001040510f508040004d0205370656e647320746861742068617665206265656e20617070726f76656420616e64206265696e672070726f6365737365642e017904010901142c5370656e64506572696f6430204038000000000000048820506572696f64206265747765656e2073756363657373697665207370656e64732e104275726ed10110000000000411012050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e2050616c6c65744964fd082070792f74727372790419012054686520747265617375727927732070616c6c65742069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e304d6178417070726f76616c731010640000000c150120546865206d6178696d756d206e756d626572206f6620617070726f76616c7320746861742063616e207761697420696e20746865207370656e64696e672071756575652e004d01204e4f54453a205468697320706172616d6574657220697320616c736f20757365642077697468696e2074686520426f756e746965732050616c6c657420657874656e73696f6e20696620656e61626c65642e305061796f7574506572696f6430200a000000000000000419012054686520706572696f6420647572696e6720776869636820616e20617070726f766564207472656173757279207370656e642068617320746f20626520636c61696d65642e0101091420426f756e746965730120426f756e74696573102c426f756e7479436f756e74010010100000000004c0204e756d626572206f6620626f756e74792070726f706f73616c7320746861742068617665206265656e206d6164652e20426f756e74696573000104051005090400047820426f756e7469657320746861742068617665206265656e206d6164652e48426f756e74794465736372697074696f6e7300010405100d090400048020546865206465736372697074696f6e206f66206561636820626f756e74792e3c426f756e7479417070726f76616c730100f108040004ec20426f756e747920696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f74207965742066756e6465642e018104010d012444426f756e74794465706f736974426173651840000064a7b3b6e00d000000000000000004e82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120626f756e74792070726f706f73616c2e60426f756e74794465706f7369745061796f757444656c617930204038000000000000045901205468652064656c617920706572696f6420666f72207768696368206120626f756e74792062656e6566696369617279206e65656420746f2077616974206265666f726520636c61696d20746865207061796f75742e48426f756e7479557064617465506572696f6430208013030000000000046c20426f756e7479206475726174696f6e20696e20626c6f636b732e6043757261746f724465706f7369744d756c7469706c696572d1011020a10700101901205468652063757261746f72206465706f7369742069732063616c63756c6174656420617320612070657263656e74616765206f66207468652063757261746f72206665652e0039012054686973206465706f73697420686173206f7074696f6e616c20757070657220616e64206c6f77657220626f756e64732077697468206043757261746f724465706f7369744d61786020616e6454206043757261746f724465706f7369744d696e602e4443757261746f724465706f7369744d61785d044401000010632d5ec76b0500000000000000044901204d6178696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e4443757261746f724465706f7369744d696e5d044401000064a7b3b6e00d0000000000000000044901204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e48426f756e747956616c75654d696e696d756d18400000f4448291634500000000000000000470204d696e696d756d2076616c756520666f72206120626f756e74792e48446174614465706f73697450657242797465184000008a5d7845630100000000000000000461012054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e206f7220626f756e7479206465736372697074696f6e2e4c4d6178696d756d526561736f6e4c656e67746810102c0100000c88204d6178696d756d2061636365707461626c6520726561736f6e206c656e6774682e0065012042656e63686d61726b7320646570656e64206f6e20746869732076616c75652c206265207375726520746f2075706461746520776569676874732066696c65207768656e206368616e67696e6720746869732076616c756501110915344368696c64426f756e7469657301344368696c64426f756e7469657314404368696c64426f756e7479436f756e7401001010000000000480204e756d626572206f6620746f74616c206368696c6420626f756e746965732e4c506172656e744368696c64426f756e74696573010104051010100000000008b0204e756d626572206f66206368696c6420626f756e746965732070657220706172656e7420626f756e74792ee0204d6170206f6620706172656e7420626f756e747920696e64657820746f206e756d626572206f66206368696c6420626f756e746965732e344368696c64426f756e746965730001080505c108150904000494204368696c6420626f756e7469657320746861742068617665206265656e2061646465642e5c4368696c64426f756e74794465736372697074696f6e7300010405100d090400049820546865206465736372697074696f6e206f662065616368206368696c642d626f756e74792e4c4368696c6472656e43757261746f72466565730101040510184000000000000000000000000000000000040101205468652063756d756c6174697665206368696c642d626f756e74792063757261746f722066656520666f72206561636820706172656e7420626f756e74792e01850401110108644d61784163746976654368696c64426f756e7479436f756e74101005000000041d01204d6178696d756d206e756d626572206f66206368696c6420626f756e7469657320746861742063616e20626520616464656420746f206120706172656e7420626f756e74792e5c4368696c64426f756e747956616c75654d696e696d756d1840000064a7b3b6e00d00000000000000000488204d696e696d756d2076616c756520666f722061206368696c642d626f756e74792e011d091620426167734c6973740120426167734c6973740c244c6973744e6f6465730001040500210904000c8020412073696e676c65206e6f64652c2077697468696e20736f6d65206261672e000501204e6f6465732073746f7265206c696e6b7320666f727761726420616e64206261636b2077697468696e207468656972207265737065637469766520626167732e4c436f756e746572466f724c6973744e6f646573010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204c697374426167730001040530250904000c642041206261672073746f72656420696e2073746f726167652e0019012053746f7265732061206042616760207374727563742c2077686963682073746f726573206865616420616e64207461696c20706f696e7465727320746f20697473656c662e01890401150104344261675468726573686f6c647319060919210300407a10f35a00006a70ccd4a96000009ef3397fbc660000a907ccd5306d00003d9a67fb0c740000a9bfa275577b0000a6fdf73217830000034f5d91538b0000132445651494000078081001629d00000302f63c45a70000392e6f7fc7b10000f59c23c6f2bc00004ae76aafd1c80000598a64846fd50000129fb243d8e200003f22e1ac18f1000033a4844c3e000100e2e51b895710010076a2c0b0732101006789b407a3330100793ed8d7f646010078131b81815b01000c1cf38a567101004437eeb68a8801009eb56d1434a10100335e9f156abb010067c3c7a545d701003218f340e1f40100de0b230d59140200699c11f5ca350200ad50a2c4565902009ae41c471e7f0200d0244e6745a70200f984ad51f2d10200ace7a7984dff0200a118325b822f0300ffa4c76dbe620300580bfd8532990300a9afce6812d30300109ad81b95100400d9caa519f551040038df488970970400bee1727949e10400cc73401fc62f0500b304f91831830500828bffb4d9db05001235383d143a0600a5b42a473a9e060036662d09ab080700f73aeab4cb790700b87e93d707f20700ffec23c0d1710800b84b0beca2f90800c9dcae7afc89090091752ba867230a0064f1cd4f76c60a003609be76c3730b0078655fdff32b0c00a407f5a5b6ef0c0052f61be7c5bf0d00da71bb70e79c0e000de9127eed870f001477987fb7811000ebee65ef328b11001269fe325ca5120033f8428b3fd113008ba57a13fa0f15001b2b60d0ba6216000d1d37d0c3ca17006c64fa5c6b4919002622c7411de01a00045bb9245c901c00233d83f6c25b1e00c8771c79064420003013fddef64a2200aa8b6e848172240082c096c4b2bc260016a3faebb72b29008296524ae1c12b00a636a865a4812e00d0e2d4509e6d31009c0a9a2796883400e4faafb27fd53700e6e64d367e573b000e4bd66de7113f0088b17db746084300b07def72603e470034de249635b84b00d48bd57b077a5000d0bd20ef5b885500b8f0467801e85a0010f88aee139e60003892925301b066009c95e4fc8e236d00b4126d10dffe730028b43e5976487b00a08a1c7a42078300b09ab083a0428b002846b2f463029400c861a42ade4e9d0050d23d4ae630a700805101a7e1b1b10038e501b2ccdbbc002016527844b9c800388924ba9055d50070ca35a4aebce200805fb1355cfbf0008035685d241f0001a0c3dcd96b361001d07862e87e50210160e852d09f7d330190662c5816cf460110274c3340575b01804be277a22971013082b92dfc5a880180d276075a01a101b0f511592b34bb014031745f580cd701802f6cee59a4f40140ff799b521814026075607d2986350260fde999a60d590200e5e71c91d07e02c0df2575cff2a602a07fd975899ad102a067009d4cf0fe0220dc29a1321f2f0320ff526b0a5562038088caa383c29803e05683fb5c9bd203401dd75d9516100400317e39a06e5104c0b071129de1960480b48c9192b1e00480e8124aad242f05c007ca7082858205007c13c45623db0540836fe869523906c0700f81466c9d0640f09c5017d00707c0e624b301e37807c0332ac78510f10780074ca1e4ca700800d5a9eb8c8bf80800a849588ed3880900804254142c220a80a25170e826c50a00e8d5fafc5e720b801df64e00792a0c80d4fe64f923ee0c006dd038ee19be0d001e90a494209b0e0010bf570e0a860f00da6a9db0b57f1000bf64afd810891100bb5b60cd17a31200f963f3aed6ce1300d5f004766a0d1500e099770202601600103d663bdfc71700de3e2d4158461900ecdbadb2d8dc1a0045c70007e38c1c00b8bde0fc11581e00ba5c2a211a402000407de46dcb462200dea55b03136e2400aaf1f3fcfcb7260014226f63b62629006492803e8fbc2b008486a6c7fc7b2e002cf05fc09b673100da63f7ed32823400f0b13fbdb5ce3700f291c41047503b00422a1a3c3c0a3f002c24212f20004300ac9342d4b6354700cc6ed7a400af4b00c4d022773e70500020017d89f57d5500f86387cef3dc5a008c4c7f7e54926000206207f284a36600cc1e05cb49166d00b42a7a70c4f07300d43a90e278397b0038f461ec53f78200a07264b9b1318b0048c9b3d464f09300007fe998bd3b9d0010058f17921ca70000dfaf7f469cb100e80c880bd6c4bc0058bdcb7ddca0c80038d18d37a03bd50030d55bf01ca1e200704ac01a0fdef0ffffffffffffffffacd020546865206c697374206f66207468726573686f6c64732073657061726174696e672074686520766172696f757320626167732e00490120496473206172652073657061726174656420696e746f20756e736f727465642062616773206163636f7264696e6720746f2074686569722073636f72652e205468697320737065636966696573207468656101207468726573686f6c64732073657061726174696e672074686520626167732e20416e20696427732062616720697320746865206c6172676573742062616720666f722077686963682074686520696427732073636f7265b8206973206c657373207468616e206f7220657175616c20746f20697473207570706572207468726573686f6c642e006501205768656e20696473206172652069746572617465642c2068696768657220626167732061726520697465726174656420636f6d706c6574656c79206265666f7265206c6f77657220626167732e2054686973206d65616e735901207468617420697465726174696f6e206973205f73656d692d736f727465645f3a20696473206f66206869676865722073636f72652074656e6420746f20636f6d65206265666f726520696473206f66206c6f7765722d012073636f72652c206275742070656572206964732077697468696e206120706172746963756c6172206261672061726520736f7274656420696e20696e73657274696f6e206f726465722e006820232045787072657373696e672074686520636f6e7374616e74004d01205468697320636f6e7374616e74206d75737420626520736f7274656420696e207374726963746c7920696e6372656173696e67206f726465722e204475706c6963617465206974656d7320617265206e6f742c207065726d69747465642e00410120546865726520697320616e20696d706c696564207570706572206c696d6974206f66206053636f72653a3a4d4158603b20746861742076616c756520646f6573206e6f74206e65656420746f2062652101207370656369666965642077697468696e20746865206261672e20466f7220616e792074776f207468726573686f6c64206c697374732c206966206f6e6520656e647320776974683101206053636f72653a3a4d4158602c20746865206f74686572206f6e6520646f6573206e6f742c20616e64207468657920617265206f746865727769736520657175616c2c207468652074776f7c206c697374732077696c6c20626568617665206964656e746963616c6c792e003820232043616c63756c6174696f6e005501204974206973207265636f6d6d656e64656420746f2067656e65726174652074686520736574206f66207468726573686f6c647320696e20612067656f6d6574726963207365726965732c2073756368207468617441012074686572652065786973747320736f6d6520636f6e7374616e7420726174696f2073756368207468617420607468726573686f6c645b6b202b20315d203d3d20287468726573686f6c645b6b5d202ad020636f6e7374616e745f726174696f292e6d6178287468726573686f6c645b6b5d202b2031296020666f7220616c6c20606b602e005901205468652068656c7065727320696e2074686520602f7574696c732f6672616d652f67656e65726174652d6261677360206d6f64756c652063616e2073696d706c69667920746869732063616c63756c6174696f6e2e002c2023204578616d706c6573005101202d20496620604261675468726573686f6c64733a3a67657428292e69735f656d7074792829602c207468656e20616c6c20696473206172652070757420696e746f207468652073616d65206261672c20616e64b0202020697465726174696f6e206973207374726963746c7920696e20696e73657274696f6e206f726465722e6101202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d203634602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f11012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320657175616c20746f20322e6501202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d20323030602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f59012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320617070726f78696d6174656c7920657175616c20746f20312e3234382e6101202d20496620746865207468726573686f6c64206c69737420626567696e7320605b312c20322c20332c202e2e2e5d602c207468656e20616e20696420776974682073636f72652030206f7220312077696c6c2066616c6cf0202020696e746f2062616720302c20616e20696420776974682073636f726520322077696c6c2066616c6c20696e746f2062616720312c206574632e00302023204d6967726174696f6e00610120496e20746865206576656e7420746861742074686973206c6973742065766572206368616e6765732c206120636f7079206f6620746865206f6c642062616773206c697374206d7573742062652072657461696e65642e5d012057697468207468617420604c6973743a3a6d696772617465602063616e2062652063616c6c65642c2077686963682077696c6c20706572666f726d2074686520617070726f707269617465206d6967726174696f6e2e012909173c4e6f6d696e6174696f6e506f6f6c73013c4e6f6d696e6174696f6e506f6f6c735440546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e384d6178506f6f6c4d656d626572730000100400084901204d6178696d756d206e756d626572206f66206d656d6265727320746861742063616e20657869737420696e207468652073797374656d2e20496620604e6f6e65602c207468656e2074686520636f756e74b8206d656d6265727320617265206e6f7420626f756e64206f6e20612073797374656d20776964652062617369732e544d6178506f6f6c4d656d62657273506572506f6f6c0000100400084101204d6178696d756d206e756d626572206f66206d656d626572732074686174206d61792062656c6f6e6720746f20706f6f6c2e20496620604e6f6e65602c207468656e2074686520636f756e74206f66a8206d656d62657273206973206e6f7420626f756e64206f6e20612070657220706f6f6c2062617369732e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c506f6f6c4d656d626572730001040500310904000c4020416374697665206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e54436f756e746572466f72506f6f6c4d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c426f6e646564506f6f6c7300010405104509040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510590904000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f7574206f66207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f7261676500010405105d0904000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d65746164617461010104051055010400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e4c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0075012054686973206973206f6e6c79207573656420666f7220736c617368696e6720616e64206f6e206175746f6d61746963207769746864726177207570646174652e20496e20616c6c206f7468657220696e7374616e6365732c20746865250120706f6f6c20696420697320757365642c20616e6420746865206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500a5040402040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e018d040119010c2050616c6c65744964fd082070792f6e6f706c73048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101008000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e01750918245363686564756c657201245363686564756c6572103c496e636f6d706c65746553696e6365000030040000184167656e646101010405307d090400044d01204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e1c526574726965730001040239018d09040004210120526574727920636f6e66696775726174696f6e7320666f72206974656d7320746f2062652065786563757465642c20696e6465786564206279207461736b20616464726573732e184c6f6f6b757000010405043901040010f8204c6f6f6b75702066726f6d2061206e616d6520746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e00590120466f72207633202d3e207634207468652070726576696f75736c7920756e626f756e646564206964656e7469746965732061726520426c616b65322d3235362068617368656420746f20666f726d2074686520763430206964656e7469746965732e01a90401350108344d6178696d756d57656967687428400b00806e87740113cccccccccccccccc04290120546865206d6178696d756d207765696768742074686174206d6179206265207363686564756c65642070657220626c6f636b20666f7220616e7920646973706174636861626c65732e504d61785363686564756c6564506572426c6f636b101000020000141d0120546865206d6178696d756d206e756d626572206f66207363686564756c65642063616c6c7320696e2074686520717565756520666f7220612073696e676c6520626c6f636b2e0018204e4f54453a5101202b20446570656e64656e742070616c6c657473272062656e63686d61726b73206d696768742072657175697265206120686967686572206c696d697420666f72207468652073657474696e672e205365742061c420686967686572206c696d697420756e646572206072756e74696d652d62656e63686d61726b736020666561747572652e0191091920507265696d6167650120507265696d6167650c24537461747573466f72000104063495090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e4052657175657374537461747573466f7200010406349d090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e2c507265696d616765466f7200010406e908a90904000001b1040141010001ad091a204f6666656e63657301204f6666656e636573081c5265706f7274730001040534b109040004490120546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e58436f6e63757272656e745265706f727473496e6465780101080505b509c1010400042901204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e0001450100001b1c54785061757365011c54785061757365042c50617573656443616c6c7300010402510184040004b42054686520736574206f662063616c6c73207468617420617265206578706c696369746c79207061757365642e01b504014d0104284d61784e616d654c656e1010000100000c2501204d6178696d756d206c656e67746820666f722070616c6c6574206e616d6520616e642063616c6c206e616d65205343414c4520656e636f64656420737472696e67206e616d65732e00a820544f4f204c4f4e47204e414d45532057494c4c2042452054524541544544204153205041555345442e01b9091c20496d4f6e6c696e650120496d4f6e6c696e65103848656172746265617441667465720100302000000000000000002c1d012054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e207468652063757272656e74242073657373696f6e2e0025012041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c350120726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f721901207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f207468617420746865a820686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00390120546869732076616c75652077696c6c206f6e6c79206265207573656420617320612066616c6c6261636b206966207765206661696c20746f2067657420612070726f7065722073657373696f6e2d012070726f677265737320657374696d6174652066726f6d20604e65787453657373696f6e526f746174696f6e602c2061732074686f736520657374696d617465732073686f756c642062650101206d6f7265206163637572617465207468656e207468652076616c75652077652063616c63756c61746520666f7220604865617274626561744166746572602e104b6579730100bd09040004d0205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e485265636569766564486561727462656174730001080505c10820040004350120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206053657373696f6e496e6465786020616e64206041757468496e646578602e38417574686f726564426c6f636b730101080505950810100000000008150120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206056616c696461746f7249643c543e6020746f20746865c8206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e01b9040159010440556e7369676e65645072696f726974793020ffffffffffffffff10f0204120636f6e66696775726174696f6e20666f722062617365207072696f72697479206f6620756e7369676e6564207472616e73616374696f6e732e0015012054686973206973206578706f73656420736f20746861742069742063616e2062652074756e656420666f7220706172746963756c61722072756e74696d652c207768656eb4206d756c7469706c652070616c6c6574732073656e6420756e7369676e6564207472616e73616374696f6e732e01c5091d204964656e7469747901204964656e746974791c284964656e746974794f660001040500c909040010690120496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e204669727374206974656d20697320746865e020726567697374726174696f6e2c207365636f6e6420697320746865206163636f756e742773207072696d61727920757365726e616d652e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e1c53757065724f66000104020055050400086101205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e2074686174510120636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e18537562734f660101040500e10944000000000000000000000000000000000014b820416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e001d0120546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e28526567697374726172730100e9090400104d012054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061a8207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e0029012054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e4c557365726e616d65417574686f7269746965730001040500f909040004f42041206d6170206f6620746865206163636f756e74732077686f2061726520617574686f72697a656420746f206772616e7420757365726e616d65732e444163636f756e744f66557365726e616d65000104027d01000400146d012052657665727365206c6f6f6b75702066726f6d2060757365726e616d656020746f2074686520604163636f756e7449646020746861742068617320726567697374657265642069742e205468652076616c75652073686f756c6465012062652061206b657920696e2074686520604964656e746974794f6660206d61702c20627574206974206d6179206e6f742069662074686520757365722068617320636c6561726564207468656972206964656e746974792e006901204d756c7469706c6520757365726e616d6573206d6179206d617020746f207468652073616d6520604163636f756e744964602c2062757420604964656e746974794f66602077696c6c206f6e6c79206d617020746f206f6e6548207072696d61727920757365726e616d652e4050656e64696e67557365726e616d6573000104027d01010a0400186d0120557365726e616d6573207468617420616e20617574686f7269747920686173206772616e7465642c20627574207468617420746865206163636f756e7420636f6e74726f6c6c657220686173206e6f7420636f6e6669726d65647101207468617420746865792077616e742069742e2055736564207072696d6172696c7920696e2063617365732077686572652074686520604163636f756e744964602063616e6e6f742070726f766964652061207369676e61747572655d012062656361757365207468657920617265206120707572652070726f78792c206d756c74697369672c206574632e20496e206f7264657220746f20636f6e6669726d2069742c20746865792073686f756c642063616c6c6c205b6043616c6c3a3a6163636570745f757365726e616d65605d2e001d01204669727374207475706c65206974656d20697320746865206163636f756e7420616e64207365636f6e642069732074686520616363657074616e636520646561646c696e652e01c504017901203042617369634465706f7369741840000064a7b3b6e00d000000000000000004d82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e2c427974654465706f7369741840000064a7b3b6e00d0000000000000000041d012054686520616d6f756e742068656c64206f6e206465706f7369742070657220656e636f646564206279746520666f7220612072656769737465726564206964656e746974792e445375624163636f756e744465706f73697418400000d1d21fe5ea6b05000000000000000c65012054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f7220746865206661637465012074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c350120626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e384d61785375624163636f756e7473101064000000040d0120546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e344d617852656769737472617273101014000000084d01204d6178696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c65786974797c206f662c20652e672e2c207570646174696e67206a756467656d656e74732e6450656e64696e67557365726e616d6545787069726174696f6e3020c08901000000000004150120546865206e756d626572206f6620626c6f636b732077697468696e207768696368206120757365726e616d65206772616e74206d7573742062652061636365707465642e3c4d61785375666669784c656e677468101007000000048020546865206d6178696d756d206c656e677468206f662061207375666669782e444d6178557365726e616d654c656e67746810102000000004610120546865206d6178696d756d206c656e677468206f66206120757365726e616d652c20696e636c7564696e67206974732073756666697820616e6420616e792073797374656d2d61646465642064656c696d69746572732e01050a1e1c5574696c69747900016905018101044c626174636865645f63616c6c735f6c696d69741010aa2a000004a820546865206c696d6974206f6e20746865206e756d626572206f6620626174636865642063616c6c732e01090a1f204d756c746973696701204d756c746973696704244d756c74697369677300010805020d0a110a040004942054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e0181050185010c2c4465706f736974426173651840000068cd83c1fd77050000000000000018590120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e672061206d756c746973696720657865637574696f6e206f7220746f842073746f726520612064697370617463682063616c6c20666f72206c617465722e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069733101206034202b2073697a656f662828426c6f636b4e756d6265722c2042616c616e63652c204163636f756e74496429296020627974657320616e642077686f7365206b65792073697a652069738020603332202b2073697a656f66284163636f756e74496429602062797465732e344465706f736974466163746f721840000020f84dde700400000000000000000c55012054686520616d6f756e74206f662063757272656e6379206e65656465642070657220756e6974207468726573686f6c64207768656e206372656174696e672061206d756c746973696720657865637574696f6e2e00250120546869732069732068656c6420666f7220616464696e67203332206279746573206d6f726520696e746f2061207072652d6578697374696e672073746f726167652076616c75652e384d61785369676e61746f7269657310106400000004ec20546865206d6178696d756d20616d6f756e74206f66207369676e61746f7269657320616c6c6f77656420696e20746865206d756c74697369672e01150a2020457468657265756d0120457468657265756d141c50656e64696e670100190a040004d02043757272656e74206275696c64696e6720626c6f636b2773207472616e73616374696f6e7320616e642072656365697074732e3043757272656e74426c6f636b0000390a04000470205468652063757272656e7420457468657265756d20626c6f636b2e3c43757272656e74526563656970747300004d0a0400047c205468652063757272656e7420457468657265756d2072656365697074732e6843757272656e745472616e73616374696f6e53746174757365730000510a04000488205468652063757272656e74207472616e73616374696f6e2073746174757365732e24426c6f636b4861736801010405c9013480000000000000000000000000000000000000000000000000000000000000000000018905018d010001550a210c45564d010c45564d10304163636f756e74436f64657301010402910138040000504163636f756e74436f6465734d65746164617461000104029101590a0400003c4163636f756e7453746f726167657301010802025d0a34800000000000000000000000000000000000000000000000000000000000000000002053756963696465640001040291018404000001b10501b9010001610a222845564d436861696e4964012845564d436861696e4964041c436861696e49640100302000000000000000000448205468652045564d20636861696e2049442e00000000232844796e616d6963466565012844796e616d6963466565082c4d696e47617350726963650100c90180000000000000000000000000000000000000000000000000000000000000000000445461726765744d696e47617350726963650000c90104000001c105000000241c42617365466565011c426173654665650834426173654665655065724761730100c9018040420f00000000000000000000000000000000000000000000000000000000000028456c61737469636974790100d1011048e801000001c50501c50100002544486f7466697853756666696369656e74730001c905000001650a2618436c61696d730118436c61696d731418436c61696d7300010406d9011804000014546f74616c01001840000000000000000000000000000000000030457870697279436f6e6669670000690a040004c82045787069727920626c6f636b20616e64206163636f756e7420746f206465706f73697420657870697265642066756e64731c56657374696e6700010406d901e905040010782056657374696e67207363686564756c6520666f72206120636c61696d2e0d012046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672ee4205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2ecc2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e1c5369676e696e6700010406d901f905040004c0205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e01d10501d5010418507265666978386c68436c61696d20544e547320746f20746865206163636f756e743a00016d0a271450726f7879011450726f7879081c50726f786965730101040500710a4400000000000000000000000000000000000845012054686520736574206f66206163636f756e742070726f786965732e204d61707320746865206163636f756e74207768696368206861732064656c65676174656420746f20746865206163636f756e7473210120776869636820617265206265696e672064656c65676174656420746f2c20746f67657468657220776974682074686520616d6f756e742068656c64206f6e206465706f7369742e34416e6e6f756e63656d656e74730101040500810a44000000000000000000000000000000000004ac2054686520616e6e6f756e63656d656e7473206d616465206279207468652070726f787920286b6579292e01fd0501e101184050726f78794465706f736974426173651840000018e1c095e36c050000000000000010110120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720612070726f78792e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069732501206073697a656f662842616c616e6365296020627974657320616e642077686f7365206b65792073697a65206973206073697a656f66284163636f756e74496429602062797465732e4850726f78794465706f736974466163746f7218400000e16740659404000000000000000014bc2054686520616d6f756e74206f662063757272656e6379206e6565646564207065722070726f78792061646465642e00350120546869732069732068656c6420666f7220616464696e6720333220627974657320706c757320616e20696e7374616e6365206f66206050726f78795479706560206d6f726520696e746f20616101207072652d6578697374696e672073746f726167652076616c75652e20546875732c207768656e20636f6e6669677572696e67206050726f78794465706f736974466163746f7260206f6e652073686f756c642074616b65f420696e746f206163636f756e7420603332202b2070726f78795f747970652e656e636f646528292e6c656e282960206279746573206f6620646174612e284d617850726f7869657310102000000004f020546865206d6178696d756d20616d6f756e74206f662070726f7869657320616c6c6f77656420666f7220612073696e676c65206163636f756e742e284d617850656e64696e6710102000000004450120546865206d6178696d756d20616d6f756e74206f662074696d652d64656c6179656420616e6e6f756e63656d656e747320746861742061726520616c6c6f77656420746f2062652070656e64696e672e5c416e6e6f756e63656d656e744465706f736974426173651840000018e1c095e36c050000000000000010310120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720616e20616e6e6f756e63656d656e742e00490120546869732069732068656c64207768656e2061206e65772073746f72616765206974656d20686f6c64696e672061206042616c616e636560206973206372656174656420287479706963616c6c7920313620206279746573292e64416e6e6f756e63656d656e744465706f736974466163746f7218400000c2cf80ca2809000000000000000010d42054686520616d6f756e74206f662063757272656e6379206e65656465642070657220616e6e6f756e63656d656e74206d6164652e00590120546869732069732068656c6420666f7220616464696e6720616e20604163636f756e744964602c2060486173686020616e642060426c6f636b4e756d6265726020287479706963616c6c79203638206279746573298c20696e746f2061207072652d6578697374696e672073746f726167652076616c75652e01910a2c504d756c7469417373657444656c65676174696f6e01504d756c7469417373657444656c65676174696f6e1c244f70657261746f72730001040200950a040004882053746f7261676520666f72206f70657261746f7220696e666f726d6174696f6e2e3043757272656e74526f756e640100101000000000047c2053746f7261676520666f72207468652063757272656e7420726f756e642e1c41745374616b6500010802029508bd0a040004050120536e617073686f74206f6620636f6c6c61746f722064656c65676174696f6e207374616b6520617420746865207374617274206f662074686520726f756e642e2844656c656761746f72730001040200c10a0400048c2053746f7261676520666f722064656c656761746f7220696e666f726d6174696f6e2e305265776172645661756c74730001040218010b040004782053746f7261676520666f722074686520726577617264207661756c74735c41737365744c6f6f6b75705265776172645661756c747300010402f10118040004782053746f7261676520666f722074686520726577617264207661756c74734c526577617264436f6e66696753746f726167650000050b04000869012053746f7261676520666f72207468652072657761726420636f6e66696775726174696f6e2c20776869636820696e636c75646573204150592c2063617020666f72206173736574732c20616e642077686974656c69737465643020626c75657072696e74732e01050601ed0130584d617844656c656761746f72426c75657072696e747310103200000004150120546865206d6178696d756d206e756d626572206f6620626c75657072696e747320612064656c656761746f722063616e206861766520696e204669786564206d6f64652e544d61784f70657261746f72426c75657072696e747310103200000004e820546865206d6178696d756d206e756d626572206f6620626c75657072696e747320616e206f70657261746f722063616e20737570706f72742e4c4d61785769746864726177526571756573747310100500000004f820546865206d6178696d756d206e756d626572206f6620776974686472617720726571756573747320612064656c656761746f722063616e20686176652e384d617844656c65676174696f6e7310103200000004e020546865206d6178696d756d206e756d626572206f662064656c65676174696f6e7320612064656c656761746f722063616e20686176652e484d6178556e7374616b65526571756573747310100500000004f420546865206d6178696d756d206e756d626572206f6620756e7374616b6520726571756573747320612064656c656761746f722063616e20686176652e544d696e4f70657261746f72426f6e64416d6f756e7418401027000000000000000000000000000004d820546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220616e206f70657261746f722e444d696e44656c6567617465416d6f756e741840e803000000000000000000000000000004d420546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220612064656c65676174652e30426f6e644475726174696f6e10100a00000004b020546865206475726174696f6e20666f7220776869636820746865207374616b65206973206c6f636b65642e4c4c656176654f70657261746f727344656c617910100a000000045501204e756d626572206f6620726f756e64732074686174206f70657261746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e544f70657261746f72426f6e644c65737344656c6179101001000000045901204e756d626572206f6620726f756e6473206f70657261746f7220726571756573747320746f2064656372656173652073656c662d7374616b65206d757374207761697420746f2062652065786563757461626c652e504c6561766544656c656761746f727344656c6179101001000000045901204e756d626572206f6620726f756e647320746861742064656c656761746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e5c44656c65676174696f6e426f6e644c65737344656c6179101005000000045501204e756d626572206f6620726f756e647320746861742064656c65676174696f6e20756e7374616b65207265717565737473206d7573742077616974206265666f7265206265696e672065786563757461626c652e01190b2d20536572766963657301205365727669636573403c4e657874426c75657072696e74496401003020000000000000000004a820546865206e657874206672656520494420666f722061207365727669636520626c75657072696e742e504e6578745365727669636552657175657374496401003020000000000000000004a020546865206e657874206672656520494420666f722061207365727669636520726571756573742e384e657874496e7374616e6365496401003020000000000000000004a420546865206e657874206672656520494420666f722061207365727669636520496e7374616e63652e344e6578744a6f6243616c6c4964010030200000000000000000049420546865206e657874206672656520494420666f72206120736572766963652063616c6c2e5c4e657874556e6170706c696564536c617368496e646578010010100000000004a020546865206e657874206672656520494420666f72206120756e6170706c69656420736c6173682e28426c75657072696e747300010406301d0b08010004bc20546865207365727669636520626c75657072696e747320616c6f6e672077697468207468656972206f776e65722e244f70657261746f72730001080606210b010208010908c020546865206f70657261746f727320666f722061207370656369666963207365727669636520626c75657072696e742ec420426c75657072696e74204944202d3e204f70657261746f72202d3e204f70657261746f7220507265666572656e6365733c5365727669636552657175657374730001040630250b08010c08b420546865207365727669636520726571756573747320616c6f6e672077697468207468656972206f776e65722e782052657175657374204944202d3e2053657276696365205265717565737424496e7374616e6365730001040630450b08010e085c2054686520536572766963657320496e7374616e636573582053657276696365204944202d3e2053657276696365305573657253657276696365730101040600550b0400085c2055736572205365727669636520496e7374616e636573782055736572204163636f756e74204944202d3e2053657276696365204944204a6f6243616c6c730001080606e9025d0b0801170858205468652053657276696365204a6f622043616c6c73882053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c284a6f62526573756c74730001080606e902610b0801170874205468652053657276696365204a6f622043616c6c20526573756c7473a42053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c20526573756c7440556e6170706c696564536c61736865730001080606c108650b0801240cc420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e009020457261496e646578202d3e20496e646578202d3e20556e6170706c696564536c617368984d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e730100690b04000cd420416c6c20746865204d617374657220426c75657072696e742053657276696365204d616e6167657273207265766973696f6e732e00a02057686572652074686520696e64657820697320746865207265766973696f6e206e756d6265722e404f70657261746f727350726f66696c6500010406006d0b08011b005853746167696e67536572766963655061796d656e74730001040630790b040014f420486f6c6473207468652073657276696365207061796d656e7420696e666f726d6174696f6e20666f722061207365727669636520726571756573742e3d01204f6e636520746865207365727669636520697320696e697469617465642c20746865207061796d656e74206973207472616e7366657272656420746f20746865204d42534d20616e6420746869736020696e666f726d6174696f6e2069732072656d6f7665642e0094205365727669636520526571757374204944202d3e2053657276696365205061796d656e74011d0601fd015c4050616c6c657445564d4164647265737391015011111111111111111111111111111111111111110458206050616c6c6574602045564d20416464726573732e244d61784669656c647310100001000004a0204d6178696d756d206e756d626572206f66206669656c647320696e2061206a6f622063616c6c2e344d61784669656c647353697a65101000040000049c204d6178696d756d2073697a65206f662061206669656c6420696e2061206a6f622063616c6c2e444d61784d657461646174614c656e67746810100004000004a8204d6178696d756d206c656e677468206f66206d6574616461746120737472696e67206c656e6774682e444d61784a6f6273506572536572766963651010000400000490204d6178696d756d206e756d626572206f66206a6f62732070657220736572766963652e584d61784f70657261746f72735065725365727669636510100004000004a4204d6178696d756d206e756d626572206f66204f70657261746f72732070657220736572766963652e4c4d61785065726d697474656443616c6c65727310100001000004c4204d6178696d756d206e756d626572206f66207065726d69747465642063616c6c6572732070657220736572766963652e584d617853657276696365735065724f70657261746f7210100004000004a4204d6178696d756d206e756d626572206f6620736572766963657320706572206f70657261746f722e604d6178426c75657072696e74735065724f70657261746f7210100004000004ac204d6178696d756d206e756d626572206f6620626c75657072696e747320706572206f70657261746f722e484d61785365727669636573506572557365721010000400000494204d6178696d756d206e756d626572206f662073657276696365732070657220757365722e504d617842696e6172696573506572476164676574101040000000049c204d6178696d756d206e756d626572206f662062696e617269657320706572206761646765742e4c4d6178536f75726365735065724761646765741010400000000498204d6178696d756d206e756d626572206f6620736f757263657320706572206761646765742e444d61784769744f776e65724c656e677468101000040000046820476974206f776e6572206d6178696d756d206c656e6774682e404d61784769745265706f4c656e677468101000040000047c20476974207265706f7369746f7279206d6178696d756d206c656e6774682e3c4d61784769745461674c656e67746810100004000004602047697420746167206d6178696d756d206c656e6774682e4c4d617842696e6172794e616d654c656e67746810100004000004702062696e617279206e616d65206d6178696d756d206c656e6774682e444d617849706673486173684c656e67746810102e000000046820495046532068617368206d6178696d756d206c656e6774682e684d6178436f6e7461696e657252656769737472794c656e677468101000040000048c20436f6e7461696e6572207265676973747279206d6178696d756d206c656e6774682e6c4d6178436f6e7461696e6572496d6167654e616d654c656e677468101000040000049420436f6e7461696e657220696d616765206e616d65206d6178696d756d206c656e6774682e684d6178436f6e7461696e6572496d6167655461674c656e677468101000040000049020436f6e7461696e657220696d61676520746167206d6178696d756d206c656e6774682e4c4d6178417373657473506572536572766963651010400000000498204d6178696d756d206e756d626572206f66206173736574732070657220736572766963652ea04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e731010ffffffff042101204d6178696d756d206e756d626572206f662076657273696f6e73206f66204d617374657220426c75657072696e742053657276696365204d616e6167657220616c6c6f7765642e48536c61736844656665724475726174696f6e101007000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e01810b330c4c7374010c4c73744c40546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c426f6e646564506f6f6c730001040510890b040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c7300010405109d0b04000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f757420666f207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f726167650001040510a10b04000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d657461646174610101040510b90b0400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e40556e626f6e64696e674d656d626572730001040500bd0b04000c4c20556e626f6e64696e67206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e68436f756e746572466f72556e626f6e64696e674d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61704c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0055012054686973206973206f6e6c79207573656420666f7220736c617368696e672e20496e20616c6c206f7468657220696e7374616e6365732c2074686520706f6f6c20696420697320757365642c20616e6420746865c0206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500d10b0400040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e01ed06014502142050616c6c65744964fd082070792f746e6c7374048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101020000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e344d61784e616d654c656e677468101032000000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c206e616d652e344d617849636f6e4c656e6774681010f4010000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c2069636f6e2e01d50b34dd0b042448436865636b4e6f6e5a65726f53656e646572e50b8440436865636b5370656356657273696f6ee90b1038436865636b547856657273696f6eed0b1030436865636b47656e65736973f10b3438436865636b4d6f7274616c697479f50b3428436865636b4e6f6e6365fd0b842c436865636b576569676874010c84604368617267655472616e73616374696f6e5061796d656e74050c8444436865636b4d6574616461746148617368090c3d01150c","id":"1"} \ No newline at end of file From 0c400ac5439c063b2cb642f93deff7de4dea1eda Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 21:36:28 +0530 Subject: [PATCH 18/63] update subxt --- .../metadata/tangle-testnet-runtime.scale | Bin 368138 -> 369318 bytes tangle-subxt/src/tangle_testnet_runtime.rs | 566 ++++++++++++------ 2 files changed, 379 insertions(+), 187 deletions(-) diff --git a/tangle-subxt/metadata/tangle-testnet-runtime.scale b/tangle-subxt/metadata/tangle-testnet-runtime.scale index e9fcc80047823bd73381bf2549111151c0492d03..67ee32d166f506731809782e0335ecb7d4dd3f88 100644 GIT binary patch delta 20482 zcma)k4_uW+*8ekqp3A-5i-H1P{(4amP*6}&FfcJGsYp>YDG{%5)tmfLE|gfNY*}fs z$=-CDa!GgJpP$G3%*=D< z%$YN1&YU@OhHbBgKiL^>s&v&lho5gXonxf9?R$30L@s#W3!FgmerxqSM3%SJiodY1 zK0@Z?dOWV$?4lVn^hAF7OmEqvE3f>e?fpkX$dx~Nf7t!dmA|w#?wLSHzZf0FQoUb1 z_OH=bY*Zn3XIZVgy6U|5{NAsFU}=l-p5}YOCr2);Wx(n<%?rO<0!GYr%hEXihW^ijk{_UR}#E&2UAJ1cizE? zB-MNO!I}DRhAl`3sVl2B>mXyPlI|UQ=A+BV&u!J#L1UUNzfagPLru1 zlUSIyP@C*MaqkGP&?bk6P`*%6xDrH(eX*-7yJ)7Oq*LJxVQJGdeBZMCzGVO-D=xp_q6p zo6`2}>n()lQ;|E7M~I~pxYhgGo8xJLQQ&>H)9M}GdCT}h%I)*kN}1ujh%BPS9DGxC zl?%)cURYh};>sd4O%%LzM5wo%6nlf-T4X7aG-VOR>0R^IbmHH`N+69o{OYby(&XLP6-k>eQQ&>6 zYYN%n{byG;+2x)7rzglB@5g`2nX-p++cnj9NR~BIj4*x_{fF+S3Lf;Wg$64vNHMc6 zxCh#9`15ZVX>I$T_q~iBq~ho@7V6#m(I|3QZ2B!7>;34XDkB-+R{8O0LOOP|61#W* zCsm|FkjH4GTIQ^%Fkssj_oNYenC^U)+P(WewUbKkq*J9{`)8wREA__xb(vRu7Q+ux zvful{sioe~Q<0<{5F2SH^{)MPnb&qYnjbg5F7s|X9YOo3xB2sBUiOz*66f9bd8xPI zFAkF6b^Nu|OFnma_kOX7t6g9{yvU3a?+(2xBfkews4*Ptg~^X z6;(^UFP|Mv4;uKgz8p;s>xD0U=^&kYD)Xz+)UE0*Ye+VzdIzVSbI`3u^3b^`-l~#j zy@mAN7}DXL*Si_DPxRi;kE!IO{z3aX5k!3U^#*=HB`tc<;ct?;Y9eR!%gFyqo$`^f8Or8Aog)W(pbB_F3P}%qVM{-@n{SIu5py z5mYakq-$ z2g+xKlMs}Pb$63U@tT9EM%&_32QlkOyY}oT@_~_#6puNG>Ayio9Eu~exsTeK1d>0{ z&U;DZbEEx;Ku5W&!nMj->(a$l`+hvZ!X(oX;@>I6=Bqs;l{^_hI<(VMNyh-?uS_E! z45XjQB&(4Yp)-h+xWw%<$gNUV=Q-@+s~Kdxk4i1=DpD=MF0sbwDvCozFXs9{Z)AbC zKZoF-PKtJPCRt@r@9@4HKTIs1P0C1)$UR2Gw0CEdY#*FRm_v56W0Z)h>qxlv(HwFo zrN^lFdJP*Ti_*w(vG+QX&$}quE^_CSaIq|(IOu6A?w?O$wb^qCbkxv~#1}V`w5)Dw&Mzk?sS->a)hk!Js>)q8C!vJ%%M}vrsi>~)p(J=A z-U>-u>8|nAmacX=0n;t!6_AKw-B>;5>II6@O}!^*n0T;&JVs86@i&p_q(`i{iHsws z#nzih9;p}a-bAL-GgQ1*3sV5Zj3#Hrta&6Rwijz|Zbe1)9jiu7B^q_`kP z>`9AL91D|S+jv}M)m7zwMG9e}q?p`DRpwon5;-$|p?g)8v$n1V>larnjLdbFPtM3l z&zdpA?~8>&E6>ukauAZ-Oqj})5GFobLXu2jgRMIvE^pnhNC^|0Zz1ylC6R?QASz0n_RTG1m6Tgd%rW9rDGAZGEhSSRka~%Rl6{OMh=wwfNs_gf z%g72sTw08aSP6AeZ{y?)t#l=sL-Fy~t4RRC`&l<>k?+N8$OsdrjC&n<(Gd2CBrxfA zw{8YzFp_l5rJT3)wCpV; zov~yVEcz;0nAq|F2{#?4d@e~9%@2@dk}m%E0LeklvX#Wsbf#N2()uA8vNI#amaXJA zk|n;~N)j;L!nctGn#;WD(<612DayA&g7j$^uI=1LMsh5Gzxg>y2MM42oJ;`|MDTVJ zF<82EJ6RwJeEt`tA8)aL2bqQJ7dyzOT%3E7jL_cy6>$vA`rzGUrY{}n@RY4~mDg3c z@z_Q7=4F`16m@u#PC`(@Hk%giRS78WOga~JGX;-gI!hGUAG(eycoc4P(K?1Nbvm4z)iVW;Nil6? z%0}^82br`<_L**B3LYJPtAyW*48z#Sijonui79w=fE^NGhXlZX2_U&c_b>&I4$v$C znk9fF6#)AsKnqjw=l};KzyS%MDw}kORta&CDR^{BzI{CQ}E~jof4o^ z0t6TU$0WdUrr^;5x+FlC1dx^|i0GC8Cz*mr2k4OiJq+zLive+3LY!d=9v$MWggA=~ z3p4j5};oKSPg*l65s+;@aO=91Au@F%w_<{VWk!*WxVC!1o4G{2$B#% z280}I8pahoIz)s-5g`GF831zpX&hJZ=l}^4AVC5QHvp2kJ`?`>1{o7IFwID`F}*zl z1xl)jdy^!LOqbX)xPk|Qq-1d=OBBCJJkWc`-y{=*NUrv;F7jXi)XW1X$%A->end`@ zey#r_V&VhVL&#_3YfADC{e}E8faD6)h|vz6l}1p$n6#8ei8sC?BL~voeMLe^fe1K< zHMu}cJcl`4C<@O(IW7`?OR;u8bPfQ8TJt%wGME%=<_iRy;Sw?8B9yID%f1LhAvjmk z-9eQ+`3_d{1*jb@=1`g@-lQ~Dyi!ZYif~3#$Mq9p!)C5}Ex2P_=&I!kO5_$wu`h5{ zR^RT@b&yei8l!2nnClu`?CoIzK{X(|$2t9iu{v%OTwST8rG!drueH#Ze2L<6F#P0x33|E-k`_?F`wdS%=eSEo7s3$xah!1NWY~ z#jdY98jrxP7{hr}6#ZTdrYX#L5wND?5w0B}tT z_4;KUljv#HuijwmOEPGoAK)LSW2ZcbrfLQ)Wn`;(Cx>3;BX`V9dT3xV{O)R6?@L>v zE9CCiRij%0;>le4I%@=zPuF5QS-K)X+cuk8DQ)7~+D!H{qD5Rw1F%!k;^xwFSn<-h z*Y?h%Zy6SKgxIu@1{%ed=oQsFOG6HtWMoy$gut8S*R3`{B85;}&H z9di0iFkVqs?C{r@uC1=F@az%|OKB|GCH5_)iF6kitpzNR?9niPP7u;8&Mm{F>sdyJ z8R!7aNsV=eSE zX%gRh=n~yR?lp{%wJjXzgQgT$lD*jTb()`=7k*U?J3v8`Sk zAx7O!XORP9cRgL?+xUyF+vyuWDH^t(KJt^I=z6+oXpt7SfyM`*Y(@h((aJ?-C9`XH zHqbXXIjCKIAAJfw0xqgQW)XrsK;weiIa!O%LQU-om$TN}R}*H9_YBy}9b(=Ckm+`j zvz6|HVfyJ-nh_xlXiv@M26U%L*+#PsR*8mf^cXp&-S8mA7Oqfx@geNoAk`Zlru(H; zDE5oEinvah2t^W;TyPrK1QLBrHn>u>~T8ZH;AI*33`LkhUj{NjwU5q z-xH8>}OaZ?M8iXE&FU3-VS78CGNiE`XfnQ>h{m6@*&s?08EM{e%s z-CXJBV$%Vr!f#sWsHBs+whdn3yaQ`lk5r+G%uMFWX=Iq5nZlJbV&ZS8ebZT#ne?)0 zT6mXt6fhjwG| zE!@bV-8ke%89B6@fSldPq1|NUB8(iGO+_x!$bkXr*CHEbWWjjz~ z9OPp4+!PR#i`-}<2V(NX^Uu&Fn@)lkFnlB%AGQN);X@5U}l}&y0K-}d99mOW}VS22$meMNjB@Il359oNof?B z70G56q9-Mf*$6!;8O%oNNy$$ZrY9vcS-75*oMfZ)q+}zr>q*H&7NIB8WinDvW?U`P zQF>akjz#N9$u}0GCneKZte(u1$#y608JcOD6@-H1&=hyAnnEC?gMm3 za*671b~x3`%nm1NfaOk+{Txju7P0aEX(A_EMAUm&M&LDlZJS*zeGeRL6r0|I z(a^Z_18AJ!ZW_s&R3e(YY3MK|Ixm0z_y!$>) zBYW^Ii!|#HXm6E)ayAy(e|ah1xZrQ0wKOTYBiv0BZh}CWaoC&9UE zG{8uYg{^xOMOx@z=qXChi2lFQD(pYX&(LssMQ{z^zv9LxyYQT&PNcifVOUSfhDLcu zdrcy$7t3FdxT=@NM8MFTwa{4L2S))jsYk5qrL%)EcO19YWnSf&mQkW8rw4JI>ZM^> zunzqFZD)qe(zBP((zEC^aGzE6O-5m_YHSYr{8qYN$wiypo~HCk4k6n=1nc?Bv7R@u zo>$G@++T!?&aYwZUr@bAyzi7w!IU=);D65TT{@ z(ck;h0_jZc`tRxI0}gZ)#0uAWngOHb(epHZz@~lsB8}31_!m85SR4@=3K|En=pTPh z*gg~(2RJn@XT^UZ=M~1z!GCNLEh-yFRPBVya#%FnIZk=DTGiQuDX!Zq zOP%HAH7<|GVj^k26Rx@G)6zt?h0O`MQneWIq=ik6<>bHAo+&=Gu)P0J{hC0w_==xm z#nC_(%7aYgLvbV+ZszX;*<)9Pj1iiZz5O3Pwb)o4WF5!di2n&@Q)!4vcZbahVNoPZEDvFsp%JD*YbyeN z7n-KTh-X7sE{W5=4q*X|VPJ4X9VUXp*hmtj;Z*!liY2Cf6!XT$lO#C?)%vRNlOdR? zh(bF{^66T!-Od7i>0xO#u61=d;3BY*#e4@F zC%mIs0-2*79?d2b5+|A`u^3^AV{vd|Pl#jDaR1JYV>iGb@^&0c60gRw;YK=*mzY3G zYl%8aj2gotxzj`*5za&&6Su&1yW0bwCA^cXoY(`@x=bYgIz5$r4Gs(vj8?XfVbMI< zL>}^zL!mpzvf<*cacmeo(K+#Kk_F)pb+xOjYmBUwIB@9TT7`3Aqd?pi7OklB)jAs*Ab&v3zHlloEsN?~~Xx;xy9N zC9}EM_31)$Aen{6x=m#2%}!6H-)JlLn{ZroJN!vK;`VSGwSK_EgtF>^oI&spk6Lk_SUM!rz!eD2) zCqQL2r@)Q#_yjb&QM@^UO@YPrzY|y@)(uArOB~e=W))%LUhAsGp+b!mPnh-_^(G({ zBaL=nOJPxbi%(L;cPT8KH=4);Qf`GK6)JLviQKE_ZcJr%SUIj#mZeRe$i@>H&N7|s z(uHl;0NN1%ks}e-?CZoqzfLsEHm8N}hyKs4DO(LeF4IrJh`HL+B6=r*bqBj;*J+&)SOzs$ zUAn?urRS#(k$d=^PfDulOb`*hH!CtA&%UugZ6JFugN^nT1)l-5sh=okFO8G6h2yfJqHWK1({CK zCg$Nx@V`{nkI7||rr;}M5Y~Kl$uIUvK11wOzIOV0b{C~;fJj?P$NS!qejYN5c%c9* zPLOu8fVC5xt#-_VOzSQ&J)LM2=`OLQL@O->!9F4%S^z=m6W~acbc?MfT5=Kljt-46 z!r3GJ8-uF{QARjl>l0vPsQ0-yP2&EgY)W$f5S4iTa+P=<0|1qH{?gEozc8c<3Ajv) z5*&4)3JJJ$!YKQVP^gi5yFXvXg2c-u&~Qo1u-@oSIgd=uhZl~9424X?qW{`5R!Jia zY+~~^xN#n=^aW`E~o=~#4tAzaK@!5+0{NHjLNqs|hiRq>@h%OYlXk#{7D0h_`;cN07yuNZpbw#fDQyI&kxqeK^3qU-I zU2~PQ923pgKZJ?Yk6HYPf&gRXSrjl}=?LcCkU1|QQ=sSppE!Yu>yZg;lmu)HP?`b|v=XT`RkN!ZHlAHIYzo^IU=|I_c$669VGg>-Z&Z?+ zeRS^kqq7;PxcMYZ(ESoAvMolhuJO4B5BLEekRV)X4e&QZ4qiTi4gwAn=%8q>!#VWS zS|-EJZmeaAtRsMk_ByzTAFhRM)G3;4VZTAoOSq3}*&J*YN7u1YBijQ=+Txm(gWE)< zUF6rXd>gib4t$tjQ(e7M1mDg^OLR9_FU74Wz$uYUx}D|!XJp636SsrgMmS37W#K5w zaf1ipS;Uaz62H@_t^l#`I>eqVzk}^1q$MhnxE3=8?b)AG3e9l1Si7= z=$FHR{CQbqF6MUSLV)+kG`m=~i6uoQvq8Bg=ID7DLJ(`FVa#%zWG zkSq!|vk7?BZ)SO6su}hMJWuu6zNv*SsG{K>XulKFOyb;Tc0INt$lJxd26i1b1EK+j zTZGv9Gc12GqUC4MjLAR4`ko;we}+ZU|I0YJcW7kk@gZh|vti}|4WTF@I6>y-;Fpvz zB;Z97o9;n~t88@EJ!}?GqtRQ!;&iBF_M(!Yr_zeyd)4XF*uCsF6$Z0x!BDj6qHQay zj>PF=rVNSosZRtq}{}jGt3ARiPjpnvAq<54zhj>);~R*Hph>`97$L{ zQ*uRhBO6ci%-*i6BD5D9*$8UMm){D^@GrjmFssK=D_+sUwH@|gj(BK0%c6_Sh~|jb zzS_=WIW0Epr^o3#u&F5#Nb-Xh4liY<+DA|15G0SF_s;Lsg&ZIN_EqwLK1gKdd$I!vP<0g z7;CWZ(di3Tf|X_wu$SEnWAmZCYylRT&-Su}=`CjNm|axkauqn&n)wYx;fqNyg0&8y zn*Kvu%?cji1d4-5(8FdJo>%Q-O>0``Easc3IkCR`AHCgOyG_@q=ACCWbY$dqUBl zsZzQIPMAUFarp&dkgU;Xh9J17e#@T2AQ9x0w^$Fi28(-bC-OyuLE?Z!OKvS3r`8|v&EQXGrX^DN;w!baJ1WZ;SX zp}7_Xj~qsXw_8M?2NbM6f~7rQJa~j%M;BSdu4Eo3`j5bgkZ;i8c#X|Q07c<=?yweG z$g4hi9EgIC$F>cp|1sjPuR$9Yh?Jx7RuqZ_N1<1M4oyUg9Y@(V%oB7g-{?`8*wn$E zrX@ZSI#c;5>a>VYQ+XtJSqKqFCSeI5HIXM_AFFfY!`C57F28=yb6Sj!yRXo3w`Hi@ z2Se_i76^W&WQF{p>nsW$$qIa^vs^MbEZQI6V1WUoUVHx!>|T}C4}J;|cb#Aw-DpTe zPJ@qtt?+~lTsT0PUx5D>%Voy(7PJZ5V2gOXOJ8%|>4K206TMw*K31Tae}cmSmo^>| zd+Tw+z41@X8jTZ?sY8xJ5JxXN&|py-#jpRw%4w4Yr`=In!k^hv0{;H&J@yce?1y)= zDWO?xP=QRD47D#c$Kq}b(H?PEH!Hw_{U5rqvDhyx@3YKnuK?bxGfBBu**~Of&6jsg zLIQt_--J0}G0w?9f1jPEq*ZjDWXnfG1?&1^fopAb4bEjDs0Z~%@=2z0*dk`#hr@`a zAF-EdyKlT__4V|GN6RO+Nt`O?Y14$s~@-YSfF|0KE={J@e`I2a*QKBFX_@D zx2H?ge!@yZk8zTgUk+8_uC33nT3M|qT?WaC-M$e$>DN@Zjyt$mRZhxAk?j%LJuK03 zTK`}_V-c-AY>FPnGt7T=IqMUXULVqaKcp!06O+EndD#c#;ANle%{`WW*>bN1noRFp z=cgKqgPyvTE8Xiah;Ke+@WdM}ip?c#WFTV6pkLE)heo7sqX<>_jO|pZB~ZNc z91fU}vxBOOUw1pShDH7X9pc(8?3|*i>|DoN13LY@8kBE7M z|K>_W;QG!KF^%%qvAaJ{`SdHn?BhHf=3XJ=Uju3u=kZs90;ahJ)Fkl*=XdEgErG@9 zRQat~i`rFQl#1>;q=rExD>`hk4pnY;bRo!!K7`2dz#v(3qNp(O6oiZKGV$n8Sx&>O z3LbRJ4%i5*=)$>&_{PMoCJfE>tZL)?u@ zg9t>J6ydaUhxl$3p9xC>teK1@R42T_4hzs% z1~!G#g$%BQE(ooK1KtzuL&xJU?U9H=%(xkXs1Y()hzS;*YaIV^rHPQKzWWC=X2>Hz zsj?fa`o&JMJqlCnS#5U|zXjU??H{B0Nb{yy1#XWAy~boQ!Wxt${%c>EL(U+h)UmR< zMn5dlC)IjanI2$1acvm&WXtjbUtSmXM$ru8 zP+p`ILF4%~0|sf6^}iaVBVdWj>zRp4lhuF4Ex7#VWdXuehByyMzMsE($IkLs3wZM4WShUFC)h6Af+V0C6jdtV7Pvfh6}4t89-Da{Ne8TX-WslK z266=hP=nAt0~m|xLOw=ZwUCcv88#w17D52lFXXnUEE}1-sA^4B^&M4yVMeln3|Z$R z_>=G&EA|xeo3P-VE8+=QiAOBr~0Ex5K^ASxH} z1^GEP*zZ+13xo-;$B!z7L%OoahQ6%!b!Cx6Ew#4qM$*qlGG zn8(4T^P9!kY?nxoJgedqe_zaJEOrgy=;6!5Vq{zrI_w@oMx{R)m6wrGDP|T!*X+2N zXGE^Ek?2JpSNU~L+yzXzL%%Lv>c-ZjPCQ%8$7AIkzJzBd*A1bg{_>HnM=PMCUeqpu z9@vNremvS#;f8&+Q5;zU`$#W}yZSP>(#9c_H~3TDa2e$dlJcVeljtqtgJMvzRa}&> zMv-_6PaM_+Y}~fRw$;{XQ+9}@D6{R7W#%oiWRH0G7QQ5{c?dcCB{`R5bH5)wKH=PN z2xr!Q{jC_tdhzJ3khd1`<*hv7sslq9*LpeQT7eXdlP`MErr-fZnWv>I?E0nr z=9sgTBqhNJNpau@mm^b*$Om_=+vV9Wjx6OxBQN)&w~K@lo&&FVSqUG9#QptJ9#;_lLoevvesB}vXo0V{>+ZN99xcFF~-Rg1N-oe9w17;RI(AG!ii=7fY{>X$v6;v-U*q`6CXMGM2a(< z6Hq0wEBGjoK5Ye-htp!k3K$D#Mbio{gF#-GuMF}13TVkZaZMRdDsG!=_g3;{6qkxVujYu`FBUhhgL&W<53J); zM^;j@#GW?0qPlF2@rM#T8^ycp_#2oq-WvWQ42!uQUP^XpPkZ=qN)Bi*)$wZyLMt!c z&i9Z&{NaJS6cQG|6mfJtj}Wh|$0$UIbL;t6=<|p5Jdq^?Bn!HM-^4Nkvc$p-{5;DE zm@k@EV_`45lP6Hpu5I1OD;UYs{%12U;Ml0l*~0$`I6}Xc5=#;Kk@i^A4FktK|s(5QRYhVHe+EIu^hcbEGYSJOQQCr)_wG|D8ah%J%cI zAmIM}=s}!#VL!hS@^xW9zZ(L3*OORw&TD^ulGhPtr-(c%V z611jgU{c`y<^ld|6U4~DAFfd~0YEOP4(@>j6Pr5@t75ZuQP z@iFEsGgtVBj(ibxpBf>~9Ks-B71RKbC+^qyX1vTVfyR81@)BQ$z=H>0;-R?UD)zn1 z?;l>k$lFN{!wZ;S-l9!=g)cDSKt(i{@fhu?4s-yc_3zjD1_)XG8+0G^-|$`;)BF2A*zE1X_8os4;GN>*?|5Ut4znFhaf(ylL2e)T9{13XiBG=g z)6`b;ar0&=pbl;N51923%=`N}p|HWX{)1lx(OdtQCtDx`ZA2XdhQCkLA0P^Ur0Nr3 zWHnR2#Wr<0SF<1qzvAlk=5?H?*wCF3=eRlrL+?=4HL#E$Qq`x;y>e*oa?BU+TGSX( zY*KH7E&8TOZA5bm0@N9h{Kf$FQF1{`HmfdBVG-Lc08+(|7WFDPZ>9&T(@~{5P(`@7 z)*7f@Ah0B!x2YR2^~VRPZ^^ijzF}%V>wuOyJ6x5ghUvlTudtVTJ6Jt}dHP_8Iu3&Q z+Yt3A>^RQ|b#>TQPQnPEI@`IbXf?u3S65e*dm^-NN2u;$7~EUpRQx@SbP=DZK7}s7 zov7Z4JB)La)F`yAl_#qI%MXU#1ZxgT!jBp2K~AWlqC(sw}k| zS~h2fng|ha%}_tY9nG0nffuL6#jDh}F<@_Jt6yT0YB}m2j6k5a_-gfT0%g=aOZ|!s zR|8{}=tZ^e3b=F?DAsr9s5fGmqVv>oEGRHUMD(NJOch=WoOaVz}t_Q?fvFQf&uh@l@->6O_UD~5J zqGOPX-U78y1*fiFs6Il8Rdg>@XCj(Zgcd>mRB=<0T7>}P_9C?j10m)WtKnppwz3#3 z!@z%hi#mtL;ZF~UvA3#sVeI$asyZ>Cbg6nRn2^6z&1Yw6iP*7Jori=|{B5aP203zx zf)e$?)Mz{YZBhp-zEsUOucbarPWNLlqFYmu)x0LrnGw03jM(`SBjJolxlck z9BYj;G>5c3@mGN4wRYVX;dFR>5I(oe#2n(7hyB-(+HMajx;NFjaROJKqJO%C5bgLJ zh&8Tq>79_Vum!Uh7Qjb={A#yn`H)tDt46;zTRu^F#NqQ2ITj#@*Hi1rpW{fKd8yFn zJ0daodtqehEN$sB^%)aJ+w4*|bGp?kjwh-c=pL)cPg3s{+ip{LVuK#HM(wAEt>V`4 z>a*g_3XDm+_Hl)JM*gjkjw;NWUK7cqp?h@)_Z5^r3>M!S?sEjVYX+i!I^ql(RyFWS!-~bUUHqQ%H?r;daY9p zhyommIHef(S*IoqU@vo>x89o~bAdh^;ez#EflY1%{_4xUb9Ar)Z^>MQ7pt}$5@eed zd=36GhAsMbg9v4p*zHlXp^8p=)M>1n#)%QNY8y|m@rT5)IyGE;R*PAZEUb0vUm$^B z*QtMCVK&@xzFqY~xz4*oy^7`7VnpK|>TQ7`wqWV2$*~m(vR?fW0csc4%jw|M=50`) zmn#3;ooeLRgKB7%+@~K@9f;v{L!?}e6nK;nK3`hl_SCv;ZjpT#)Q|z6@qfc_v?)`| z>T2ZXuXKepnv^Z#cXz3iFpvLnmzo2sDPtqlag(UrsM;~X?%SxAVsd`5QGJWW*mjBM z?^b8xQsdWmL%*{|HB8*SS8#T53?od7)w`!hf|xiKWtWK$-5ucd!Wf%wEON+ z9Ry16se2(ohsDe-AiGCw*rLjn?Z_5&7G4*(sGCOg(6oX5K|O8~oTMGv_WRUW7S=_x z*SP9Su~l}}l&+OAJe{^<+8bNdZ>c%VW~*>j1s@l$JfubpQ*`_Mjqr zSe-|qB7yu`ZC8_eh%bn-rRej_xa`xYUUFP)R^*2=m%%gJ5bwoYefM7KSJBgP$>kxM zcVcpMibY-0kiH)(H5l(@1Sbh5&tvT`OTX~xnTOPaB=!nAT`Y_k5}ea_`!^!xw+evbF-$J%?Xz4qE` zt-ba>JasI1%PYaAQfIZJf9FBdH;l|X^gTOgB3C_s^Bqod{%CdIN0uI{7N0RseMmn~ z$xf$yANpdaKhX>Pnzrf%2bzWva#`Hhk0pCdyMB^o7Gif4RlCZ|u6Sa1U-aSCxvQOJ z)xs9Y?esDcZLgCs&)~-g(kn=tc(TX&cr3Yk=-$U~r0g0Yo|%UOJ!hYsO)R1#iVZ)s zWY3d?sDFGqk&sMLx0M8XZrnGiD=GGkm)P8HXSF-~(Aj75e*@@{*q22~w&(0K^A08M ze~ff>{QUvmogVyre@?Fv(J+iffPe^)QF=HgTBRgqW|gbRIoDCO5-1dfP(@*}ilUem zl?pP7MS6}OcKTXSO#P_hM@2(A8{}EsGL-~)o@g0Nf;?~IH`McW%izFBN^Gt%X^KU$ z&#A6*m96ATtml^(23viVz=^fhPB&NLJu_bzK@vUdUl_0drrZ2<;F_Xpvkn|bl09+S z-BAI+s9KaD`SMjl<;$u>%9l-v)u|X88c)gOiRCqA#m?gS&Z4ZEjHH-3;}s>IijH(P zktXWz6kk8e=O_wSEYvgg#jG)@-fTK0cG+w$nxvv*ZjO~hOh=L;pDEvpk}Y3$CFhSv zE~q5;&{s#3IM1WxQBS~Ifu0d>JV5frgCqFpLs_MJ3CpGaqOOqH#rVhXVT@$h`g?K3K*^l(0x%%a5XKfS!n36A^EDKB+$Wfl+;1uvs3G+ajJdHTIQ z&$398l1Y>TPs!V3iNo{c+c{)6@C(QsO#v^E>|~q|`IzPZLSaq541lqK1~r zMwL{-gArzAC^fPmL#g#NpIl1Td44`Qgs!8W^?r8G`1YWTI;z-+y{x>d)KOAL37@Nw zr1A=9l|xe8T@+X9C@XeUmsiyqFiIVI3-&a(XOYdGPue5#`%`;F&}K?9jIm}daJp8m zss^Vwdy?OeC-pkK>-|8o&2#trVRTzJ1)jIxA59uO|9wA;Z1-gR^$F7G`TJk9M>kS# zn^e9=@~nwsF7c!2KeU-Dcrdm-)L+?y6f^7MyZ6v7f7{2%{zL!%(8I_<&(@EVNQ>BT zhz|CA{BfC)j5}2J_h>>|MRPW>d!9O5W+cPZB1cJy0eon|CneHOuw8@0E3wtg1M zJ1OXq?f5^UNTjFvpM{={|A-;6p4jt+9{SH1EM~pzpHZGc|6KOa`52Ois)zV2My~1Y zHk>zm!aq;sncUmalb=WN(yq*)FQRD;*HJfr5kuD*$=EOBc^xOm^$wo;GM;WW%7*asEFqH4%-cjA~RV>|a0KNQGG(XtY{|#S9(-x!r$k#En%}8c`6HT0+_KSs{ z7r%+7>r@^8*v=Tb*+^=g;e5YJnsq#*E=H18&&-P(NE@2m%a5t#j9&5Lw+ZBg=iIk< z@T)4>s~5d=DUlNsIj?6XT~30^sknRxzhLtAb@O)t^a%AlKQLG<+)DgB8@@|2rZM!; zTi;c(uJo*bEwg&lBDx<5);b9Jhj;EnjglW2d5K;J^NEQRboF4s-0n;6^p-?wMlt|lI{u( z6<-q8fsSHlqNBQ7h*Q>nkxx=G+o?IPn4F@DKZz+{vBC-aQ*{c8Jg-NAx1 z&%s+EDJxu6?&`u-P6uGx#mwm>v|l^y&Q!fXQQE2JBn=YxO(&0$Q)2iGGM1bXMKj0{ z(6(g;$t5-7wdqwD_`)1APes}Mg=9|X6-uV& zR@S&ymlx^kKWl1I%yg*mE8_Kq;NDg7(?U|i{TOKwzbqsZg|>(!p!Cy4B++yYMwSrK zZ!sAeYhlDbbUtizqC)I$XHj`sajzof8Wp!LCbv++Je5gd;;qG`-$<2_sm|h2>FKGN zH{3ACwX)1nT~h@ksWRyI3A%o_Aj!?w&`j|YbxX)Vab_X$6Td7X7E=K0#vT>a7kjTF zL6$%SA6`PTVuJJz0~k6CW#$NXMPX5SmD7KIxeN2ED3RKwC1ho{plw}GES{f|{Ix9w zB&}OOyGt)GBM&kf%RJE|LdB!SB#OjqFBg;LggCUQ6~s!YgL<}&O4pXHB$FvB_qgP2 z#B2L+lj|&ATTnsDtzfQC5l8v1277|C3neIN3 zRN>x2){%5^c?*fhVhhc@figqY^gu4pe+#>$x0g?(tXCEM=F+dT}Ktg*; z3mV95NyhUY0*P{nr*@DD$bPYde8OoC^R$l((LULU7G3lQG!bY3WBvQaxQkXfi)%`p zxgvWvNztBojLhq*G~26nzqJpj2GAv7j@I}TnM=g6on(Oc_KApGsJGF zj}YzTGvs>)dft4N+)hcpmhv14>C&f~;}BWOX+9IX8?gF5(nyM*15R$u=uy%)oW(@* zBP>CTe-Wx>o+y72t0G?8`yzRlf|;vdCSQyc7kX8VzS1j` zMtDyT>3+R3V?vQpKF z)iR}4y!JX7xn7Q$)-eT-4!>E#Z$^e;a%4lv2)d0acyxdU3D6(`@LvK*?$Ac2;L!n^ zBtVk{kfZ{jSpw`~3LYI`uLRgD0aRtZ4zXWC9ApX}9il}-v`7e((S_tLZDk4`9iUAD zv`GLT1K^khIL;J2I=~4Da6$q|PZmV9OMp{M!J`A5kpO2H@H2}6aaKZfFa?heab7~4 zM~3+t02d@cCsXj~0GB1eWeH$40Io=Yt4zV816-2;*Cc?=0Fcv4Rj%OC0W5qDAS}o+ zKLbL}H4Wej9vvcx10YBO^fLhD{L@IT;L!nMB|xkM=x+eTbA2hCf0GOf?^Q2PVtjQn`W$f~2H#C0#5&M%>U#e>p}*_>pYw+WTay4^&S5M`SBrK_8QI zIij)ExF5dix4D3pO{|yNwdBWTY z3!NuMc48Ihi`kt}jI+2%nZW|ZwoX9gYmax575-$NX8D;|C|R_9AWb9%E!p%8_0N`c zw^AiXzWtS40cxYgSWf-KY(@v8-=2b3YUp55!)S6K=&@m^SY826+2%N_xq?u`VMfOb zpVf3QoyVopP6aw{aKrxZfN1o2*GlqRL<=eX#=EaI*W_h z&Pm#&^0F1Kl`|@`U^d4io>1yoTUhEWUGA)MZx_u4G=Xdv#|!9C+NiIgRoaqU=}JPI zxR@}Dg^IIBGM&ioAoazrIKdzLUoJ zplsYmnt&a+h&|2h+Fcvz8`yzs6Yix?6QKC=_jH`!5l$+wm#C^{Ivc`MEG@=0vmN{^Fc+Aa4{?CkQjmTlNW zVF|@POb2TBKS&>v{t_~Ua$VJJr{0BV*A8x{gJhWw_{9$TR9B|QQ`5!nwwmIV&Qb(T z=V>P%p?~&HA=>Yx{k)lQ?x=ROYo9jB9(AcVN<{1~+SWCn|J_BQybbqHV^7doU6U(H zpQO{g72^FTX*5}+efK1!k{lD8_R<_|1mD_AQx~>#;y)RP6cQ*m#w9&@+ZyNco}7P` ztGv1=8|W-`xOxF+RjjNiT!Db6v#J7d&+0reV;>EV>S+*By~b6I<=b7N95>W#>`%+JClV4Q$>Ssdg2a8O4>e$S^%KnkyY* z1AWMase41Ju{XooyeH=Oa|9OW)?k@37di%1ZyRR6s}xB&T8a<@G5dP zBL|Gvkn=NgKuJ_Z>1X89;36Q`-`fq$vPGQy9~!>i52XVP7@!S6ZlI9^-XP=x_1q}n z-3~JpWaNN16m`Ky4tOJx3o&xQ8;hLX$N_IWa-l{JXcLhOGjd=+@)TsljVxG@id=+| z12O5yMH)E}lZjlEo*NBfvXP56av&y0JpU|RxL(c#d?U%mGcpN+k<@2Fx}IjGLzYSi zvm)mK-l9y(SB5tdQviz1?x%4Nfx3fB^#MtPf8xLP(7I} zlVN%?^+uTv*VB@9EJ9C8zOhI>DVfHi^kj}qM(fF3Bq@YDPvjn;2?O(Gc9yE(kq%rt zSLTWJ2k7?1MQU$Xr9kcDsuZ9FSY9BqpMzheij~hnOQ>SYb2KK-p^^#CqGGqBci;e% z;y@dgqtoFOe|e6k64wjQ)AfwBXb1{FK#5E9e}TGbY^h4-PAp%WHTQ-aW+DuXW04tE zu9dDbm@faGxUhKpMd~509naIj+TBNJC^fWxoTu#X0osX|=`dn($?>&NrF2It9Yrd| z=vJDHfR3Y;&W2laxRu87P)2eP*US--M`<9fRAn4qOgl;uz8Ci&r5ga(|5d1~bz;`5 zG~cka!KPkhXrH_)T_^qIC|F!-qyD5$kk{!53@hbz8er~Qm8d=RCpyjKtr-|n#A-E0I*k7en3M}r~^Fy z0W4pGcrofCL@);WPBX>jBAr?ahy9Bq0aI z%uisT4vHT?Mz%%R|BiFHUlnST&r)k&(BFMRHv-i1DNP7$k$8`&3LeO618E~ltC;*L z-AUTSxlid!^q4BPea{Aoqvz-ta$LJ|j@A*&aoMVYC?~}F&*)gvE}Fiiq2lCc)W=8< zhGX1@A}#12^c*D};$P=!8Fnbn&uK9IO>hn1e?YWe_GA~;oz#K!2c4L@Q>tgeLm{4M zk4Z#aguy!_vM$od@UvJBa}0yuGXq#VXH68^nBkHdLAPOmh-BlM{3X%}yOOXKNP)$^JsNYG2v-evGtaTY+Ysp3w~&_5=M#S2Rt+&Vjr0=#MlG-mnJ$?S2@-h&Sq=%+wgP~8kHLe)zF;=cIId38 zz6xg8->G78DD#jQQ4!372TsPxW2tnUiVLOY#fHJF=xz>UzFnH__Aut>?WE_dTpS2v zS@f()T(YttjfAsYLOQgYBG{{>-+7FsCIi|W!9%xx3ZEnFLp$;xuEFlXjTA)Q_(`gL{SVI9~e_z9^*WXJ(^nBvoQXT?&RBFC0TyFkTRqNr{Q3 z-bOwabMmW$@K}frR7kQeSwX2LLxarfC0wZn&u&U!Q4#4Tl5unS^6U6zuW(d3N~O#s zu#w=>L2wLFSDn%SPGI)y#tb?$4OH1)RQbJ7Wy>K97M~7fn-L^(CbBrZwj{Ff(b+&O z-GwPGXG!tg+6w1*c*64jgMOvqH)`QSo=#-bNsf*!BiD;9uNSsl44s>^P1ze)BrOjvxvw_6Ip0T)12}etd}Xy zY6R=6bkV9b;Fcx>bB(w=8KPb*{+P@XU{OE9E93vP=N#VpeB}S)I|-X1!1}jAWO^ z`zb6XsL?y9{k;a&XrNo0%0g3`OgL7nDq00uF47O3h`HR|Y$91RjB5~OE9ca@tDU7- zj%AKg=N{3P%ErSb(g}_n#awVzkd6|2MzM)xk3rL3gQmSYO_u#~4jWC%L8DRgXco^~ zOyqfEWS@*?F)%8>jAmo_vEHQ?5uL_Vu_TSzVAb@o9x?hoVvM!b80+pdjJ0Ykix4?u zzBuop)V222f9Dka_!euaO1B{~P7{}Jgz!Kg`A|VH1s_02< zx7UvT-@;H~B4!HXIFYoa@M!U$k$fOd7?DoWHcesw&+wE)XVRysZwJD0Gke*vAwk-x zX+T19wXwIbyC@|-BDDY>JQ3%nvv{idh(F0Fl|>slgS8Uax*KOf!OFN)S6YUph@Xb? zdO0Y4m`5|2iF9hbni}F*#a{js=c!eVlp7oha~053u|+#acJw7MkaVUo8lXb z(++ONwlZD-FhXox&gO+D`jE7oq9WYk>H;VBDyPF;UY0DrTh4BT2^m$yZW5_Q&;Sn> zv7Odb*^N!^PSeGhVpf6~e4-fEJzHET)|GNUCksVxsFS7BY@NV~G{*}QdW z;_&w4^!8KPs~;yOX4oK+SjPGVyL^7#k;{je#i!R;FjHJUhF^Af8T3f0*j2^`(NZ5h zh$ucTW8uD)5}VUUsqtc~^0|xaS#Lg zmHTlJa9CRhMOh7OSBrSO2DYnJ{HcZ|g}3>TxpVZ3434VW`Ln0Yta46vt%NaCn7F-$ zMT?ZxY%&b)duv$8z#~2+Wq#F)Uc09wV%KVx*B|OD1{E`_%F9mFp0~fizWp8ZF)n-ft;K%FxE&JM=XQv4+~A40Z!I$;R^KD@dMb za{e7`2i%3uJ6JKW&AyW*1k`d8=e@%x?|z)|&c&`f;dh+XKDd)zqqYvof16^DQO^5_ z%S%XzFh779MQ|mZ&T;zo8e z#h%fBOo-UCk=+DGzjGrzupsg2JuDio_b>Orw_AS?n-qx)5<_ub;k{*n!wT<>DV)Z; zdxH<57PGGWhWMEc4T4Zh_jOV~9NcoV|BFfh5)`>0QCJ7xYsV%wfrc7{e7lKF435+R zg`@k> zR+d0h&A6ixp?$cO?V>c@=pZr|S7JbvlG%&QOi5iXQ?kXe``IuYf?m3xB~eSREY344 zd16Ro!t zy^aqH#4^EV`Z>%{e)<)LDz{6t3KkXn8$(h6CZ#IHX;z%xLHx$)rb`kF&{6{=q0&1Y zHND1JsrPg)#b2qB(8$(`-H)(kpqVtXu^2&SBO57pJ;D;@T@I7TJk6}yACaZ4W(AK# z?XR@yi689BG4bEW;ndvyICBMJC}~o_y3Tk(>v37Vl%6n)_l}V$ZOs#GkR`HR_IApw z;E_lxaVVju&YClnv*Lwku`)Zf&z@yP#P_^jk>;;l5Hk+IN$ULHSa(@OJ;yGRE5h%2 z*xxH+*z?$YUlr@0XOaE)P!gess4@_tx@N{%a+rXW`)Th#&xSF$Yu6630|+5Jdzc|A ztbK5pMadiRm2cvJ*B{sCJSR5|pnew5xy4?av+M=-9)&lPa)dnxZE)@g8zDv>!9q=V ziJfJk7UOVO!{KleA(7%-E7Z~QS6DqZj(VE6vYVlNX0#$+k|;K`vO>I2xkUEdzAI(sTOihoO}bUzIqh)8C%#l*@S6!V{xWiu$S~san`h?nEBv* zy5;(5_s6u`xxE zeNe4*kzN)i8sEUyzCb+x26k)?@$MUJ3N7%0C%*}V4t=2c1-Lc>QWfWKjMVuXBQ3B1 z*d>Q5e`u*i!6S!?ib`>?oyBU=$C%BB)M!cXvP~-XnkYOiH;`Skp1sbCb2Gw2T^IgQ z*6SL6ou!ZYuLByG|2pxX_u256c$PG=q`c_%={54$nxv#%cQODkYtmoY%&>Sy{3pTw zC?uoQQM(*FEGNzli(N%~#s0st)Cim`T;CAa;pM2-S(JM5<6mKPw`qlcV`~YRd-@c+ z&v(0pR2V8_$Kw#a-+jOa1g5hdHKL!VOa1Ze2bioz@%{%aA6wCw53wU{7KINDXee)8UCee?lvm-96GD4X zN0CP|lopG~xfh{osZvGj$5>}ajNYXC9a%sOacJ!|HLa2*1q80on}27I`W@4|I&L{* zQI1=T!_ZAV>aeN8mqCRZdCF$es}oeZmr~XY~quhXp69-Cg|F4V&{l)#ERCF9A^D$4{|v<)@wS| zN{T{!#fYucuC1gqoB{J(Z#;u~z-V zFEKBWSHWDp6UZ}RryjBMNj^ppJX!n_%2UO;pS>z?B-2rLb7se56jiV%6OiSWrL;sh`>zd%e ze4Xe>;#0%xtnvm|X{pQY#wJLziv(7cmpI+^Rx#`~7CR!BlDL`W~ zS!}bCELq+il9wOa)yYo7#QtPHy~_vL48niqgTU{=M|EjKHd}iu&b+=K%jJPiB0fpt zk@_ch!fzzsDjrJa;o`qZxZ3yXNFLfZc9;zFs#7sH1;S_eF^D1SMJrNyEN!%kgYeL3 zlU1B}1F@w>qfQ;grFF%W#fuwXW#Q8sy+YS)?d!HRcZrnOTbFKIqg>>BAdC7B-D_3w zNM{BW`*lH{i0HUZ2R4T==%cX2ii}%;h$!+GPKtaxM=FYo~F!xGLx>bGwR& z#U?H4D(?q6yXV621=x)JbvF>?)*}8qm*>W{Qr*ELEwtw}oD`^m5)>!#x)K*@^Y{$v zXCQ2x$5T`OKU!sAW&&{2nu4An@#8#xGr|(N^LgU@NL%kU5Nhk=sfMB%oQGJz&33wL zN~+D!U>kTYi3hBC#_e3$fX)^0xeCDr12|sXynqi9pU>w*ph^9ZhB8Z8fYp*HYd%5_ zufbyKLaftNAr|s@9GtZ-Th~hNBM|4sl^Abj^e%uz^l7 zzJSZ)vj>)7aXQ6IOL$hI>pHBZeP^o_eFAH#h+c{XQ7h_~@(5Fj3#Z(*!nG9kS1*da zu}`$1@;W+eded3cht3*F=iFbBSSvOb0OvZfPrmBJ`*`)+jJDiXYg=clvtbwFb1P4< zZIfl@T3ON{Zn%{%Oxb=N@~vhq_}qbgBc2B( zY&Nt}KL_Mo2bI8n?Ke9xnf?kCCxUH65G5GN#buSjw7M1(mOJ0Yk!VzZNvpa{L6 z1Rsw(c?iC1>~QLu+HVCP0j_4PfDVrrrSg?39$Ud@pw&g0n}>iGdU^R-Xw9t zvyw-m{lS%J*dflXoEuKnqpjhSNVX$@gxPY%s97YWyJDloV+9yE*PK&lCTy=Hsv)M%VDPfi6lG+Eerm zz42YTyH?y$!{5MNxACj_VYmd}ujYkhyEbPH?@zJaEvn^H2(FavyMs3opM#X#rGTB& z@4_c^K|=X?45= zxBj%|O+23?MDy+M`H!IQt9m$*4&m9t3Z&46xMMFya$Y>Mm)}h;h=hHx5?8dl z_wgEnE$a{e!#6Y4{H0{g4cZIOVg%MmGgtfp4D(;$41_ zKWTyh1-=M%k|@T!2;y2q#fyA0tX0d4d>UDg;Kfnh{86R>ScGYPmA8`}IhS`0VLm_R`GSBl*5&h9Zzu@JBHJG<+TfgMH zC`yKZ%@Y}GG&gArE@G#Nx*SpdEx&>)=OvCW0-80y@Aw*g(5r3!o_7-UAlS*p&&$+N zV(%61hp>xwg};k-ZQ^(T;@f;0%ys}c#MXat*wKIEgV|%^-hcBkY`^)q_S(OBC4rER zy2=TK2c7m`{tL)X`-vx7ARo7?>L75tPE~(^n5;IbPk^IgKI$cGY^-KA6H=0ER&O@r zPZFp^fpiG7IvT?8XR~@cl;>EB`V3^^oJGAK7X`|F)onm=%~!nvlAmE!cap2x->j+= zH{{G>oS%A|ncy=szBXo}XdbABh+izKDvtZ9c9TVxZx9^=)zBUN)KGL5)=$N4S#4=Q z6@O}Fkyz}n-T`HB%3pm;p4&em-!fvP+O`ujlj4={vl0@b6Cw=qHL5JY(k zg4EX#;Ef7aR|Re6B#7{|iH?L1 zd5O%h%r>S8CCoFBZsEwd|Nxmw-fA*iQE;qHQz(ka&E78iClwYYQNvMEtlw zEi)0^(I6=Tml#8|%?s5UZV$31D>2^dcW%<1%F+fDfQ6P&s~JZxuf)vtkY@tL6St~E zd88G8TIao6)w>`zw-l-l$ijg_bqd&ZrBKad=jkGmvrL_VM1k-uQ;Q&i4smsv`a3XX zgG0T;>O!C43JJoWC(^DgR}YvF&VJIRZs2sCRjeHj8E(*;%OF;CyH)rnt3Oa|7fmD7 zXT`EgH5eZSt*KPc6R@Pft={C1zl@PX1A7EbJM30pVC#=t(-hu{3+V-FyESg=q*YGD zv&+jCJFCj)7=OdSx@m%5I;X-}G#{5OvEM&q_0Q1D=C1XYoVEI==p{Ef%baePyTh7h zK;$F%>yUGO-kLVFtM?*jr*%`3%$aXDZ0%)nd5s#Lbj7-9vJTW09+-;jlUJ?T_{?#F z|0H~PZ;M!Mkf3ZA8Ee%nNKVaKbqs5#LE^w#^$-^9@>+E=7VOit>Stj2mOIoxF^er$ zEVxtkKrMZJr#gpB~ooUqUkR6ztH)O>!hU2)4sl2eNJBfzHg@* zW;v(^mdVZLL2-108p0OY3dHFR>bT#oj$UM|v?*ytHC1v~Q@C875Gb`azA9$66IaK| zL|ZfdEWw64bpSNKr%ug=u4%7R$A)dTDHG(^YWfxw9}bluYR+wItK9)&&_=Zoe#pj+ z>RT+pwoOdC2P?l_+j0+-B&$~~B5bpo5!hfeSFg3$hUzE_SAlhD+qD&&)d}*}_|x}7 zV4Ac+zgJ^m7R01_bq5yGNA(!S84AdiL=bV z&8AGQtZ`P=7OrqQ3yTp4a+SEvwwkroUVvlT+6Hw14Z7T?uXgmc%cIVq8x zTN3uvW!|p`>ea42I^CeiiXx}MZ`;srMuL0MJJm>gJ3xjSAoAAm(5{wZ?oM^AcP2x+ zCt6K%6cst$?!pq6yLypm-KnPb53t3ptu9T)REJp4+TxrfW@3%2q*%o4 of*tzyQPrePdsKagunt?37W|mHkikzXZ&p(Y{=UN83pVBd0J$9HdjJ3c diff --git a/tangle-subxt/src/tangle_testnet_runtime.rs b/tangle-subxt/src/tangle_testnet_runtime.rs index a70fc96e..90210a54 100644 --- a/tangle-subxt/src/tangle_testnet_runtime.rs +++ b/tangle-subxt/src/tangle_testnet_runtime.rs @@ -3373,9 +3373,9 @@ pub mod api { .hash(); runtime_metadata_hash == [ - 80u8, 141u8, 11u8, 219u8, 6u8, 178u8, 239u8, 224u8, 24u8, 145u8, 113u8, 85u8, 28u8, - 230u8, 209u8, 8u8, 141u8, 24u8, 185u8, 56u8, 183u8, 59u8, 40u8, 156u8, 46u8, 220u8, - 13u8, 52u8, 211u8, 39u8, 99u8, 68u8, + 5u8, 154u8, 107u8, 119u8, 72u8, 89u8, 231u8, 249u8, 39u8, 36u8, 249u8, 86u8, 39u8, + 140u8, 38u8, 112u8, 243u8, 211u8, 184u8, 137u8, 34u8, 181u8, 172u8, 240u8, 164u8, + 7u8, 196u8, 85u8, 203u8, 55u8, 246u8, 216u8, ] } pub mod system { @@ -4493,9 +4493,9 @@ pub mod api { "Events", (), [ - 120u8, 166u8, 58u8, 107u8, 246u8, 11u8, 96u8, 144u8, 72u8, 132u8, - 146u8, 200u8, 157u8, 71u8, 162u8, 168u8, 117u8, 62u8, 31u8, 62u8, 7u8, - 68u8, 102u8, 178u8, 57u8, 35u8, 146u8, 167u8, 3u8, 160u8, 81u8, 176u8, + 24u8, 134u8, 233u8, 26u8, 20u8, 180u8, 116u8, 72u8, 248u8, 72u8, 166u8, + 122u8, 46u8, 77u8, 208u8, 24u8, 23u8, 26u8, 84u8, 76u8, 170u8, 24u8, + 138u8, 174u8, 253u8, 229u8, 251u8, 6u8, 118u8, 104u8, 193u8, 7u8, ], ) } @@ -5146,9 +5146,9 @@ pub mod api { "sudo", types::Sudo { call: ::subxt_core::alloc::boxed::Box::new(call) }, [ - 85u8, 102u8, 44u8, 84u8, 251u8, 205u8, 199u8, 246u8, 22u8, 90u8, 100u8, - 37u8, 128u8, 197u8, 219u8, 168u8, 239u8, 85u8, 163u8, 2u8, 85u8, 168u8, - 203u8, 145u8, 51u8, 15u8, 180u8, 185u8, 158u8, 248u8, 25u8, 212u8, + 208u8, 49u8, 34u8, 70u8, 241u8, 219u8, 96u8, 19u8, 119u8, 128u8, 125u8, + 60u8, 40u8, 230u8, 90u8, 40u8, 219u8, 138u8, 131u8, 170u8, 98u8, 36u8, + 83u8, 173u8, 7u8, 246u8, 145u8, 14u8, 170u8, 0u8, 224u8, 245u8, ], ) } @@ -5170,10 +5170,9 @@ pub mod api { weight, }, [ - 89u8, 47u8, 52u8, 100u8, 155u8, 129u8, 224u8, 158u8, 9u8, 94u8, 42u8, - 43u8, 58u8, 89u8, 97u8, 181u8, 165u8, 155u8, 116u8, 104u8, 180u8, - 197u8, 119u8, 121u8, 120u8, 240u8, 219u8, 248u8, 21u8, 180u8, 83u8, - 9u8, + 144u8, 58u8, 10u8, 185u8, 102u8, 31u8, 8u8, 164u8, 133u8, 102u8, 14u8, + 66u8, 222u8, 250u8, 80u8, 70u8, 76u8, 174u8, 36u8, 65u8, 117u8, 163u8, + 109u8, 182u8, 5u8, 62u8, 80u8, 155u8, 252u8, 169u8, 154u8, 149u8, ], ) } @@ -5209,10 +5208,10 @@ pub mod api { "sudo_as", types::SudoAs { who, call: ::subxt_core::alloc::boxed::Box::new(call) }, [ - 219u8, 18u8, 110u8, 149u8, 233u8, 148u8, 26u8, 179u8, 15u8, 157u8, - 189u8, 43u8, 251u8, 179u8, 179u8, 7u8, 12u8, 159u8, 252u8, 36u8, 113u8, - 199u8, 25u8, 142u8, 69u8, 208u8, 234u8, 253u8, 198u8, 136u8, 150u8, - 215u8, + 175u8, 220u8, 140u8, 145u8, 165u8, 60u8, 117u8, 2u8, 161u8, 250u8, + 71u8, 177u8, 33u8, 30u8, 186u8, 186u8, 172u8, 166u8, 212u8, 97u8, + 134u8, 234u8, 0u8, 219u8, 138u8, 61u8, 123u8, 223u8, 184u8, 41u8, + 253u8, 29u8, ], ) } @@ -15463,10 +15462,9 @@ pub mod api { length_bound, }, [ - 80u8, 130u8, 130u8, 0u8, 201u8, 192u8, 141u8, 199u8, 219u8, 157u8, - 31u8, 126u8, 20u8, 8u8, 102u8, 21u8, 157u8, 93u8, 154u8, 250u8, 54u8, - 209u8, 125u8, 63u8, 35u8, 233u8, 180u8, 165u8, 69u8, 79u8, 180u8, - 219u8, + 151u8, 243u8, 56u8, 5u8, 25u8, 51u8, 158u8, 177u8, 194u8, 23u8, 61u8, + 148u8, 69u8, 59u8, 0u8, 133u8, 211u8, 254u8, 22u8, 130u8, 22u8, 37u8, + 44u8, 237u8, 223u8, 249u8, 235u8, 145u8, 94u8, 18u8, 124u8, 220u8, ], ) } @@ -15499,9 +15497,10 @@ pub mod api { length_bound, }, [ - 176u8, 138u8, 95u8, 94u8, 49u8, 75u8, 75u8, 70u8, 96u8, 28u8, 122u8, - 214u8, 6u8, 134u8, 203u8, 77u8, 174u8, 41u8, 78u8, 170u8, 61u8, 92u8, - 18u8, 44u8, 138u8, 116u8, 128u8, 229u8, 51u8, 178u8, 114u8, 106u8, + 190u8, 252u8, 150u8, 81u8, 94u8, 170u8, 96u8, 254u8, 98u8, 120u8, 39u8, + 21u8, 240u8, 196u8, 127u8, 150u8, 43u8, 177u8, 113u8, 128u8, 40u8, + 189u8, 78u8, 243u8, 220u8, 171u8, 203u8, 192u8, 221u8, 44u8, 38u8, + 107u8, ], ) } @@ -15883,10 +15882,9 @@ pub mod api { "ProposalOf", (), [ - 122u8, 85u8, 141u8, 87u8, 254u8, 93u8, 115u8, 216u8, 136u8, 51u8, - 131u8, 220u8, 158u8, 86u8, 163u8, 216u8, 68u8, 200u8, 220u8, 45u8, - 135u8, 38u8, 69u8, 15u8, 183u8, 247u8, 87u8, 170u8, 95u8, 2u8, 216u8, - 145u8, + 49u8, 191u8, 165u8, 123u8, 184u8, 2u8, 47u8, 239u8, 144u8, 167u8, + 191u8, 21u8, 64u8, 62u8, 6u8, 47u8, 179u8, 238u8, 103u8, 2u8, 240u8, + 97u8, 226u8, 51u8, 9u8, 80u8, 222u8, 5u8, 166u8, 243u8, 11u8, 165u8, ], ) } @@ -15906,10 +15904,9 @@ pub mod api { "ProposalOf", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 122u8, 85u8, 141u8, 87u8, 254u8, 93u8, 115u8, 216u8, 136u8, 51u8, - 131u8, 220u8, 158u8, 86u8, 163u8, 216u8, 68u8, 200u8, 220u8, 45u8, - 135u8, 38u8, 69u8, 15u8, 183u8, 247u8, 87u8, 170u8, 95u8, 2u8, 216u8, - 145u8, + 49u8, 191u8, 165u8, 123u8, 184u8, 2u8, 47u8, 239u8, 144u8, 167u8, + 191u8, 21u8, 64u8, 62u8, 6u8, 47u8, 179u8, 238u8, 103u8, 2u8, 240u8, + 97u8, 226u8, 51u8, 9u8, 80u8, 222u8, 5u8, 166u8, 243u8, 11u8, 165u8, ], ) } @@ -31303,9 +31300,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 214u8, 69u8, 165u8, 202u8, 122u8, 71u8, 224u8, 70u8, 147u8, 64u8, 20u8, - 11u8, 236u8, 192u8, 233u8, 19u8, 75u8, 207u8, 133u8, 12u8, 89u8, 203u8, - 125u8, 144u8, 213u8, 41u8, 75u8, 151u8, 15u8, 217u8, 1u8, 57u8, + 199u8, 56u8, 239u8, 224u8, 183u8, 223u8, 102u8, 228u8, 68u8, 96u8, + 85u8, 216u8, 183u8, 55u8, 0u8, 29u8, 253u8, 63u8, 126u8, 182u8, 190u8, + 143u8, 248u8, 194u8, 184u8, 188u8, 196u8, 183u8, 213u8, 98u8, 203u8, + 14u8, ], ) } @@ -31347,9 +31345,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 249u8, 19u8, 218u8, 154u8, 87u8, 150u8, 3u8, 147u8, 1u8, 221u8, 122u8, - 26u8, 72u8, 122u8, 77u8, 151u8, 144u8, 85u8, 134u8, 65u8, 33u8, 182u8, - 201u8, 223u8, 134u8, 145u8, 60u8, 28u8, 19u8, 134u8, 1u8, 231u8, + 101u8, 248u8, 172u8, 212u8, 27u8, 151u8, 85u8, 78u8, 19u8, 155u8, + 249u8, 230u8, 229u8, 142u8, 24u8, 136u8, 135u8, 162u8, 163u8, 245u8, + 57u8, 242u8, 145u8, 105u8, 25u8, 106u8, 216u8, 224u8, 16u8, 154u8, + 37u8, 7u8, ], ) } @@ -31387,9 +31386,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 179u8, 11u8, 205u8, 94u8, 110u8, 169u8, 53u8, 165u8, 57u8, 107u8, - 162u8, 240u8, 65u8, 52u8, 73u8, 96u8, 15u8, 26u8, 117u8, 20u8, 192u8, - 79u8, 98u8, 73u8, 81u8, 35u8, 45u8, 15u8, 140u8, 70u8, 180u8, 251u8, + 42u8, 118u8, 58u8, 127u8, 142u8, 66u8, 3u8, 95u8, 28u8, 90u8, 44u8, + 129u8, 152u8, 178u8, 0u8, 225u8, 186u8, 106u8, 175u8, 47u8, 66u8, + 172u8, 216u8, 35u8, 5u8, 53u8, 160u8, 14u8, 27u8, 42u8, 73u8, 169u8, ], ) } @@ -31413,10 +31412,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 62u8, 93u8, 159u8, 43u8, 150u8, 67u8, 181u8, 131u8, 170u8, 114u8, - 170u8, 226u8, 60u8, 13u8, 192u8, 68u8, 119u8, 21u8, 162u8, 73u8, 239u8, - 168u8, 161u8, 96u8, 250u8, 66u8, 183u8, 136u8, 197u8, 180u8, 244u8, - 202u8, + 144u8, 7u8, 34u8, 230u8, 179u8, 226u8, 63u8, 197u8, 27u8, 183u8, 253u8, + 252u8, 140u8, 85u8, 204u8, 78u8, 26u8, 99u8, 11u8, 180u8, 206u8, 178u8, + 161u8, 42u8, 28u8, 192u8, 138u8, 42u8, 216u8, 30u8, 178u8, 244u8, ], ) } @@ -36061,9 +36059,9 @@ pub mod api { "batch", types::Batch { calls }, [ - 13u8, 227u8, 65u8, 138u8, 249u8, 203u8, 144u8, 123u8, 159u8, 216u8, - 77u8, 124u8, 68u8, 161u8, 42u8, 13u8, 223u8, 134u8, 79u8, 91u8, 216u8, - 30u8, 126u8, 206u8, 135u8, 219u8, 45u8, 91u8, 96u8, 247u8, 82u8, 250u8, + 187u8, 197u8, 139u8, 185u8, 162u8, 29u8, 179u8, 225u8, 225u8, 87u8, + 87u8, 97u8, 3u8, 241u8, 151u8, 104u8, 91u8, 214u8, 0u8, 190u8, 251u8, + 169u8, 127u8, 160u8, 7u8, 243u8, 206u8, 61u8, 106u8, 174u8, 62u8, 80u8, ], ) } @@ -36093,9 +36091,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 60u8, 23u8, 76u8, 83u8, 52u8, 90u8, 188u8, 236u8, 116u8, 28u8, 197u8, - 201u8, 14u8, 45u8, 137u8, 212u8, 140u8, 194u8, 46u8, 45u8, 13u8, 228u8, - 226u8, 35u8, 176u8, 151u8, 222u8, 152u8, 92u8, 4u8, 196u8, 225u8, + 200u8, 142u8, 140u8, 129u8, 212u8, 157u8, 85u8, 182u8, 92u8, 141u8, + 55u8, 157u8, 229u8, 7u8, 109u8, 74u8, 53u8, 68u8, 5u8, 242u8, 149u8, + 73u8, 93u8, 111u8, 29u8, 89u8, 197u8, 13u8, 244u8, 68u8, 40u8, 237u8, ], ) } @@ -36121,10 +36119,10 @@ pub mod api { "batch_all", types::BatchAll { calls }, [ - 133u8, 33u8, 247u8, 105u8, 15u8, 197u8, 167u8, 223u8, 193u8, 155u8, - 199u8, 145u8, 191u8, 248u8, 43u8, 208u8, 81u8, 222u8, 27u8, 199u8, - 168u8, 21u8, 79u8, 178u8, 190u8, 42u8, 173u8, 182u8, 212u8, 92u8, - 135u8, 62u8, + 188u8, 180u8, 80u8, 179u8, 215u8, 76u8, 79u8, 192u8, 191u8, 209u8, + 131u8, 116u8, 125u8, 253u8, 138u8, 200u8, 196u8, 84u8, 44u8, 164u8, + 72u8, 208u8, 228u8, 58u8, 224u8, 245u8, 125u8, 94u8, 12u8, 229u8, + 240u8, 10u8, ], ) } @@ -36147,9 +36145,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 59u8, 214u8, 230u8, 214u8, 170u8, 168u8, 146u8, 241u8, 44u8, 150u8, - 234u8, 35u8, 212u8, 45u8, 7u8, 143u8, 150u8, 202u8, 241u8, 38u8, 87u8, - 217u8, 173u8, 49u8, 237u8, 252u8, 14u8, 96u8, 106u8, 59u8, 38u8, 251u8, + 125u8, 114u8, 90u8, 64u8, 203u8, 224u8, 129u8, 14u8, 186u8, 249u8, + 62u8, 217u8, 172u8, 46u8, 75u8, 204u8, 88u8, 117u8, 65u8, 205u8, 165u8, + 48u8, 69u8, 33u8, 133u8, 184u8, 1u8, 111u8, 4u8, 29u8, 159u8, 109u8, ], ) } @@ -36175,10 +36173,10 @@ pub mod api { "force_batch", types::ForceBatch { calls }, [ - 222u8, 162u8, 149u8, 127u8, 45u8, 118u8, 65u8, 250u8, 133u8, 153u8, - 207u8, 79u8, 244u8, 112u8, 199u8, 211u8, 12u8, 165u8, 125u8, 181u8, - 120u8, 85u8, 55u8, 144u8, 139u8, 198u8, 12u8, 120u8, 144u8, 200u8, - 65u8, 36u8, + 82u8, 217u8, 53u8, 168u8, 130u8, 159u8, 59u8, 212u8, 65u8, 114u8, + 250u8, 62u8, 219u8, 28u8, 88u8, 213u8, 183u8, 124u8, 33u8, 232u8, + 115u8, 234u8, 89u8, 41u8, 46u8, 13u8, 179u8, 50u8, 174u8, 141u8, 139u8, + 35u8, ], ) } @@ -36201,10 +36199,10 @@ pub mod api { weight, }, [ - 118u8, 214u8, 245u8, 97u8, 253u8, 124u8, 182u8, 221u8, 157u8, 186u8, - 66u8, 39u8, 26u8, 121u8, 237u8, 101u8, 17u8, 226u8, 236u8, 161u8, - 227u8, 158u8, 191u8, 31u8, 38u8, 33u8, 184u8, 199u8, 24u8, 225u8, - 112u8, 24u8, + 37u8, 181u8, 151u8, 119u8, 179u8, 146u8, 97u8, 56u8, 238u8, 16u8, + 125u8, 45u8, 0u8, 130u8, 176u8, 80u8, 113u8, 69u8, 90u8, 198u8, 55u8, + 59u8, 23u8, 247u8, 107u8, 135u8, 26u8, 118u8, 97u8, 210u8, 169u8, + 255u8, ], ) } @@ -36645,9 +36643,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 88u8, 136u8, 209u8, 57u8, 169u8, 7u8, 205u8, 168u8, 240u8, 9u8, 17u8, - 185u8, 233u8, 239u8, 138u8, 51u8, 193u8, 96u8, 4u8, 132u8, 127u8, - 178u8, 181u8, 180u8, 173u8, 46u8, 6u8, 19u8, 24u8, 126u8, 107u8, 134u8, + 210u8, 155u8, 101u8, 173u8, 10u8, 201u8, 67u8, 235u8, 171u8, 217u8, + 56u8, 204u8, 166u8, 107u8, 217u8, 81u8, 95u8, 73u8, 118u8, 208u8, 22u8, + 210u8, 95u8, 117u8, 101u8, 246u8, 218u8, 26u8, 93u8, 193u8, 10u8, 24u8, ], ) } @@ -36709,10 +36707,9 @@ pub mod api { max_weight, }, [ - 107u8, 148u8, 123u8, 24u8, 194u8, 73u8, 145u8, 208u8, 45u8, 97u8, - 124u8, 103u8, 21u8, 0u8, 237u8, 179u8, 86u8, 166u8, 2u8, 66u8, 112u8, - 223u8, 166u8, 73u8, 103u8, 249u8, 126u8, 53u8, 86u8, 149u8, 43u8, - 252u8, + 70u8, 226u8, 2u8, 214u8, 151u8, 211u8, 61u8, 151u8, 233u8, 219u8, 64u8, + 54u8, 62u8, 202u8, 250u8, 254u8, 145u8, 193u8, 134u8, 35u8, 194u8, + 39u8, 184u8, 221u8, 96u8, 141u8, 202u8, 80u8, 39u8, 102u8, 242u8, 11u8, ], ) } @@ -39631,9 +39628,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 38u8, 176u8, 175u8, 97u8, 38u8, 215u8, 45u8, 159u8, 78u8, 85u8, 202u8, - 29u8, 189u8, 27u8, 153u8, 104u8, 106u8, 207u8, 245u8, 221u8, 94u8, - 29u8, 221u8, 9u8, 232u8, 243u8, 154u8, 61u8, 250u8, 33u8, 246u8, 205u8, + 58u8, 167u8, 95u8, 35u8, 187u8, 56u8, 40u8, 175u8, 114u8, 203u8, 0u8, + 180u8, 200u8, 254u8, 201u8, 53u8, 48u8, 41u8, 164u8, 180u8, 22u8, 69u8, + 157u8, 116u8, 151u8, 21u8, 238u8, 217u8, 47u8, 27u8, 151u8, 207u8, ], ) } @@ -39889,10 +39886,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 190u8, 59u8, 19u8, 149u8, 211u8, 63u8, 97u8, 202u8, 183u8, 33u8, 51u8, - 61u8, 156u8, 166u8, 25u8, 83u8, 124u8, 179u8, 243u8, 185u8, 125u8, - 122u8, 188u8, 238u8, 9u8, 142u8, 138u8, 72u8, 229u8, 235u8, 164u8, - 31u8, + 126u8, 176u8, 126u8, 188u8, 213u8, 58u8, 46u8, 193u8, 84u8, 247u8, + 17u8, 63u8, 205u8, 250u8, 73u8, 63u8, 139u8, 186u8, 187u8, 244u8, 20u8, + 171u8, 220u8, 48u8, 183u8, 90u8, 116u8, 38u8, 116u8, 248u8, 74u8, + 191u8, ], ) } @@ -40523,11 +40520,14 @@ pub mod api { pub struct Deposit { pub asset_id: deposit::AssetId, pub amount: deposit::Amount, + pub evm_address: deposit::EvmAddress, } pub mod deposit { use super::runtime_types; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; + pub type EvmAddress = ::core::option::Option<::subxt_core::utils::H160>; } impl ::subxt_core::blocks::StaticExtrinsic for Deposit { const PALLET: &'static str = "MultiAssetDelegation"; @@ -40553,7 +40553,8 @@ pub mod api { } pub mod schedule_withdraw { use super::runtime_types; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; } impl ::subxt_core::blocks::StaticExtrinsic for ScheduleWithdraw { @@ -40574,7 +40575,13 @@ pub mod api { #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Executes a scheduled withdraw request."] - pub struct ExecuteWithdraw; + pub struct ExecuteWithdraw { + pub evm_address: execute_withdraw::EvmAddress, + } + pub mod execute_withdraw { + use super::runtime_types; + pub type EvmAddress = ::core::option::Option<::subxt_core::utils::H160>; + } impl ::subxt_core::blocks::StaticExtrinsic for ExecuteWithdraw { const PALLET: &'static str = "MultiAssetDelegation"; const CALL: &'static str = "execute_withdraw"; @@ -40599,7 +40606,8 @@ pub mod api { } pub mod cancel_withdraw { use super::runtime_types; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; } impl ::subxt_core::blocks::StaticExtrinsic for CancelWithdraw { @@ -40629,7 +40637,8 @@ pub mod api { pub mod delegate { use super::runtime_types; pub type Operator = ::subxt_core::utils::AccountId32; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; pub type BlueprintSelection = runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > ; } @@ -40659,7 +40668,8 @@ pub mod api { pub mod schedule_delegator_unstake { use super::runtime_types; pub type Operator = ::subxt_core::utils::AccountId32; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; } impl ::subxt_core::blocks::StaticExtrinsic for ScheduleDelegatorUnstake { @@ -40707,7 +40717,8 @@ pub mod api { pub mod cancel_delegator_unstake { use super::runtime_types; pub type Operator = ::subxt_core::utils::AccountId32; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; } impl ::subxt_core::blocks::StaticExtrinsic for CancelDelegatorUnstake { @@ -40795,7 +40806,8 @@ pub mod api { pub mod manage_asset_in_vault { use super::runtime_types; pub type VaultId = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Action = runtime_types::pallet_multi_asset_delegation::types::rewards::AssetAction; } @@ -41019,16 +41031,17 @@ pub mod api { &self, asset_id: types::deposit::AssetId, amount: types::deposit::Amount, + evm_address: types::deposit::EvmAddress, ) -> ::subxt_core::tx::payload::StaticPayload { ::subxt_core::tx::payload::StaticPayload::new_static( "MultiAssetDelegation", "deposit", - types::Deposit { asset_id, amount }, + types::Deposit { asset_id, amount, evm_address }, [ - 25u8, 39u8, 77u8, 183u8, 182u8, 45u8, 116u8, 55u8, 125u8, 104u8, 78u8, - 42u8, 142u8, 86u8, 182u8, 200u8, 101u8, 149u8, 90u8, 22u8, 156u8, - 217u8, 246u8, 111u8, 114u8, 255u8, 241u8, 215u8, 111u8, 223u8, 141u8, - 76u8, + 58u8, 72u8, 176u8, 66u8, 51u8, 188u8, 190u8, 38u8, 13u8, 234u8, 239u8, + 113u8, 157u8, 64u8, 109u8, 91u8, 0u8, 242u8, 157u8, 176u8, 126u8, + 250u8, 133u8, 66u8, 172u8, 17u8, 254u8, 231u8, 124u8, 159u8, 248u8, + 101u8, ], ) } @@ -41043,25 +41056,25 @@ pub mod api { "schedule_withdraw", types::ScheduleWithdraw { asset_id, amount }, [ - 40u8, 210u8, 230u8, 206u8, 225u8, 11u8, 174u8, 19u8, 194u8, 166u8, - 107u8, 100u8, 26u8, 173u8, 183u8, 29u8, 19u8, 216u8, 240u8, 58u8, 39u8, - 135u8, 143u8, 252u8, 235u8, 221u8, 152u8, 255u8, 108u8, 134u8, 78u8, - 103u8, + 151u8, 83u8, 1u8, 25u8, 237u8, 166u8, 220u8, 253u8, 160u8, 43u8, 229u8, + 21u8, 247u8, 247u8, 110u8, 119u8, 99u8, 12u8, 213u8, 134u8, 181u8, + 30u8, 13u8, 11u8, 133u8, 131u8, 2u8, 79u8, 48u8, 65u8, 144u8, 77u8, ], ) } #[doc = "Executes a scheduled withdraw request."] pub fn execute_withdraw( &self, + evm_address: types::execute_withdraw::EvmAddress, ) -> ::subxt_core::tx::payload::StaticPayload { ::subxt_core::tx::payload::StaticPayload::new_static( "MultiAssetDelegation", "execute_withdraw", - types::ExecuteWithdraw {}, + types::ExecuteWithdraw { evm_address }, [ - 113u8, 223u8, 166u8, 138u8, 53u8, 85u8, 30u8, 76u8, 4u8, 251u8, 52u8, - 29u8, 41u8, 224u8, 40u8, 64u8, 67u8, 230u8, 19u8, 43u8, 114u8, 166u8, - 56u8, 18u8, 19u8, 208u8, 3u8, 93u8, 131u8, 140u8, 223u8, 28u8, + 192u8, 219u8, 87u8, 231u8, 26u8, 7u8, 60u8, 107u8, 41u8, 80u8, 25u8, + 90u8, 189u8, 215u8, 113u8, 78u8, 93u8, 147u8, 56u8, 175u8, 57u8, 75u8, + 117u8, 131u8, 227u8, 252u8, 16u8, 241u8, 170u8, 241u8, 77u8, 124u8, ], ) } @@ -41076,9 +41089,9 @@ pub mod api { "cancel_withdraw", types::CancelWithdraw { asset_id, amount }, [ - 153u8, 92u8, 147u8, 28u8, 101u8, 84u8, 56u8, 240u8, 202u8, 89u8, 138u8, - 195u8, 166u8, 73u8, 49u8, 48u8, 119u8, 135u8, 221u8, 36u8, 92u8, 223u8, - 46u8, 152u8, 252u8, 193u8, 43u8, 214u8, 175u8, 33u8, 128u8, 110u8, + 18u8, 80u8, 162u8, 132u8, 33u8, 12u8, 254u8, 88u8, 103u8, 101u8, 227u8, + 4u8, 12u8, 113u8, 76u8, 143u8, 80u8, 89u8, 50u8, 188u8, 233u8, 184u8, + 102u8, 60u8, 245u8, 21u8, 95u8, 250u8, 78u8, 193u8, 28u8, 242u8, ], ) } @@ -41095,10 +41108,10 @@ pub mod api { "delegate", types::Delegate { operator, asset_id, amount, blueprint_selection }, [ - 229u8, 174u8, 212u8, 104u8, 133u8, 233u8, 29u8, 42u8, 84u8, 225u8, - 15u8, 137u8, 245u8, 47u8, 206u8, 52u8, 134u8, 101u8, 122u8, 114u8, - 184u8, 61u8, 228u8, 27u8, 245u8, 185u8, 31u8, 161u8, 244u8, 130u8, - 183u8, 243u8, + 122u8, 21u8, 147u8, 191u8, 103u8, 51u8, 255u8, 119u8, 157u8, 35u8, + 16u8, 92u8, 138u8, 149u8, 215u8, 86u8, 170u8, 106u8, 101u8, 232u8, + 96u8, 14u8, 80u8, 242u8, 180u8, 96u8, 86u8, 78u8, 237u8, 155u8, 3u8, + 88u8, ], ) } @@ -41114,9 +41127,9 @@ pub mod api { "schedule_delegator_unstake", types::ScheduleDelegatorUnstake { operator, asset_id, amount }, [ - 59u8, 253u8, 25u8, 246u8, 47u8, 194u8, 135u8, 112u8, 106u8, 76u8, 33u8, - 166u8, 129u8, 10u8, 202u8, 94u8, 0u8, 22u8, 17u8, 52u8, 93u8, 95u8, - 136u8, 18u8, 216u8, 102u8, 20u8, 20u8, 183u8, 199u8, 55u8, 116u8, + 244u8, 2u8, 144u8, 12u8, 8u8, 144u8, 76u8, 125u8, 36u8, 206u8, 176u8, + 88u8, 49u8, 6u8, 202u8, 23u8, 225u8, 231u8, 241u8, 133u8, 69u8, 214u8, + 67u8, 79u8, 174u8, 140u8, 28u8, 167u8, 84u8, 227u8, 88u8, 130u8, ], ) } @@ -41147,10 +41160,10 @@ pub mod api { "cancel_delegator_unstake", types::CancelDelegatorUnstake { operator, asset_id, amount }, [ - 148u8, 108u8, 146u8, 167u8, 117u8, 105u8, 88u8, 221u8, 166u8, 87u8, - 52u8, 24u8, 132u8, 99u8, 15u8, 48u8, 217u8, 247u8, 225u8, 253u8, 40u8, - 225u8, 173u8, 59u8, 75u8, 189u8, 118u8, 122u8, 135u8, 60u8, 168u8, - 169u8, + 230u8, 243u8, 246u8, 127u8, 75u8, 179u8, 58u8, 225u8, 144u8, 194u8, + 15u8, 13u8, 172u8, 162u8, 88u8, 181u8, 223u8, 191u8, 89u8, 231u8, + 168u8, 91u8, 170u8, 199u8, 178u8, 151u8, 49u8, 58u8, 166u8, 208u8, + 159u8, 220u8, ], ) } @@ -41207,9 +41220,9 @@ pub mod api { "manage_asset_in_vault", types::ManageAssetInVault { vault_id, asset_id, action }, [ - 148u8, 94u8, 58u8, 190u8, 112u8, 51u8, 136u8, 40u8, 105u8, 143u8, 71u8, - 172u8, 40u8, 71u8, 175u8, 236u8, 203u8, 248u8, 29u8, 86u8, 112u8, 66u8, - 33u8, 197u8, 130u8, 45u8, 66u8, 182u8, 231u8, 151u8, 170u8, 241u8, + 164u8, 251u8, 229u8, 192u8, 83u8, 53u8, 179u8, 154u8, 228u8, 245u8, + 116u8, 154u8, 100u8, 198u8, 182u8, 69u8, 90u8, 178u8, 237u8, 99u8, 0u8, + 160u8, 243u8, 162u8, 69u8, 87u8, 26u8, 61u8, 82u8, 151u8, 100u8, 251u8, ], ) } @@ -41529,7 +41542,8 @@ pub mod api { use super::runtime_types; pub type Who = ::subxt_core::utils::AccountId32; pub type Amount = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; } impl ::subxt_core::events::StaticEvent for Deposited { const PALLET: &'static str = "MultiAssetDelegation"; @@ -41558,7 +41572,8 @@ pub mod api { use super::runtime_types; pub type Who = ::subxt_core::utils::AccountId32; pub type Amount = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; } impl ::subxt_core::events::StaticEvent for Scheduledwithdraw { const PALLET: &'static str = "MultiAssetDelegation"; @@ -41639,7 +41654,8 @@ pub mod api { pub type Who = ::subxt_core::utils::AccountId32; pub type Operator = ::subxt_core::utils::AccountId32; pub type Amount = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; } impl ::subxt_core::events::StaticEvent for Delegated { const PALLET: &'static str = "MultiAssetDelegation"; @@ -41670,7 +41686,8 @@ pub mod api { pub type Who = ::subxt_core::utils::AccountId32; pub type Operator = ::subxt_core::utils::AccountId32; pub type Amount = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; } impl ::subxt_core::events::StaticEvent for ScheduledDelegatorBondLess { const PALLET: &'static str = "MultiAssetDelegation"; @@ -41804,7 +41821,8 @@ pub mod api { use super::runtime_types; pub type Who = ::subxt_core::utils::AccountId32; pub type VaultId = ::core::primitive::u128; - pub type AssetId = ::core::primitive::u128; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Action = runtime_types::pallet_multi_asset_delegation::types::rewards::AssetAction; } @@ -41866,6 +41884,37 @@ pub mod api { const PALLET: &'static str = "MultiAssetDelegation"; const EVENT: &'static str = "DelegatorSlashed"; } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "EVM execution reverted with a reason."] + pub struct EvmReverted { + pub from: evm_reverted::From, + pub to: evm_reverted::To, + pub data: evm_reverted::Data, + pub reason: evm_reverted::Reason, + } + pub mod evm_reverted { + use super::runtime_types; + pub type From = ::subxt_core::utils::H160; + pub type To = ::subxt_core::utils::H160; + pub type Data = ::subxt_core::alloc::vec::Vec<::core::primitive::u8>; + pub type Reason = ::subxt_core::alloc::vec::Vec<::core::primitive::u8>; + } + impl ::subxt_core::events::StaticEvent for EvmReverted { + const PALLET: &'static str = "MultiAssetDelegation"; + const EVENT: &'static str = "EvmReverted"; + } } pub mod storage { use super::runtime_types; @@ -41893,13 +41942,16 @@ pub mod api { } pub mod reward_vaults { use super::runtime_types; - pub type RewardVaults = ::subxt_core::alloc::vec::Vec<::core::primitive::u128>; + pub type RewardVaults = ::subxt_core::alloc::vec::Vec< + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>, + >; pub type Param0 = ::core::primitive::u128; } pub mod asset_lookup_reward_vaults { use super::runtime_types; pub type AssetLookupRewardVaults = ::core::primitive::u128; - pub type Param0 = ::core::primitive::u128; + pub type Param0 = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; } pub mod reward_config_storage { use super::runtime_types; @@ -41927,9 +41979,9 @@ pub mod api { "Operators", (), [ - 96u8, 12u8, 202u8, 32u8, 26u8, 119u8, 119u8, 77u8, 133u8, 40u8, 41u8, - 55u8, 220u8, 158u8, 30u8, 147u8, 39u8, 168u8, 231u8, 231u8, 102u8, - 161u8, 66u8, 27u8, 228u8, 0u8, 123u8, 144u8, 205u8, 235u8, 186u8, 91u8, + 181u8, 37u8, 69u8, 139u8, 18u8, 44u8, 99u8, 55u8, 186u8, 237u8, 91u8, + 83u8, 53u8, 119u8, 142u8, 206u8, 254u8, 203u8, 89u8, 154u8, 138u8, + 163u8, 29u8, 141u8, 7u8, 161u8, 54u8, 162u8, 48u8, 28u8, 70u8, 0u8, ], ) } @@ -41949,9 +42001,9 @@ pub mod api { "Operators", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 96u8, 12u8, 202u8, 32u8, 26u8, 119u8, 119u8, 77u8, 133u8, 40u8, 41u8, - 55u8, 220u8, 158u8, 30u8, 147u8, 39u8, 168u8, 231u8, 231u8, 102u8, - 161u8, 66u8, 27u8, 228u8, 0u8, 123u8, 144u8, 205u8, 235u8, 186u8, 91u8, + 181u8, 37u8, 69u8, 139u8, 18u8, 44u8, 99u8, 55u8, 186u8, 237u8, 91u8, + 83u8, 53u8, 119u8, 142u8, 206u8, 254u8, 203u8, 89u8, 154u8, 138u8, + 163u8, 29u8, 141u8, 7u8, 161u8, 54u8, 162u8, 48u8, 28u8, 70u8, 0u8, ], ) } @@ -41992,9 +42044,10 @@ pub mod api { "AtStake", (), [ - 225u8, 39u8, 121u8, 190u8, 208u8, 227u8, 9u8, 44u8, 140u8, 28u8, 13u8, - 112u8, 213u8, 80u8, 240u8, 250u8, 179u8, 121u8, 82u8, 26u8, 136u8, - 62u8, 197u8, 86u8, 231u8, 210u8, 155u8, 245u8, 36u8, 251u8, 0u8, 193u8, + 156u8, 26u8, 172u8, 63u8, 87u8, 150u8, 192u8, 117u8, 222u8, 34u8, + 191u8, 110u8, 251u8, 174u8, 184u8, 171u8, 73u8, 48u8, 79u8, 87u8, + 175u8, 216u8, 132u8, 96u8, 217u8, 232u8, 148u8, 89u8, 181u8, 39u8, + 219u8, 106u8, ], ) } @@ -42014,9 +42067,10 @@ pub mod api { "AtStake", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 225u8, 39u8, 121u8, 190u8, 208u8, 227u8, 9u8, 44u8, 140u8, 28u8, 13u8, - 112u8, 213u8, 80u8, 240u8, 250u8, 179u8, 121u8, 82u8, 26u8, 136u8, - 62u8, 197u8, 86u8, 231u8, 210u8, 155u8, 245u8, 36u8, 251u8, 0u8, 193u8, + 156u8, 26u8, 172u8, 63u8, 87u8, 150u8, 192u8, 117u8, 222u8, 34u8, + 191u8, 110u8, 251u8, 174u8, 184u8, 171u8, 73u8, 48u8, 79u8, 87u8, + 175u8, 216u8, 132u8, 96u8, 217u8, 232u8, 148u8, 89u8, 181u8, 39u8, + 219u8, 106u8, ], ) } @@ -42043,9 +42097,10 @@ pub mod api { ::subxt_core::storage::address::StaticStorageKey::new(_1.borrow()), ), [ - 225u8, 39u8, 121u8, 190u8, 208u8, 227u8, 9u8, 44u8, 140u8, 28u8, 13u8, - 112u8, 213u8, 80u8, 240u8, 250u8, 179u8, 121u8, 82u8, 26u8, 136u8, - 62u8, 197u8, 86u8, 231u8, 210u8, 155u8, 245u8, 36u8, 251u8, 0u8, 193u8, + 156u8, 26u8, 172u8, 63u8, 87u8, 150u8, 192u8, 117u8, 222u8, 34u8, + 191u8, 110u8, 251u8, 174u8, 184u8, 171u8, 73u8, 48u8, 79u8, 87u8, + 175u8, 216u8, 132u8, 96u8, 217u8, 232u8, 148u8, 89u8, 181u8, 39u8, + 219u8, 106u8, ], ) } @@ -42064,10 +42119,10 @@ pub mod api { "Delegators", (), [ - 186u8, 236u8, 239u8, 183u8, 201u8, 64u8, 123u8, 184u8, 5u8, 98u8, 2u8, - 199u8, 173u8, 253u8, 72u8, 182u8, 3u8, 142u8, 163u8, 56u8, 162u8, - 106u8, 229u8, 144u8, 49u8, 151u8, 144u8, 111u8, 12u8, 187u8, 73u8, - 108u8, + 208u8, 190u8, 90u8, 169u8, 30u8, 169u8, 192u8, 170u8, 53u8, 227u8, + 128u8, 145u8, 223u8, 226u8, 166u8, 141u8, 222u8, 141u8, 6u8, 136u8, + 232u8, 114u8, 217u8, 222u8, 129u8, 124u8, 160u8, 239u8, 33u8, 211u8, + 10u8, 156u8, ], ) } @@ -42087,10 +42142,10 @@ pub mod api { "Delegators", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 186u8, 236u8, 239u8, 183u8, 201u8, 64u8, 123u8, 184u8, 5u8, 98u8, 2u8, - 199u8, 173u8, 253u8, 72u8, 182u8, 3u8, 142u8, 163u8, 56u8, 162u8, - 106u8, 229u8, 144u8, 49u8, 151u8, 144u8, 111u8, 12u8, 187u8, 73u8, - 108u8, + 208u8, 190u8, 90u8, 169u8, 30u8, 169u8, 192u8, 170u8, 53u8, 227u8, + 128u8, 145u8, 223u8, 226u8, 166u8, 141u8, 222u8, 141u8, 6u8, 136u8, + 232u8, 114u8, 217u8, 222u8, 129u8, 124u8, 160u8, 239u8, 33u8, 211u8, + 10u8, 156u8, ], ) } @@ -42109,10 +42164,10 @@ pub mod api { "RewardVaults", (), [ - 107u8, 40u8, 83u8, 145u8, 146u8, 241u8, 12u8, 112u8, 110u8, 211u8, - 66u8, 186u8, 13u8, 229u8, 71u8, 181u8, 174u8, 19u8, 143u8, 231u8, - 242u8, 61u8, 45u8, 254u8, 61u8, 113u8, 204u8, 68u8, 51u8, 82u8, 212u8, - 248u8, + 30u8, 97u8, 236u8, 132u8, 229u8, 86u8, 124u8, 248u8, 89u8, 52u8, 91u8, + 194u8, 48u8, 44u8, 236u8, 142u8, 251u8, 192u8, 107u8, 103u8, 244u8, + 170u8, 94u8, 57u8, 146u8, 82u8, 122u8, 212u8, 228u8, 119u8, 152u8, + 57u8, ], ) } @@ -42132,10 +42187,10 @@ pub mod api { "RewardVaults", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 107u8, 40u8, 83u8, 145u8, 146u8, 241u8, 12u8, 112u8, 110u8, 211u8, - 66u8, 186u8, 13u8, 229u8, 71u8, 181u8, 174u8, 19u8, 143u8, 231u8, - 242u8, 61u8, 45u8, 254u8, 61u8, 113u8, 204u8, 68u8, 51u8, 82u8, 212u8, - 248u8, + 30u8, 97u8, 236u8, 132u8, 229u8, 86u8, 124u8, 248u8, 89u8, 52u8, 91u8, + 194u8, 48u8, 44u8, 236u8, 142u8, 251u8, 192u8, 107u8, 103u8, 244u8, + 170u8, 94u8, 57u8, 146u8, 82u8, 122u8, 212u8, 228u8, 119u8, 152u8, + 57u8, ], ) } @@ -42154,10 +42209,10 @@ pub mod api { "AssetLookupRewardVaults", (), [ - 46u8, 208u8, 170u8, 41u8, 111u8, 195u8, 130u8, 114u8, 204u8, 158u8, - 215u8, 207u8, 211u8, 217u8, 51u8, 244u8, 150u8, 215u8, 253u8, 106u8, - 106u8, 142u8, 208u8, 128u8, 25u8, 0u8, 123u8, 33u8, 0u8, 233u8, 72u8, - 186u8, + 128u8, 153u8, 122u8, 108u8, 34u8, 110u8, 223u8, 199u8, 51u8, 251u8, + 55u8, 208u8, 134u8, 89u8, 137u8, 250u8, 251u8, 211u8, 107u8, 114u8, + 38u8, 28u8, 52u8, 98u8, 234u8, 110u8, 226u8, 205u8, 105u8, 195u8, + 149u8, 113u8, ], ) } @@ -42179,10 +42234,10 @@ pub mod api { "AssetLookupRewardVaults", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 46u8, 208u8, 170u8, 41u8, 111u8, 195u8, 130u8, 114u8, 204u8, 158u8, - 215u8, 207u8, 211u8, 217u8, 51u8, 244u8, 150u8, 215u8, 253u8, 106u8, - 106u8, 142u8, 208u8, 128u8, 25u8, 0u8, 123u8, 33u8, 0u8, 233u8, 72u8, - 186u8, + 128u8, 153u8, 122u8, 108u8, 34u8, 110u8, 223u8, 199u8, 51u8, 251u8, + 55u8, 208u8, 134u8, 89u8, 137u8, 250u8, 251u8, 211u8, 107u8, 114u8, + 38u8, 28u8, 52u8, 98u8, 234u8, 110u8, 226u8, 205u8, 105u8, 195u8, + 149u8, 113u8, ], ) } @@ -42594,6 +42649,7 @@ pub mod api { #[doc = "operators that will run your service. Optionally, you can customize who is permitted"] #[doc = "caller of this service, by default only the caller is allowed to call the service."] pub struct Request { + pub evm_origin: request::EvmOrigin, #[codec(compact)] pub blueprint_id: request::BlueprintId, pub permitted_callers: request::PermittedCallers, @@ -42608,6 +42664,7 @@ pub mod api { } pub mod request { use super::runtime_types; + pub type EvmOrigin = ::core::option::Option<::subxt_core::utils::H160>; pub type BlueprintId = ::core::primitive::u64; pub type PermittedCallers = ::subxt_core::alloc::vec::Vec<::subxt_core::utils::AccountId32>; @@ -42798,11 +42855,12 @@ pub mod api { # [codec (crate = :: subxt_core :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed stake for that service."] + #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed"] + #[doc = "stake for that service."] #[doc = ""] #[doc = "The caller needs to be an authorized Slash Origin for this service."] - #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash"] - #[doc = "by another entity."] + #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call"] + #[doc = "to apply the slash by another entity."] pub struct Slash { pub offender: slash::Offender, #[codec(compact)] @@ -42835,7 +42893,8 @@ pub mod api { #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispute an [UnappliedSlash] for a given era and index."] #[doc = ""] - #[doc = "The caller needs to be an authorized Dispute Origin for the service in the [UnappliedSlash]."] + #[doc = "The caller needs to be an authorized Dispute Origin for the service in the"] + #[doc = "[UnappliedSlash]."] pub struct Dispute { #[codec(compact)] pub era: dispute::Era, @@ -42996,6 +43055,7 @@ pub mod api { #[doc = "caller of this service, by default only the caller is allowed to call the service."] pub fn request( &self, + evm_origin: types::request::EvmOrigin, blueprint_id: types::request::BlueprintId, permitted_callers: types::request::PermittedCallers, operators: types::request::Operators, @@ -43009,6 +43069,7 @@ pub mod api { "Services", "request", types::Request { + evm_origin, blueprint_id, permitted_callers, operators, @@ -43019,10 +43080,10 @@ pub mod api { value, }, [ - 44u8, 199u8, 194u8, 99u8, 16u8, 16u8, 204u8, 77u8, 89u8, 63u8, 128u8, - 231u8, 49u8, 38u8, 217u8, 90u8, 110u8, 121u8, 182u8, 100u8, 192u8, - 195u8, 32u8, 70u8, 198u8, 126u8, 114u8, 138u8, 40u8, 45u8, 204u8, - 238u8, + 239u8, 112u8, 229u8, 145u8, 173u8, 9u8, 69u8, 119u8, 15u8, 142u8, 38u8, + 190u8, 184u8, 7u8, 192u8, 144u8, 170u8, 45u8, 45u8, 161u8, 217u8, + 190u8, 35u8, 153u8, 9u8, 37u8, 231u8, 191u8, 139u8, 174u8, 211u8, + 148u8, ], ) } @@ -43120,11 +43181,12 @@ pub mod api { ], ) } - #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed stake for that service."] + #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed"] + #[doc = "stake for that service."] #[doc = ""] #[doc = "The caller needs to be an authorized Slash Origin for this service."] - #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash"] - #[doc = "by another entity."] + #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call"] + #[doc = "to apply the slash by another entity."] pub fn slash( &self, offender: types::slash::Offender, @@ -43144,7 +43206,8 @@ pub mod api { } #[doc = "Dispute an [UnappliedSlash] for a given era and index."] #[doc = ""] - #[doc = "The caller needs to be an authorized Dispute Origin for the service in the [UnappliedSlash]."] + #[doc = "The caller needs to be an authorized Dispute Origin for the service in the"] + #[doc = "[UnappliedSlash]."] pub fn dispute( &self, era: types::dispute::Era, @@ -43803,6 +43866,16 @@ pub mod api { runtime_types::tangle_primitives::services::OperatorProfile; pub type Param0 = ::subxt_core::utils::AccountId32; } + pub mod staging_service_payments { + use super::runtime_types; + pub type StagingServicePayments = + runtime_types::tangle_primitives::services::StagingServicePayment< + ::subxt_core::utils::AccountId32, + ::core::primitive::u128, + ::core::primitive::u128, + >; + pub type Param0 = ::core::primitive::u64; + } } pub struct StorageApi; impl StorageApi { @@ -44471,6 +44544,61 @@ pub mod api { ], ) } + #[doc = " Holds the service payment information for a service request."] + #[doc = " Once the service is initiated, the payment is transferred to the MBSM and this"] + #[doc = " information is removed."] + #[doc = ""] + #[doc = " Service Requst ID -> Service Payment"] + pub fn staging_service_payments_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::staging_service_payments::StagingServicePayments, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Services", + "StagingServicePayments", + (), + [ + 192u8, 196u8, 170u8, 27u8, 123u8, 252u8, 120u8, 33u8, 138u8, 77u8, + 224u8, 10u8, 9u8, 100u8, 175u8, 118u8, 86u8, 82u8, 147u8, 139u8, 223u8, + 187u8, 42u8, 108u8, 143u8, 226u8, 174u8, 159u8, 195u8, 179u8, 246u8, + 28u8, + ], + ) + } + #[doc = " Holds the service payment information for a service request."] + #[doc = " Once the service is initiated, the payment is transferred to the MBSM and this"] + #[doc = " information is removed."] + #[doc = ""] + #[doc = " Service Requst ID -> Service Payment"] + pub fn staging_service_payments( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::staging_service_payments::Param0, + >, + types::staging_service_payments::StagingServicePayments, + ::subxt_core::utils::Yes, + (), + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Services", + "StagingServicePayments", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 192u8, 196u8, 170u8, 27u8, 123u8, 252u8, 120u8, 33u8, 138u8, 77u8, + 224u8, 10u8, 9u8, 100u8, 175u8, 118u8, 86u8, 82u8, 147u8, 139u8, 223u8, + 187u8, 42u8, 108u8, 143u8, 226u8, 174u8, 159u8, 195u8, 179u8, 246u8, + 28u8, + ], + ) + } } } pub mod constants { @@ -55145,7 +55273,7 @@ pub mod api { #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The callable functions (extrinsics) of the pallet."] pub enum Call { - # [codec (index = 0)] # [doc = "Allows an account to join as an operator by providing a stake."] join_operators { bond_amount : :: core :: primitive :: u128 , } , # [codec (index = 1)] # [doc = "Schedules an operator to leave."] schedule_leave_operators , # [codec (index = 2)] # [doc = "Cancels a scheduled leave for an operator."] cancel_leave_operators , # [codec (index = 3)] # [doc = "Executes a scheduled leave for an operator."] execute_leave_operators , # [codec (index = 4)] # [doc = "Allows an operator to increase their stake."] operator_bond_more { additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "Schedules an operator to decrease their stake."] schedule_operator_unstake { unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "Executes a scheduled stake decrease for an operator."] execute_operator_unstake , # [codec (index = 7)] # [doc = "Cancels a scheduled stake decrease for an operator."] cancel_operator_unstake , # [codec (index = 8)] # [doc = "Allows an operator to go offline."] go_offline , # [codec (index = 9)] # [doc = "Allows an operator to go online."] go_online , # [codec (index = 10)] # [doc = "Allows a user to deposit an asset."] deposit { asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , } , # [codec (index = 11)] # [doc = "Schedules an withdraw request."] schedule_withdraw { asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , } , # [codec (index = 12)] # [doc = "Executes a scheduled withdraw request."] execute_withdraw , # [codec (index = 13)] # [doc = "Cancels a scheduled withdraw request."] cancel_withdraw { asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , } , # [codec (index = 14)] # [doc = "Allows a user to delegate an amount of an asset to an operator."] delegate { operator : :: subxt_core :: utils :: AccountId32 , asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > , } , # [codec (index = 15)] # [doc = "Schedules a request to reduce a delegator's stake."] schedule_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , } , # [codec (index = 16)] # [doc = "Executes a scheduled request to reduce a delegator's stake."] execute_delegator_unstake , # [codec (index = 17)] # [doc = "Cancels a scheduled request to reduce a delegator's stake."] cancel_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : :: core :: primitive :: u128 , amount : :: core :: primitive :: u128 , } , # [codec (index = 18)] # [doc = "Sets the APY and cap for a specific asset."] # [doc = "The APY is the annual percentage yield that the asset will earn."] # [doc = "The cap is the amount of assets required to be deposited to distribute the entire APY."] # [doc = "The APY is capped at 10% and will require runtime upgrade to change."] # [doc = ""] # [doc = "While the cap is not met, the APY distributed will be `amount_deposited / cap * APY`."] set_incentive_apy_and_cap { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Whitelists a blueprint for rewards."] whitelist_blueprint_for_rewards { blueprint_id : :: core :: primitive :: u32 , } , # [codec (index = 20)] # [doc = "Manage asset id to vault rewards"] manage_asset_in_vault { vault_id : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 22)] # [doc = "Adds a blueprint ID to a delegator's selection."] add_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 23)] # [doc = "Removes a blueprint ID from a delegator's selection."] remove_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , } + # [codec (index = 0)] # [doc = "Allows an account to join as an operator by providing a stake."] join_operators { bond_amount : :: core :: primitive :: u128 , } , # [codec (index = 1)] # [doc = "Schedules an operator to leave."] schedule_leave_operators , # [codec (index = 2)] # [doc = "Cancels a scheduled leave for an operator."] cancel_leave_operators , # [codec (index = 3)] # [doc = "Executes a scheduled leave for an operator."] execute_leave_operators , # [codec (index = 4)] # [doc = "Allows an operator to increase their stake."] operator_bond_more { additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "Schedules an operator to decrease their stake."] schedule_operator_unstake { unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "Executes a scheduled stake decrease for an operator."] execute_operator_unstake , # [codec (index = 7)] # [doc = "Cancels a scheduled stake decrease for an operator."] cancel_operator_unstake , # [codec (index = 8)] # [doc = "Allows an operator to go offline."] go_offline , # [codec (index = 9)] # [doc = "Allows an operator to go online."] go_online , # [codec (index = 10)] # [doc = "Allows a user to deposit an asset."] deposit { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , } , # [codec (index = 11)] # [doc = "Schedules an withdraw request."] schedule_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 12)] # [doc = "Executes a scheduled withdraw request."] execute_withdraw { evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , } , # [codec (index = 13)] # [doc = "Cancels a scheduled withdraw request."] cancel_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 14)] # [doc = "Allows a user to delegate an amount of an asset to an operator."] delegate { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > , } , # [codec (index = 15)] # [doc = "Schedules a request to reduce a delegator's stake."] schedule_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 16)] # [doc = "Executes a scheduled request to reduce a delegator's stake."] execute_delegator_unstake , # [codec (index = 17)] # [doc = "Cancels a scheduled request to reduce a delegator's stake."] cancel_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 18)] # [doc = "Sets the APY and cap for a specific asset."] # [doc = "The APY is the annual percentage yield that the asset will earn."] # [doc = "The cap is the amount of assets required to be deposited to distribute the entire APY."] # [doc = "The APY is capped at 10% and will require runtime upgrade to change."] # [doc = ""] # [doc = "While the cap is not met, the APY distributed will be `amount_deposited / cap * APY`."] set_incentive_apy_and_cap { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Whitelists a blueprint for rewards."] whitelist_blueprint_for_rewards { blueprint_id : :: core :: primitive :: u32 , } , # [codec (index = 20)] # [doc = "Manage asset id to vault rewards"] manage_asset_in_vault { vault_id : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 22)] # [doc = "Adds a blueprint ID to a delegator's selection."] add_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 23)] # [doc = "Removes a blueprint ID from a delegator's selection."] remove_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -55302,6 +55430,15 @@ pub mod api { #[codec(index = 46)] #[doc = "The blueprint is not selected"] BlueprintNotSelected, + #[codec(index = 47)] + #[doc = "Erc20 transfer failed"] + ERC20TransferFailed, + #[codec(index = 48)] + #[doc = "EVM encode error"] + EVMAbiEncode, + #[codec(index = 49)] + #[doc = "EVM decode error"] + EVMAbiDecode, } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -55318,7 +55455,7 @@ pub mod api { #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events emitted by the pallet."] pub enum Event { - # [codec (index = 0)] # [doc = "An operator has joined."] OperatorJoined { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 1)] # [doc = "An operator has scheduled to leave."] OperatorLeavingScheduled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 2)] # [doc = "An operator has cancelled their leave request."] OperatorLeaveCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 3)] # [doc = "An operator has executed their leave request."] OperatorLeaveExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 4)] # [doc = "An operator has increased their stake."] OperatorBondMore { who : :: subxt_core :: utils :: AccountId32 , additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "An operator has scheduled to decrease their stake."] OperatorBondLessScheduled { who : :: subxt_core :: utils :: AccountId32 , unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "An operator has executed their stake decrease."] OperatorBondLessExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 7)] # [doc = "An operator has cancelled their stake decrease request."] OperatorBondLessCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 8)] # [doc = "An operator has gone offline."] OperatorWentOffline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 9)] # [doc = "An operator has gone online."] OperatorWentOnline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 10)] # [doc = "A deposit has been made."] Deposited { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , } , # [codec (index = 11)] # [doc = "An withdraw has been scheduled."] Scheduledwithdraw { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , } , # [codec (index = 12)] # [doc = "An withdraw has been executed."] Executedwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 13)] # [doc = "An withdraw has been cancelled."] Cancelledwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 14)] # [doc = "A delegation has been made."] Delegated { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , } , # [codec (index = 15)] # [doc = "A delegator unstake request has been scheduled."] ScheduledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , } , # [codec (index = 16)] # [doc = "A delegator unstake request has been executed."] ExecutedDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 17)] # [doc = "A delegator unstake request has been cancelled."] CancelledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 18)] # [doc = "Event emitted when an incentive APY and cap are set for a reward vault"] IncentiveAPYAndCapSet { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Event emitted when a blueprint is whitelisted for rewards"] BlueprintWhitelisted { blueprint_id : :: core :: primitive :: u32 , } , # [codec (index = 20)] # [doc = "Asset has been updated to reward vault"] AssetUpdatedInVault { who : :: subxt_core :: utils :: AccountId32 , vault_id : :: core :: primitive :: u128 , asset_id : :: core :: primitive :: u128 , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 21)] # [doc = "Operator has been slashed"] OperatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , # [codec (index = 22)] # [doc = "Delegator has been slashed"] DelegatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , } + # [codec (index = 0)] # [doc = "An operator has joined."] OperatorJoined { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 1)] # [doc = "An operator has scheduled to leave."] OperatorLeavingScheduled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 2)] # [doc = "An operator has cancelled their leave request."] OperatorLeaveCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 3)] # [doc = "An operator has executed their leave request."] OperatorLeaveExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 4)] # [doc = "An operator has increased their stake."] OperatorBondMore { who : :: subxt_core :: utils :: AccountId32 , additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "An operator has scheduled to decrease their stake."] OperatorBondLessScheduled { who : :: subxt_core :: utils :: AccountId32 , unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "An operator has executed their stake decrease."] OperatorBondLessExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 7)] # [doc = "An operator has cancelled their stake decrease request."] OperatorBondLessCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 8)] # [doc = "An operator has gone offline."] OperatorWentOffline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 9)] # [doc = "An operator has gone online."] OperatorWentOnline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 10)] # [doc = "A deposit has been made."] Deposited { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 11)] # [doc = "An withdraw has been scheduled."] Scheduledwithdraw { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 12)] # [doc = "An withdraw has been executed."] Executedwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 13)] # [doc = "An withdraw has been cancelled."] Cancelledwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 14)] # [doc = "A delegation has been made."] Delegated { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 15)] # [doc = "A delegator unstake request has been scheduled."] ScheduledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 16)] # [doc = "A delegator unstake request has been executed."] ExecutedDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 17)] # [doc = "A delegator unstake request has been cancelled."] CancelledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 18)] # [doc = "Event emitted when an incentive APY and cap are set for a reward vault"] IncentiveAPYAndCapSet { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Event emitted when a blueprint is whitelisted for rewards"] BlueprintWhitelisted { blueprint_id : :: core :: primitive :: u32 , } , # [codec (index = 20)] # [doc = "Asset has been updated to reward vault"] AssetUpdatedInVault { who : :: subxt_core :: utils :: AccountId32 , vault_id : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 21)] # [doc = "Operator has been slashed"] OperatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , # [codec (index = 22)] # [doc = "Delegator has been slashed"] DelegatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , # [codec (index = 23)] # [doc = "EVM execution reverted with a reason."] EvmReverted { from : :: subxt_core :: utils :: H160 , to : :: subxt_core :: utils :: H160 , data : :: subxt_core :: alloc :: vec :: Vec < :: core :: primitive :: u8 > , reason : :: subxt_core :: alloc :: vec :: Vec < :: core :: primitive :: u8 > , } , } } pub mod types { use super::runtime_types; @@ -55337,7 +55474,7 @@ pub mod api { # [codec (crate = :: subxt_core :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct BondInfoDelegator < _0 , _1 , _2 , _3 > { pub operator : _0 , pub amount : _1 , pub asset_id : _2 , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , } + pub struct BondInfoDelegator < _0 , _1 , _2 , _3 > { pub operator : _0 , pub amount : _1 , pub asset_id : runtime_types :: tangle_primitives :: services :: Asset < _1 > , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < _2 > } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -55351,7 +55488,7 @@ pub mod api { # [codec (crate = :: subxt_core :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct BondLessRequest < _0 , _1 , _2 , _3 > { pub operator : _0 , pub asset_id : _1 , pub amount : _2 , pub requested_round : :: core :: primitive :: u32 , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , } + pub struct BondLessRequest < _0 , _1 , _2 , _3 > { pub operator : _0 , pub asset_id : runtime_types :: tangle_primitives :: services :: Asset < _1 > , pub amount : _2 , pub requested_round : :: core :: primitive :: u32 , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -55389,7 +55526,7 @@ pub mod api { # [codec (crate = :: subxt_core :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct DelegatorMetadata < _0 , _1 , _2 , _3 , _4 , _5 , _6 > { pub deposits : :: subxt_core :: utils :: KeyedVec < _1 , _1 > , pub withdraw_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: WithdrawRequest < _1 , _1 > > , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondInfoDelegator < _0 , _1 , _1 , _6 > > , pub delegator_unstake_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondLessRequest < _0 , _1 , _1 , _6 > > , pub status : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorStatus , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _4 , _3 , _5) > } + pub struct DelegatorMetadata < _0 , _1 , _2 , _3 , _4 , _5 , _6 > { pub deposits : :: subxt_core :: utils :: KeyedVec < runtime_types :: tangle_primitives :: services :: Asset < _1 > , _1 > , pub withdraw_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: WithdrawRequest < _1 , _1 > > , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondInfoDelegator < _0 , _1 , _1 , _6 > > , pub delegator_unstake_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondLessRequest < _0 , _1 , _1 , _6 > > , pub status : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorStatus , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _4 , _3 , _5) > } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -55423,7 +55560,7 @@ pub mod api { #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WithdrawRequest<_0, _1> { - pub asset_id: _0, + pub asset_id: runtime_types::tangle_primitives::services::Asset<_0>, pub amount: _1, pub requested_round: ::core::primitive::u32, } @@ -55446,7 +55583,9 @@ pub mod api { pub struct DelegatorBond<_0, _1, _2> { pub delegator: _0, pub amount: _1, - pub asset_id: _2, + pub asset_id: runtime_types::tangle_primitives::services::Asset<_1>, + #[codec(skip)] + pub __ignore: ::core::marker::PhantomData<_2>, } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -57865,6 +58004,7 @@ pub mod api { #[doc = "operators that will run your service. Optionally, you can customize who is permitted"] #[doc = "caller of this service, by default only the caller is allowed to call the service."] request { + evm_origin: ::core::option::Option<::subxt_core::utils::H160>, #[codec(compact)] blueprint_id: ::core::primitive::u64, permitted_callers: @@ -57937,11 +58077,12 @@ pub mod api { >, }, #[codec(index = 11)] - #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed stake for that service."] + #[doc = "Slash an operator (offender) for a service id with a given percent of their exposed"] + #[doc = "stake for that service."] #[doc = ""] #[doc = "The caller needs to be an authorized Slash Origin for this service."] - #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call to apply the slash"] - #[doc = "by another entity."] + #[doc = "Note that this does not apply the slash directly, but instead schedules a deferred call"] + #[doc = "to apply the slash by another entity."] slash { offender: ::subxt_core::utils::AccountId32, #[codec(compact)] @@ -57952,7 +58093,8 @@ pub mod api { #[codec(index = 12)] #[doc = "Dispute an [UnappliedSlash] for a given era and index."] #[doc = ""] - #[doc = "The caller needs to be an authorized Dispute Origin for the service in the [UnappliedSlash]."] + #[doc = "The caller needs to be an authorized Dispute Origin for the service in the"] + #[doc = "[UnappliedSlash]."] dispute { #[codec(compact)] era: ::core::primitive::u32, @@ -58102,6 +58244,15 @@ pub mod api { #[codec(index = 39)] #[doc = "The ERC20 transfer failed."] ERC20TransferFailed, + #[codec(index = 40)] + #[doc = "Missing EVM Origin for the EVM execution."] + MissingEVMOrigin, + #[codec(index = 41)] + #[doc = "Expected the account to be an EVM address."] + ExpectedEVMAddress, + #[codec(index = 42)] + #[doc = "Expected the account to be an account ID."] + ExpectedAccountId, } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -63573,6 +63724,25 @@ pub mod api { runtime_types::tangle_primitives::services::ApprovalState, )>, } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub struct StagingServicePayment<_0, _1, _2> { + pub request_id: ::core::primitive::u64, + pub refund_to: runtime_types::tangle_primitives::types::Account<_0>, + pub asset: runtime_types::tangle_primitives::services::Asset<_1>, + pub amount: _2, + } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -63669,6 +63839,28 @@ pub mod api { Wasmer, } } + pub mod types { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub enum Account<_0> { + #[codec(index = 0)] + Id(_0), + #[codec(index = 1)] + Address(::subxt_core::utils::H160), + } + } } pub mod tangle_testnet_runtime { use super::runtime_types; From c179e4c478e4ad8d1a82dea1a37053eba94fbb0b Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:26:16 +0530 Subject: [PATCH 19/63] cleanup clippy --- .../src/functions/deposit.rs | 2 +- .../src/functions/evm.rs | 4 +- .../src/functions/rewards.rs | 9 ++--- pallets/multi-asset-delegation/src/lib.rs | 5 +-- .../src/tests/operator.rs | 37 +++++++++++++------ .../src/tests/session_manager.rs | 27 +++++++++----- .../src/types/rewards.rs | 1 - precompiles/multi-asset-delegation/src/lib.rs | 3 +- primitives/src/traits/services.rs | 1 - 9 files changed, 51 insertions(+), 38 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 7711ecf7..08cff321 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -51,7 +51,7 @@ impl Pallet { Asset::Custom(asset_id) => { T::Fungibles::transfer( asset_id, - &sender, + sender, &Self::pallet_account(), amount, Preservation::Expendable, diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index e42d65be..7c307c82 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -10,7 +10,7 @@ use scale_info::prelude::string::String; use sp_core::{H160, U256}; use sp_runtime::traits::UniqueSaturatedInto; use sp_std::{vec, vec::Vec}; -use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; +use tangle_primitives::services::{EvmGasWeightMapping, EvmRunner}; impl Pallet { /// Moves a `value` amount of tokens from the caller's account to `to`. @@ -59,7 +59,7 @@ impl Pallet { let maybe_value = info.exit_reason.is_succeed().then_some(&info.value); let success = if let Some(data) = maybe_value { let result = transfer_fn.decode_output(data).map_err(|_| Error::::EVMAbiDecode)?; - let success = result.first().ok_or_else(|| Error::::EVMAbiDecode)?; + let success = result.first().ok_or(Error::::EVMAbiDecode)?; if let ethabi::Token::Bool(val) = success { *val } else { diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs index deff06ab..6341fa7e 100644 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ b/pallets/multi-asset-delegation/src/functions/rewards.rs @@ -14,13 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::{ - types::{DelegatorBond, *}, - Pallet, -}; +use crate::{types::*, Pallet}; use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; -use sp_runtime::{traits::Zero, DispatchError, Saturating}; -use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; use tangle_primitives::{services::Asset, RoundIndex}; impl Pallet { diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 33378eb2..6f6d33dc 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -82,10 +82,7 @@ pub mod pallet { use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; use frame_support::{ pallet_prelude::*, - traits::{ - fungibles::Inspect, tokens::fungibles, Currency, Get, LockableCurrency, - ReservableCurrency, - }, + traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, PalletId, }; use frame_system::pallet_prelude::*; diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index ee7c85fc..34cba929 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -20,7 +20,7 @@ use crate::{ }; use frame_support::{assert_noop, assert_ok}; use sp_keyring::AccountKeyring::Bob; -use sp_keyring::AccountKeyring::{Alice, Eve}; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve}; use sp_runtime::Percent; use tangle_primitives::services::Asset; @@ -626,8 +626,8 @@ fn slash_operator_success() { let asset_id = Asset::Custom(1); let blueprint_id = 1; - create_and_mint_tokens(asset_id, Bob.to_account_id(), delegator_stake); - mint_tokens(Bob.to_account_id(), asset_id, Bob.to_account_id(), delegator_stake); + create_and_mint_tokens(1, Bob.to_account_id(), delegator_stake); + mint_tokens(Bob.to_account_id(), 1, Bob.to_account_id(), delegator_stake); // Setup delegator with fixed blueprint selection assert_ok!(MultiAssetDelegation::deposit( @@ -660,7 +660,7 @@ fn slash_operator_success() { assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(Bob.to_account_id()), - 1, + Alice.to_account_id(), asset_id, delegator_stake, Fixed(vec![blueprint_id].try_into().unwrap()), @@ -679,13 +679,21 @@ fn slash_operator_success() { assert_eq!(operator_info.stake, operator_stake / 2); // Verify fixed delegator stake was slashed - let delegator_2 = MultiAssetDelegation::delegators(2).unwrap(); - let delegation_2 = delegator_2.delegations.iter().find(|d| d.operator == 1).unwrap(); + let delegator_2 = MultiAssetDelegation::delegators(Charlie.to_account_id()).unwrap(); + let delegation_2 = delegator_2 + .delegations + .iter() + .find(|d| d.operator == Alice.to_account_id()) + .unwrap(); assert_eq!(delegation_2.amount, delegator_stake / 2); // Verify all-blueprints delegator stake was slashed - let delegator_3 = MultiAssetDelegation::delegators(3).unwrap(); - let delegation_3 = delegator_3.delegations.iter().find(|d| d.operator == 1).unwrap(); + let delegator_3 = MultiAssetDelegation::delegators(Charlie.to_account_id()).unwrap(); + let delegation_3 = delegator_3 + .delegations + .iter() + .find(|d| d.operator == Alice.to_account_id()) + .unwrap(); assert_eq!(delegation_3.amount, delegator_stake / 2); // Verify event @@ -745,7 +753,7 @@ fn slash_delegator_fixed_blueprint_not_selected() { // Setup delegator with fixed blueprint selection assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(Bob.to_account_id()), - 1, + Asset::Custom(1), 5_000 )); @@ -756,15 +764,20 @@ fn slash_delegator_fixed_blueprint_not_selected() { assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(Bob.to_account_id()), - 1, - 1, + Alice.to_account_id(), + Asset::Custom(1), 5_000, Fixed(vec![2].try_into().unwrap()), )); // Try to slash with unselected blueprint assert_noop!( - MultiAssetDelegation::slash_delegator(&2, &1, 5, Percent::from_percent(50)), + MultiAssetDelegation::slash_delegator( + &Bob.to_account_id(), + &Alice.to_account_id(), + 5, + Percent::from_percent(50) + ), Error::::BlueprintNotSelected ); }); diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index d16c193d..acdba2f7 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -16,14 +16,16 @@ use super::*; use crate::CurrentRound; use frame_support::assert_ok; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve}; +use tangle_primitives::services::Asset; #[test] fn handle_round_change_should_work() { new_test_ext().execute_with(|| { // Arrange - let who = 1; - let operator = 2; - let asset_id = VDOT; + let who = Bob.to_account_id(); + let operator = Alice.to_account_id(); + let asset_id = Asset::Custom(VDOT); let amount = 100; CurrentRound::::put(1); @@ -33,7 +35,12 @@ fn handle_round_change_should_work() { create_and_mint_tokens(VDOT, who, amount); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, amount,)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who), + asset_id, + amount, + None + )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who), @@ -61,11 +68,11 @@ fn handle_round_change_should_work() { fn handle_round_change_with_unstake_should_work() { new_test_ext().execute_with(|| { // Arrange - let delegator1 = 1; - let delegator2 = 2; - let operator1 = 3; - let operator2 = EVE; - let asset_id = VDOT; + let delegator1 = Alice.to_account_id(); + let delegator2 = Bob.to_account_id(); + let operator1 = Charlie.to_account_id(); + let operator2 = Dave.to_account_id(); + let asset_id = Asset::Custom(VDOT); let amount1 = 100; let amount2 = 200; let unstake_amount = 50; @@ -83,6 +90,7 @@ fn handle_round_change_with_unstake_should_work() { RuntimeOrigin::signed(delegator1), asset_id, amount1, + None, )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(delegator1), @@ -96,6 +104,7 @@ fn handle_round_change_with_unstake_should_work() { RuntimeOrigin::signed(delegator2), asset_id, amount2, + None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(delegator2), diff --git a/pallets/multi-asset-delegation/src/types/rewards.rs b/pallets/multi-asset-delegation/src/types/rewards.rs index 488694c3..6a1daad7 100644 --- a/pallets/multi-asset-delegation/src/types/rewards.rs +++ b/pallets/multi-asset-delegation/src/types/rewards.rs @@ -16,7 +16,6 @@ use super::*; use sp_runtime::Percent; -use tangle_primitives::services::Asset; /// Configuration for rewards associated with a specific asset. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 02d87f18..b8d54921 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -45,10 +45,9 @@ use frame_support::{ }; use pallet_evm::AddressMapping; use pallet_multi_asset_delegation::types::DelegatorBlueprintSelection; -use parity_scale_codec::Decode; use precompile_utils::prelude::*; use sp_core::{H160, H256, U256}; -use sp_runtime::traits::{Dispatchable, TryConvert}; +use sp_runtime::traits::Dispatchable; use sp_std::{marker::PhantomData, vec::Vec}; use tangle_primitives::{services::Asset, types::WrappedAccountId32}; diff --git a/primitives/src/traits/services.rs b/primitives/src/traits/services.rs index 087586b7..e550c188 100644 --- a/primitives/src/traits/services.rs +++ b/primitives/src/traits/services.rs @@ -1,5 +1,4 @@ use scale_info::prelude::vec::Vec; -use sp_core::{H160, U256}; /// A trait to manage and query services and blueprints for operators. /// From 8c58a054cff356eecc8339c29b50a3a63efb0694 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:26:29 +0530 Subject: [PATCH 20/63] use nightly fmt --- .../evm-tracing/src/formatters/blockscout.rs | 2 +- .../evm-tracing/src/formatters/call_tracer.rs | 37 ++++----- .../src/formatters/trace_filter.rs | 15 ++-- client/evm-tracing/src/listeners/call_list.rs | 71 +++++++--------- client/evm-tracing/src/listeners/raw.rs | 12 +-- client/evm-tracing/src/types/serialization.rs | 4 +- client/rpc-core/txpool/src/types/content.rs | 15 ++-- client/rpc/debug/src/lib.rs | 80 ++++++++----------- client/rpc/trace/src/lib.rs | 47 +++++------ client/rpc/txpool/src/lib.rs | 2 +- frost/frost-ristretto255/src/lib.rs | 5 +- frost/src/keys.rs | 2 +- frost/src/lib.rs | 10 +-- frost/src/round1.rs | 6 +- frost/src/scalar_mul.rs | 6 +- frost/src/signature.rs | 6 +- frost/src/signing_key.rs | 2 +- node/src/distributions/mainnet.rs | 42 +++++----- node/src/manual_seal.rs | 2 +- node/src/service.rs | 8 +- node/src/utils.rs | 2 +- pallets/claims/src/lib.rs | 15 ++-- pallets/claims/src/utils/mod.rs | 5 +- .../src/functions/delegate.rs | 2 +- .../src/functions/deposit.rs | 5 +- pallets/multi-asset-delegation/src/mock.rs | 25 +++--- .../multi-asset-delegation/src/mock_evm.rs | 17 ++-- .../src/tests/operator.rs | 11 +-- pallets/services/rpc/src/lib.rs | 10 +-- pallets/services/src/functions.rs | 5 +- pallets/services/src/lib.rs | 5 +- pallets/services/src/mock.rs | 7 +- pallets/services/src/mock_evm.rs | 14 ++-- pallets/services/src/tests.rs | 5 +- pallets/tangle-lst/src/lib.rs | 11 ++- pallets/tangle-lst/src/types/bonded_pool.rs | 12 +-- pallets/tangle-lst/src/types/commission.rs | 8 +- precompiles/assets-erc20/src/lib.rs | 6 +- precompiles/assets-erc20/src/tests.rs | 4 +- precompiles/balances-erc20/src/lib.rs | 10 +-- precompiles/balances-erc20/src/tests.rs | 4 +- precompiles/batch/src/lib.rs | 40 ++++------ precompiles/call-permit/src/lib.rs | 7 +- precompiles/multi-asset-delegation/src/lib.rs | 32 +++----- .../multi-asset-delegation/src/tests.rs | 8 +- precompiles/pallet-democracy/src/lib.rs | 2 +- precompiles/pallet-democracy/src/tests.rs | 36 ++++----- precompiles/precompile-registry/src/lib.rs | 7 +- precompiles/proxy/src/lib.rs | 25 +++--- precompiles/services/src/lib.rs | 9 +-- precompiles/services/src/mock.rs | 2 +- precompiles/services/src/mock_evm.rs | 14 ++-- precompiles/services/src/tests.rs | 5 +- precompiles/staking/src/lib.rs | 2 +- precompiles/tangle-lst/src/lib.rs | 2 +- .../verify-bls381-signature/src/lib.rs | 4 +- .../verify-schnorr-signatures/src/lib.rs | 2 +- precompiles/vesting/src/lib.rs | 4 +- primitives/rpc/evm-tracing-events/src/evm.rs | 20 ++--- .../rpc/evm-tracing-events/src/gasometer.rs | 20 ++--- .../rpc/evm-tracing-events/src/runtime.rs | 15 ++-- primitives/src/chain_identifier.rs | 16 ++-- primitives/src/services/field.rs | 20 +++-- primitives/src/services/mod.rs | 14 ++-- primitives/src/verifier/circom.rs | 10 +-- runtime/mainnet/src/filters.rs | 4 +- runtime/mainnet/src/frontier_evm.rs | 15 ++-- runtime/mainnet/src/lib.rs | 26 +++--- runtime/testnet/src/filters.rs | 4 +- runtime/testnet/src/frontier_evm.rs | 6 +- runtime/testnet/src/lib.rs | 26 +++--- 71 files changed, 419 insertions(+), 535 deletions(-) diff --git a/client/evm-tracing/src/formatters/blockscout.rs b/client/evm-tracing/src/formatters/blockscout.rs index 61b8033e..9efe1505 100644 --- a/client/evm-tracing/src/formatters/blockscout.rs +++ b/client/evm-tracing/src/formatters/blockscout.rs @@ -36,7 +36,7 @@ impl super::ResponseFormatter for Formatter { if let Some(entry) = listener.entries.last() { return Some(TransactionTrace::CallList( entry.iter().map(|(_, value)| Call::Blockscout(value.clone())).collect(), - )); + )) } None } diff --git a/client/evm-tracing/src/formatters/call_tracer.rs b/client/evm-tracing/src/formatters/call_tracer.rs index 6b2d7ae4..b72ea0c9 100644 --- a/client/evm-tracing/src/formatters/call_tracer.rs +++ b/client/evm-tracing/src/formatters/call_tracer.rs @@ -56,14 +56,13 @@ impl super::ResponseFormatter for Formatter { gas_used, trace_address: Some(trace_address.clone()), inner: match inner.clone() { - BlockscoutCallInner::Call { input, to, res, call_type } => { + BlockscoutCallInner::Call { input, to, res, call_type } => CallTracerInner::Call { call_type: match call_type { CallType::Call => "CALL".as_bytes().to_vec(), CallType::CallCode => "CALLCODE".as_bytes().to_vec(), - CallType::DelegateCall => { - "DELEGATECALL".as_bytes().to_vec() - }, + CallType::DelegateCall => + "DELEGATECALL".as_bytes().to_vec(), CallType::StaticCall => "STATICCALL".as_bytes().to_vec(), }, to, @@ -74,8 +73,7 @@ impl super::ResponseFormatter for Formatter { CallResult::Output { .. } => it.logs.clone(), CallResult::Error { .. } => Vec::new(), }, - } - }, + }, BlockscoutCallInner::Create { init, res } => CallTracerInner::Create { input: init, error: match res { @@ -89,21 +87,19 @@ impl super::ResponseFormatter for Formatter { CreateResult::Error { .. } => None, }, output: match res { - CreateResult::Success { created_contract_code, .. } => { - Some(created_contract_code) - }, + CreateResult::Success { created_contract_code, .. } => + Some(created_contract_code), CreateResult::Error { .. } => None, }, value, call_type: "CREATE".as_bytes().to_vec(), }, - BlockscoutCallInner::SelfDestruct { balance, to } => { + BlockscoutCallInner::SelfDestruct { balance, to } => CallTracerInner::SelfDestruct { value: balance, to, call_type: "SELFDESTRUCT".as_bytes().to_vec(), - } - }, + }, }, calls: Vec::new(), }) @@ -165,11 +161,11 @@ impl super::ResponseFormatter for Formatter { let sibling_greater_than = |a: &Vec, b: &Vec| -> bool { for (i, a_value) in a.iter().enumerate() { if a_value > &b[i] { - return true; + return true } else if a_value < &b[i] { - return false; + return false } else { - continue; + continue } } false @@ -193,11 +189,10 @@ impl super::ResponseFormatter for Formatter { ( Call::CallTracer(CallTracerCall { trace_address: Some(a), .. }), Call::CallTracer(CallTracerCall { trace_address: Some(b), .. }), - ) => { - &b[..] - == a.get(0..a.len() - 1) - .expect("non-root element while traversing trace result") - }, + ) => + &b[..] == + a.get(0..a.len() - 1) + .expect("non-root element while traversing trace result"), _ => unreachable!(), }) { // Remove `trace_address` from result. @@ -228,7 +223,7 @@ impl super::ResponseFormatter for Formatter { } } if traces.is_empty() { - return None; + return None } Some(traces) } diff --git a/client/evm-tracing/src/formatters/trace_filter.rs b/client/evm-tracing/src/formatters/trace_filter.rs index 9bb03210..f8844c8f 100644 --- a/client/evm-tracing/src/formatters/trace_filter.rs +++ b/client/evm-tracing/src/formatters/trace_filter.rs @@ -56,12 +56,11 @@ impl super::ResponseFormatter for Formatter { // Can't be known here, must be inserted upstream. block_number: 0, output: match res { - CallResult::Output(output) => { + CallResult::Output(output) => TransactionTraceOutput::Result(TransactionTraceResult::Call { gas_used: trace.gas_used, output, - }) - }, + }), CallResult::Error(error) => TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, @@ -87,16 +86,14 @@ impl super::ResponseFormatter for Formatter { CreateResult::Success { created_contract_address_hash, created_contract_code, - } => { + } => TransactionTraceOutput::Result(TransactionTraceResult::Create { gas_used: trace.gas_used, code: created_contract_code, address: created_contract_address_hash, - }) - }, - CreateResult::Error { error } => { - TransactionTraceOutput::Error(error) - }, + }), + CreateResult::Error { error } => + TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, trace_address: trace.trace_address.clone(), diff --git a/client/evm-tracing/src/listeners/call_list.rs b/client/evm-tracing/src/listeners/call_list.rs index 9da8a66a..5ca1eb15 100644 --- a/client/evm-tracing/src/listeners/call_list.rs +++ b/client/evm-tracing/src/listeners/call_list.rs @@ -224,9 +224,9 @@ impl Listener { pub fn gasometer_event(&mut self, event: GasometerEvent) { match event { - GasometerEvent::RecordCost { snapshot, .. } - | GasometerEvent::RecordDynamicCost { snapshot, .. } - | GasometerEvent::RecordStipend { snapshot, .. } => { + GasometerEvent::RecordCost { snapshot, .. } | + GasometerEvent::RecordDynamicCost { snapshot, .. } | + GasometerEvent::RecordStipend { snapshot, .. } => { if let Some(context) = self.context_stack.last_mut() { if context.start_gas.is_none() { context.start_gas = Some(snapshot.gas()); @@ -497,13 +497,12 @@ impl Listener { // behavior (like batch precompile does) thus we simply consider this a call. self.call_type = Some(CallType::Call); }, - EvmEvent::Log { address, topics, data } => { + EvmEvent::Log { address, topics, data } => if self.with_log { if let Some(stack) = self.context_stack.last_mut() { stack.logs.push(Log { address, topics, data }); } - } - }, + }, // We ignore other kinds of message if any (new ones may be added in the future). #[allow(unreachable_patterns)] @@ -537,15 +536,13 @@ impl Listener { match context.context_type { ContextType::Call(call_type) => { let res = match &reason { - ExitReason::Succeed(ExitSucceed::Returned) => { - CallResult::Output(return_value.to_vec()) - }, + ExitReason::Succeed(ExitSucceed::Returned) => + CallResult::Output(return_value.to_vec()), ExitReason::Succeed(_) => CallResult::Output(vec![]), ExitReason::Error(error) => CallResult::Error(error_message(error)), - ExitReason::Revert(_) => { - CallResult::Error(b"execution reverted".to_vec()) - }, + ExitReason::Revert(_) => + CallResult::Error(b"execution reverted".to_vec()), ExitReason::Fatal(_) => CallResult::Error(vec![]), }; @@ -571,12 +568,10 @@ impl Listener { created_contract_address_hash: context.to, created_contract_code: return_value.to_vec(), }, - ExitReason::Error(error) => { - CreateResult::Error { error: error_message(error) } - }, - ExitReason::Revert(_) => { - CreateResult::Error { error: b"execution reverted".to_vec() } - }, + ExitReason::Error(error) => + CreateResult::Error { error: error_message(error) }, + ExitReason::Revert(_) => + CreateResult::Error { error: b"execution reverted".to_vec() }, ExitReason::Fatal(_) => CreateResult::Error { error: vec![] }, }; @@ -625,15 +620,14 @@ impl ListenerT for Listener { Event::Gasometer(gasometer_event) => self.gasometer_event(gasometer_event), Event::Runtime(runtime_event) => self.runtime_event(runtime_event), Event::Evm(evm_event) => self.evm_event(evm_event), - Event::CallListNew() => { + Event::CallListNew() => if !self.call_list_first_transaction { self.finish_transaction(); self.skip_next_context = false; self.entries.push(BTreeMap::new()); } else { self.call_list_first_transaction = false; - } - }, + }, }; } @@ -732,9 +726,8 @@ mod tests { target: H160::default(), balance: U256::zero(), }, - TestEvmEvent::Exit => { - EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() } - }, + TestEvmEvent::Exit => + EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() }, TestEvmEvent::TransactCall => EvmEvent::TransactCall { caller: H160::default(), address: H160::default(), @@ -757,9 +750,8 @@ mod tests { gas_limit: 0u64, address: H160::default(), }, - TestEvmEvent::Log => { - EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() } - }, + TestEvmEvent::Log => + EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() }, } } @@ -772,9 +764,8 @@ mod tests { stack: test_stack(), memory: test_memory(), }, - TestRuntimeEvent::StepResult => { - RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() } - }, + TestRuntimeEvent::StepResult => + RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() }, TestRuntimeEvent::SLoad => RuntimeEvent::SLoad { address: H160::default(), index: H256::default(), @@ -790,24 +781,20 @@ mod tests { fn test_emit_gasometer_event(event_type: TestGasometerEvent) -> GasometerEvent { match event_type { - TestGasometerEvent::RecordCost => { - GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() } - }, - TestGasometerEvent::RecordRefund => { - GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() } - }, - TestGasometerEvent::RecordStipend => { - GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() } - }, + TestGasometerEvent::RecordCost => + GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordRefund => + GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordStipend => + GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() }, TestGasometerEvent::RecordDynamicCost => GasometerEvent::RecordDynamicCost { gas_cost: 0u64, memory_gas: 0u64, gas_refund: 0i64, snapshot: test_snapshot(), }, - TestGasometerEvent::RecordTransaction => { - GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() } - }, + TestGasometerEvent::RecordTransaction => + GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() }, } } diff --git a/client/evm-tracing/src/listeners/raw.rs b/client/evm-tracing/src/listeners/raw.rs index 483ea0a3..2b39fe23 100644 --- a/client/evm-tracing/src/listeners/raw.rs +++ b/client/evm-tracing/src/listeners/raw.rs @@ -161,7 +161,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(memory.data.len())); if self.remaining_memory_usage.is_none() { - return; + return } Some(memory.data.clone()) @@ -176,7 +176,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(stack.data.len())); if self.remaining_memory_usage.is_none() { - return; + return } Some(stack.data.clone()) @@ -205,7 +205,7 @@ impl Listener { }); if self.remaining_memory_usage.is_none() { - return; + return } Some(context.storage_cache.clone()) @@ -277,8 +277,8 @@ impl Listener { _ => (), } }, - RuntimeEvent::SLoad { address: _, index, value } - | RuntimeEvent::SStore { address: _, index, value } => { + RuntimeEvent::SLoad { address: _, index, value } | + RuntimeEvent::SStore { address: _, index, value } => { if let Some(context) = self.context_stack.last_mut() { if !self.disable_storage { context.storage_cache.insert(index, value); @@ -295,7 +295,7 @@ impl Listener { impl ListenerT for Listener { fn event(&mut self, event: Event) { if self.remaining_memory_usage.is_none() { - return; + return } match event { diff --git a/client/evm-tracing/src/types/serialization.rs b/client/evm-tracing/src/types/serialization.rs index f786ffaf..9f31f709 100644 --- a/client/evm-tracing/src/types/serialization.rs +++ b/client/evm-tracing/src/types/serialization.rs @@ -54,7 +54,7 @@ where S: Serializer, { if let Some(bytes) = bytes.as_ref() { - return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))); + return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))) } Err(S::Error::custom("String serialize error.")) } @@ -87,7 +87,7 @@ where let d = std::str::from_utf8(&value[..]) .map_err(|_| S::Error::custom("String serialize error."))? .to_string(); - return serializer.serialize_str(&d); + return serializer.serialize_str(&d) } Err(S::Error::custom("String serialize error.")) } diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index ec98a00f..581be173 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -66,15 +66,12 @@ where impl GetT for Transaction { fn get(hash: H256, from_address: H160, txn: &EthereumTransaction) -> Self { let (nonce, action, value, gas_price, gas_limit, input) = match txn { - EthereumTransaction::Legacy(t) => { - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) - }, - EthereumTransaction::EIP2930(t) => { - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) - }, - EthereumTransaction::EIP1559(t) => { - (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()) - }, + EthereumTransaction::Legacy(t) => + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), + EthereumTransaction::EIP2930(t) => + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), + EthereumTransaction::EIP1559(t) => + (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()), }; Self { hash, diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index 09b2b932..c1878aca 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -353,15 +353,12 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => { - Ok(BlockId::Number(client.info().best_number)) - }, - RequestBlockId::Tag(RequestBlockTag::Earliest) => { - Ok(BlockId::Number(0u32.unique_saturated_into())) - }, - RequestBlockId::Tag(RequestBlockTag::Pending) => { - Err(internal_err("'pending' blocks are not supported")) - }, + RequestBlockId::Tag(RequestBlockTag::Latest) => + Ok(BlockId::Number(client.info().best_number)), + RequestBlockId::Tag(RequestBlockTag::Earliest) => + Ok(BlockId::Number(0u32.unique_saturated_into())), + RequestBlockId::Tag(RequestBlockTag::Pending) => + Err(internal_err("'pending' blocks are not supported")), RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -381,7 +378,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -398,7 +395,7 @@ where // If there are no ethereum transactions in the block return empty trace right away. if eth_tx_hashes.is_empty() { - return Ok(Response::Block(vec![])); + return Ok(Response::Block(vec![])) } // Get block extrinsics. @@ -413,7 +410,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; // Trace the block. @@ -428,7 +425,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (core)".to_string())); + return Err(internal_err("Runtime api version call failed (core)".to_string())) }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -473,11 +470,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::CallTracer => { + TracerInput::CallTracer => client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), _ => Err(internal_err("Bug: failed to resolve the tracer format.".to_string())), }?; @@ -537,7 +533,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(reference_hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(reference_hash) { Ok(Some(h)) => h, @@ -558,7 +554,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; let reference_block = overrides.current_block(reference_hash); @@ -580,7 +576,7 @@ where } else { return Err(internal_err( "Runtime api version call failed (core)".to_string(), - )); + )) }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -612,20 +608,17 @@ where // Pre-london update, legacy transactions. match transaction { ethereum::TransactionV2::Legacy(tx) => - { #[allow(deprecated)] api.trace_transaction_before_version_4( parent_block_hash, exts, tx, - ) - }, - _ => { + ), + _ => return Err(internal_err( "Bug: pre-london runtime expects legacy transactions" .to_string(), - )) - }, + )), } } }; @@ -666,11 +659,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => { + TracerInput::Blockscout => client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) @@ -688,7 +680,7 @@ where "Bug: `handle_transaction_request` does not support {:?}.", not_supported ))), - }; + } } } Err(internal_err("Runtime block call failed".to_string())) @@ -706,15 +698,12 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => { - Ok(BlockId::Number(client.info().best_number)) - }, - RequestBlockId::Tag(RequestBlockTag::Earliest) => { - Ok(BlockId::Number(0u32.unique_saturated_into())) - }, - RequestBlockId::Tag(RequestBlockTag::Pending) => { - Err(internal_err("'pending' blocks are not supported")) - }, + RequestBlockId::Tag(RequestBlockTag::Latest) => + Ok(BlockId::Number(client.info().best_number)), + RequestBlockId::Tag(RequestBlockTag::Earliest) => + Ok(BlockId::Number(0u32.unique_saturated_into())), + RequestBlockId::Tag(RequestBlockTag::Pending) => + Err(internal_err("'pending' blocks are not supported")), RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -732,7 +721,7 @@ where let api = client.runtime_api(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")); + return Err(internal_err("Block header not found")) }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -747,13 +736,11 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())); + return Err(internal_err("Runtime api version call failed (trace)".to_string())) }; if trace_api_version <= 5 { - return Err(internal_err( - "debug_traceCall not supported with old runtimes".to_string(), - )); + return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())) } let TraceCallParams { @@ -808,7 +795,7 @@ where } else { return Err(internal_err( "block unavailable, cannot query gas limit".to_string(), - )); + )) } }, }; @@ -860,11 +847,10 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => { + TracerInput::Blockscout => client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))) - }, + .map_err(|e| internal_err(format!("{:?}", e))), TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 72c564df..4514ce79 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -100,9 +100,8 @@ where .try_into() .map_err(|_| "Block number overflow")?), Some(RequestBlockId::Tag(RequestBlockTag::Earliest)) => Ok(0), - Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => { - Err("'pending' is not supported") - }, + Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => + Err("'pending' is not supported"), Some(RequestBlockId::Hash(_)) => Err("Block hash not supported"), } } @@ -118,14 +117,14 @@ where return Err(format!( "count ({}) can't be greater than maximum ({})", count, self.max_count - )); + )) } // Build a list of all the Substrate block hashes that need to be traced. let mut block_hashes = vec![]; for block_height in block_heights { if block_height == 0 { - continue; // no traces for genesis block. + continue // no traces for genesis block. } let block_hash = self @@ -174,18 +173,15 @@ where let mut block_traces: Vec<_> = block_traces .iter() .filter(|trace| match trace.action { - block::TransactionTraceAction::Call { from, to, .. } => { - (from_address.is_empty() || from_address.contains(&from)) - && (to_address.is_empty() || to_address.contains(&to)) - }, - block::TransactionTraceAction::Create { from, .. } => { - (from_address.is_empty() || from_address.contains(&from)) - && to_address.is_empty() - }, - block::TransactionTraceAction::Suicide { address, .. } => { - (from_address.is_empty() || from_address.contains(&address)) - && to_address.is_empty() - }, + block::TransactionTraceAction::Call { from, to, .. } => + (from_address.is_empty() || from_address.contains(&from)) && + (to_address.is_empty() || to_address.contains(&to)), + block::TransactionTraceAction::Create { from, .. } => + (from_address.is_empty() || from_address.contains(&from)) && + to_address.is_empty(), + block::TransactionTraceAction::Suicide { address, .. } => + (from_address.is_empty() || from_address.contains(&address)) && + to_address.is_empty(), }) .cloned() .collect(); @@ -211,11 +207,11 @@ where "the amount of traces goes over the maximum ({}), please use 'after' \ and 'count' in your request", self.max_count - )); + )) } traces = traces.into_iter().take(count).collect(); - break; + break } } } @@ -652,8 +648,8 @@ where // We remove early the block cache if this batch is the last // pooling this block. if let Some(block_cache) = self.cached_blocks.get_mut(block) { - if block_cache.active_batch_count == 1 - && matches!( + if block_cache.active_batch_count == 1 && + matches!( block_cache.state, CacheBlockState::Pooled { started: false, .. } ) { @@ -760,12 +756,11 @@ where overrides.current_transaction_statuses(substrate_hash), ) { (Some(a), Some(b)) => (a, b), - _ => { + _ => return Err(format!( "Failed to get Ethereum block data for Substrate block {}", substrate_hash - )) - }, + )), }; let eth_block_hash = eth_block.header.hash(); @@ -786,7 +781,7 @@ where { api_version } else { - return Err("Runtime api version call failed (trace)".to_string()); + return Err("Runtime api version call failed (trace)".to_string()) }; // Trace the block. @@ -800,7 +795,7 @@ where { api_version } else { - return Err("Runtime api version call failed (core)".to_string()); + return Err("Runtime api version call failed (core)".to_string()) }; // Initialize block: calls the "on_initialize" hook on every pallet diff --git a/client/rpc/txpool/src/lib.rs b/client/rpc/txpool/src/lib.rs index 101050c5..c00ad935 100644 --- a/client/rpc/txpool/src/lib.rs +++ b/client/rpc/txpool/src/lib.rs @@ -74,7 +74,7 @@ where if let Ok(Some(api_version)) = api.api_version::>(best_block) { api_version } else { - return Err(internal_err("failed to retrieve Runtime Api version".to_string())); + return Err(internal_err("failed to retrieve Runtime Api version".to_string())) }; let ethereum_txns: TxPoolResponse = if api_version == 1 { #[allow(deprecated)] diff --git a/frost/frost-ristretto255/src/lib.rs b/frost/frost-ristretto255/src/lib.rs index a4d955fc..a3322ef4 100644 --- a/frost/frost-ristretto255/src/lib.rs +++ b/frost/frost-ristretto255/src/lib.rs @@ -102,13 +102,12 @@ impl Group for RistrettoGroup { .map_err(|_| GroupError::MalformedElement)? .decompress() { - Some(point) => { + Some(point) => if point == RistrettoPoint::identity() { Err(GroupError::InvalidIdentityElement) } else { Ok(WrappedRistrettoPoint(point)) - } - }, + }, None => Err(GroupError::MalformedElement), } } diff --git a/frost/src/keys.rs b/frost/src/keys.rs index 1c2656da..5069d93f 100644 --- a/frost/src/keys.rs +++ b/frost/src/keys.rs @@ -384,7 +384,7 @@ where let result = evaluate_vss(self.identifier, &self.commitment); if !(f_result == result) { - return Err(Error::InvalidSecretShare); + return Err(Error::InvalidSecretShare) } Ok((VerifyingShare(result), self.commitment.verifying_key()?)) diff --git a/frost/src/lib.rs b/frost/src/lib.rs index ede2024d..5bd2fdff 100644 --- a/frost/src/lib.rs +++ b/frost/src/lib.rs @@ -66,7 +66,7 @@ pub fn random_nonzero(rng: &mut R) -> Sc let scalar = <::Field>::random(rng); if scalar != <::Field>::zero() { - return scalar; + return scalar } } } @@ -203,7 +203,7 @@ fn compute_lagrange_coefficient( x_i: Identifier, ) -> Result, Error> { if x_set.is_empty() { - return Err(Error::IncorrectNumberOfIdentifiers); + return Err(Error::IncorrectNumberOfIdentifiers) } let mut num = <::Field>::one(); let mut den = <::Field>::one(); @@ -213,7 +213,7 @@ fn compute_lagrange_coefficient( for x_j in x_set.iter() { if x_i == *x_j { x_i_found = true; - continue; + continue } if let Some(x) = x { @@ -226,7 +226,7 @@ fn compute_lagrange_coefficient( } } if !x_i_found { - return Err(Error::UnknownIdentifier); + return Err(Error::UnknownIdentifier) } Ok(num * <::Field>::invert(&den).map_err(|_| Error::DuplicatedIdentifier)?) @@ -396,7 +396,7 @@ where // The following check prevents a party from accidentally revealing their share. // Note that the '&&' operator would be sufficient. if identity == commitment.binding.0 || identity == commitment.hiding.0 { - return Err(Error::IdentityCommitment); + return Err(Error::IdentityCommitment) } let binding_factor = diff --git a/frost/src/round1.rs b/frost/src/round1.rs index 54039c00..52f7d61a 100644 --- a/frost/src/round1.rs +++ b/frost/src/round1.rs @@ -106,9 +106,9 @@ where /// Checks if the commitments are valid. pub fn is_valid(&self) -> bool { - element_is_valid::(&self.hiding.0) - && element_is_valid::(&self.binding.0) - && self.hiding.0 != self.binding.0 + element_is_valid::(&self.hiding.0) && + element_is_valid::(&self.binding.0) && + self.hiding.0 != self.binding.0 } } diff --git a/frost/src/scalar_mul.rs b/frost/src/scalar_mul.rs index 8211ac83..a80b98b3 100644 --- a/frost/src/scalar_mul.rs +++ b/frost/src/scalar_mul.rs @@ -118,7 +118,7 @@ where // If carry == 1 and window & 1 == 0, then bit_buf & 1 == 1 so the next carry should // be 1 pos += 1; - continue; + continue } if window < width / 2 { @@ -197,14 +197,14 @@ where .collect::>>()?; if nafs.len() != lookup_tables.len() { - return None; + return None } let mut r = ::identity(); // All NAFs will have the same size, so get it from the first if nafs.is_empty() { - return Some(r); + return Some(r) } let naf_length = nafs[0].len(); diff --git a/frost/src/signature.rs b/frost/src/signature.rs index 5a1f89be..c7f059e5 100644 --- a/frost/src/signature.rs +++ b/frost/src/signature.rs @@ -210,10 +210,10 @@ where lambda_i: Scalar, challenge: &Challenge, ) -> Result<(), Error> { - if (::generator() * self.share) - != (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) + if (::generator() * self.share) != + (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) { - return Err(Error::InvalidSignatureShare); + return Err(Error::InvalidSignatureShare) } Ok(()) diff --git a/frost/src/signing_key.rs b/frost/src/signing_key.rs index 758600f5..9307d5ed 100644 --- a/frost/src/signing_key.rs +++ b/frost/src/signing_key.rs @@ -44,7 +44,7 @@ where <::Field as Field>::deserialize(&bytes).map_err(Error::from)?; if scalar == <::Field as Field>::zero() { - return Err(Error::MalformedSigningKey); + return Err(Error::MalformedSigningKey) } Ok(Self { scalar }) diff --git a/node/src/distributions/mainnet.rs b/node/src/distributions/mainnet.rs index a88ba554..cfbec875 100644 --- a/node/src/distributions/mainnet.rs +++ b/node/src/distributions/mainnet.rs @@ -44,7 +44,7 @@ fn read_contents_to_substrate_accounts(path_str: &str) -> BTreeMap BTreeMap BTreeMap Result<(), S // Ensure key is present if !ensure_keytype_exists_in_keystore(key_type, key_store.clone()) { println!("{key_type:?} key not found!"); - return Err("Key not found!".to_string()); + return Err("Key not found!".to_string()) } } diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 161de15d..40964208 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -94,16 +94,14 @@ impl StatementKind { /// Convert this to the (English) statement it represents. fn to_text(self) -> &'static [u8] { match self { - StatementKind::Regular => { + StatementKind::Regular => &b"I hereby agree to the terms of the statement whose sha2256sum is \ 5627de05cfe235cd4ffa0d6375c8a5278b89cc9b9e75622fa2039f4d1b43dadf. (This may be found at the URL: \ - https://statement.tangle.tools/airdrop-statement.html)"[..] - }, - StatementKind::Safe => { + https://statement.tangle.tools/airdrop-statement.html)"[..], + StatementKind::Safe => &b"I hereby agree to the terms of the statement whose sha2256sum is \ 7eae145b00c1912c8b01674df5df4ad9abcf6d18ea3f33d27eb6897a762f4273. (This may be found at the URL: \ - https://statement.tangle.tools/safe-claim-statement)"[..] - }, + https://statement.tangle.tools/safe-claim-statement)"[..], } } } @@ -641,10 +639,9 @@ impl Pallet { statement: Vec, ) -> Result> { let signer = match signature { - MultiAddressSignature::EVM(ethereum_signature) => { + MultiAddressSignature::EVM(ethereum_signature) => Self::eth_recover(ðereum_signature, &data, &statement[..]) - .ok_or(Error::::InvalidEthereumSignature)? - }, + .ok_or(Error::::InvalidEthereumSignature)?, MultiAddressSignature::Native(sr25519_signature) => { ensure!(!signer.is_none(), Error::::InvalidNativeAccount); Self::sr25519_recover(signer.unwrap(), &sr25519_signature, &data, &statement[..]) diff --git a/pallets/claims/src/utils/mod.rs b/pallets/claims/src/utils/mod.rs index a387457f..f2559685 100644 --- a/pallets/claims/src/utils/mod.rs +++ b/pallets/claims/src/utils/mod.rs @@ -45,9 +45,8 @@ impl Hash for MultiAddress { impl MultiAddress { pub fn to_account_id_32(&self) -> AccountId32 { match self { - MultiAddress::EVM(ethereum_address) => { - HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)) - }, + MultiAddress::EVM(ethereum_address) => + HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)), MultiAddress::Native(substrate_address) => substrate_address.clone(), } } diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 03c95e66..73a85832 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -121,7 +121,7 @@ impl Pallet { // Update storage Operators::::insert(&operator, operator_metadata); } else { - return Err(Error::::NotAnOperator.into()); + return Err(Error::::NotAnOperator.into()) } Ok(()) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 08cff321..34410afe 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -190,7 +190,7 @@ impl Pallet { Preservation::Expendable, ) .is_ok(), - Asset::Erc20(asset_address) => { + Asset::Erc20(asset_address) => if let Some(evm_addr) = evm_address { if let Ok((success, _weight)) = Self::erc20_transfer( asset_address, @@ -204,8 +204,7 @@ impl Pallet { } } else { false - } - }, + }, } } else { true diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 74231224..32dbc36a 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -21,34 +21,28 @@ use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, SequentialPhragmen, }; -use frame_support::pallet_prelude::Hooks; -use frame_support::pallet_prelude::Weight; -use frame_support::PalletId; use frame_support::{ - construct_runtime, derive_impl, parameter_types, + construct_runtime, derive_impl, + pallet_prelude::{Hooks, Weight}, + parameter_types, traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, + PalletId, }; use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; -use parity_scale_codec::Decode; -use parity_scale_codec::Encode; -use parity_scale_codec::MaxEncodedLen; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use serde_json::json; use sp_core::{sr25519, H160}; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; -use sp_runtime::traits::ConstU64; use sp_runtime::{ testing::UintAuthorityId, - traits::{ConvertInto, IdentityLookup}, + traits::{ConstU64, ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; -use tangle_primitives::services::EvmAddressMapping; -use tangle_primitives::services::EvmGasWeightMapping; -use tangle_primitives::services::EvmRunner; -use tangle_primitives::services::RunnerError; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner, RunnerError}; use core::ops::Mul; use std::{collections::BTreeMap, sync::Arc}; @@ -655,11 +649,10 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => { + (left_val, right_val) => if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - } - }, + }, }; } } diff --git a/pallets/multi-asset-delegation/src/mock_evm.rs b/pallets/multi-asset-delegation/src/mock_evm.rs index 17ba9132..86325eff 100644 --- a/pallets/multi-asset-delegation/src/mock_evm.rs +++ b/pallets/multi-asset-delegation/src/mock_evm.rs @@ -35,8 +35,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionValidityError}, ConsensusEngineId, }; -use tangle_primitives::services::EvmRunner; -use tangle_primitives::services::RunnerError; +use tangle_primitives::services::{EvmRunner, RunnerError}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; @@ -166,7 +165,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet multi_asset_delegation account free to use if who == &pallet_multi_asset_delegation_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation as OnChargeEVMTransaction< @@ -184,7 +183,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet multi_asset_delegation account free to use if who == &pallet_multi_asset_delegation_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation as OnChargeEVMTransaction< @@ -270,9 +269,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -282,9 +280,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), _ => None, } } diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 34cba929..27ed16a1 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -19,7 +19,6 @@ use crate::{ CurrentRound, Error, }; use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::Bob; use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve}; use sp_runtime::Percent; use tangle_primitives::services::Asset; @@ -303,8 +302,8 @@ fn schedule_operator_unstake_success() { // Verify remaining stake is above minimum assert!( - operator_info.stake.saturating_sub(unstake_amount) - >= MinOperatorBondAmount::get().into() + operator_info.stake.saturating_sub(unstake_amount) >= + MinOperatorBondAmount::get().into() ); // Verify event @@ -362,7 +361,8 @@ fn schedule_operator_unstake_not_an_operator() { // let unstake_amount = 5_000; // // Join operator first -// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(Alice.to_account_id()), bond_amount)); +// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(Alice. +// to_account_id()), bond_amount)); // // Manually set the operator's delegation count to simulate active services // Operators::::mutate(1, |operator| { @@ -373,7 +373,8 @@ fn schedule_operator_unstake_not_an_operator() { // // Attempt to schedule unstake with active services // assert_noop!( -// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), +// +// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), // unstake_amount), Error::::ActiveServicesUsingTNT // ); // }); diff --git a/pallets/services/rpc/src/lib.rs b/pallets/services/rpc/src/lib.rs index ce67fb1b..e25f3c23 100644 --- a/pallets/services/rpc/src/lib.rs +++ b/pallets/services/rpc/src/lib.rs @@ -113,12 +113,10 @@ impl From for i32 { fn custom_error_into_rpc_err(err: Error) -> ErrorObjectOwned { match err { - Error::RuntimeError(e) => { - ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))) - }, - Error::DecodeError => { - ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")) - }, + Error::RuntimeError(e) => + ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))), + Error::DecodeError => + ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")), Error::CustomDispatchError(msg) => ErrorObject::owned(3, "Dispatch error", Some(msg)), } } diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index 5080ebe2..4fd786b7 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -77,9 +77,8 @@ impl Pallet { pub fn mbsm_address_of(blueprint: &ServiceBlueprint) -> Result> { match blueprint.master_manager_revision { MasterBlueprintServiceManagerRevision::Specific(rev) => Self::mbsm_address(rev), - MasterBlueprintServiceManagerRevision::Latest => { - Self::mbsm_address(Self::mbsm_latest_revision()) - }, + MasterBlueprintServiceManagerRevision::Latest => + Self::mbsm_address(Self::mbsm_latest_revision()), other => unimplemented!("Got unexpected case for {:?}", other), } } diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index 7a8d82c3..06677d2f 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -1071,9 +1071,8 @@ pub mod module { .operators_with_approval_state .into_iter() .filter_map(|(v, state)| match state { - ApprovalState::Approved { restaking_percent } => { - Some((v, restaking_percent)) - }, + ApprovalState::Approved { restaking_percent } => + Some((v, restaking_percent)), // N.B: this should not happen, as all operators are approved and checked // above. _ => None, diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 7f161aef..3ba4c7c3 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -275,7 +275,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false; + return false } true } @@ -775,11 +775,10 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => { + (left_val, right_val) => if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - } - }, + }, }; } } diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index 02bc329c..46b7ea04 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -163,7 +163,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation as OnChargeEVMTransaction< @@ -180,7 +180,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation as OnChargeEVMTransaction< @@ -266,9 +266,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -278,9 +277,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), _ => None, } } diff --git a/pallets/services/src/tests.rs b/pallets/services/src/tests.rs index 7a35b33c..0a4796ca 100644 --- a/pallets/services/src/tests.rs +++ b/pallets/services/src/tests.rs @@ -59,9 +59,8 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => { - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } - }, + MachineKind::Small => + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, } } diff --git a/pallets/tangle-lst/src/lib.rs b/pallets/tangle-lst/src/lib.rs index b439669f..028e5c54 100644 --- a/pallets/tangle-lst/src/lib.rs +++ b/pallets/tangle-lst/src/lib.rs @@ -844,7 +844,7 @@ pub mod pallet { let pool_id = member.get_by_pool_id(current_era, pool_id); if pool_id.is_none() { - return Err(Error::::PoolNotFound.into()); + return Err(Error::::PoolNotFound.into()) } // checked above @@ -1506,7 +1506,7 @@ impl Pallet { let balance = T::U256ToBalance::convert; if current_balance.is_zero() || current_points.is_zero() || points.is_zero() { // There is nothing to unbond - return Zero::zero(); + return Zero::zero() } // Equivalent of (current_balance / current_points) * points @@ -1614,9 +1614,8 @@ impl Pallet { bonded_pool.ok_to_join()?; let (_points_issued, bonded) = match extra { - BondExtra::FreeBalance(amount) => { - (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount) - }, + BondExtra::FreeBalance(amount) => + (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount), }; bonded_pool.ok_to_be_open()?; @@ -1682,7 +1681,7 @@ impl Pallet { let min_balance = T::Currency::minimum_balance(); if pre_frozen_balance == min_balance { - return Err(Error::::NothingToAdjust.into()); + return Err(Error::::NothingToAdjust.into()) } // Update frozen amount with current ED. diff --git a/pallets/tangle-lst/src/types/bonded_pool.rs b/pallets/tangle-lst/src/types/bonded_pool.rs index bca83493..bcddfb94 100644 --- a/pallets/tangle-lst/src/types/bonded_pool.rs +++ b/pallets/tangle-lst/src/types/bonded_pool.rs @@ -160,8 +160,8 @@ impl BondedPool { } pub fn can_nominate(&self, who: &T::AccountId) -> bool { - self.is_root(who) - || self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) + self.is_root(who) || + self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) } pub fn can_kick(&self, who: &T::AccountId) -> bool { @@ -262,9 +262,9 @@ impl BondedPool { // any unbond must comply with the balance condition: ensure!( - is_full_unbond - || balance_after_unbond - >= if is_depositor { + is_full_unbond || + balance_after_unbond >= + if is_depositor { Pallet::::depositor_min_bond() } else { MinJoinBond::::get() @@ -296,7 +296,7 @@ impl BondedPool { }, (false, true) => { // the depositor can simply not be unbonded permissionlessly, period. - return Err(Error::::DoesNotHavePermission.into()); + return Err(Error::::DoesNotHavePermission.into()) }, }; diff --git a/pallets/tangle-lst/src/types/commission.rs b/pallets/tangle-lst/src/types/commission.rs index 9fbee755..01ecdd0e 100644 --- a/pallets/tangle-lst/src/types/commission.rs +++ b/pallets/tangle-lst/src/types/commission.rs @@ -55,13 +55,13 @@ impl Commission { // do not throttle if `to` is the same or a decrease in commission. if *to <= commission_as_percent { - return false; + return false } // Test for `max_increase` throttling. // // Throttled if the attempted increase in commission is greater than `max_increase`. if (*to).saturating_sub(commission_as_percent) > t.max_increase { - return true; + return true } // Test for `min_delay` throttling. @@ -84,7 +84,7 @@ impl Commission { blocks_surpassed < t.min_delay } }, - ); + ) } false } @@ -145,7 +145,7 @@ impl Commission { ); if let Some(old) = self.max.as_mut() { if new_max > *old { - return Err(Error::::MaxCommissionRestricted.into()); + return Err(Error::::MaxCommissionRestricted.into()) } *old = new_max; } else { diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index 91a07416..fae8c1d3 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -127,7 +127,7 @@ where fn discriminant(address: H160, gas: u64) -> DiscriminantResult> { let extra_cost = RuntimeHelper::::db_read_gas_cost(); if gas < extra_cost { - return DiscriminantResult::OutOfGas; + return DiscriminantResult::OutOfGas } let asset_id = match Runtime::address_to_asset_id(address) { @@ -254,8 +254,8 @@ where handle.record_db_read::(136)?; // If previous approval exists, we need to clean it - if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) - != 0u32.into() + if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) != + 0u32.into() { RuntimeHelper::::try_dispatch( handle, diff --git a/precompiles/assets-erc20/src/tests.rs b/precompiles/assets-erc20/src/tests.rs index 7152d4c4..05d48cf8 100644 --- a/precompiles/assets-erc20/src/tests.rs +++ b/precompiles/assets-erc20/src/tests.rs @@ -441,8 +441,8 @@ fn transfer_not_enough_founds() { ForeignPCall::transfer { to: Address(Charlie.into()), value: 50.into() }, ) .execute_reverts(|output| { - from_utf8(output).unwrap().contains("Dispatched call failed with error: ") - && from_utf8(output).unwrap().contains("BalanceLow") + from_utf8(output).unwrap().contains("Dispatched call failed with error: ") && + from_utf8(output).unwrap().contains("BalanceLow") }); }); } diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index aa3a6b4f..8c05ca46 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -437,7 +437,7 @@ where fn deposit(handle: &mut impl PrecompileHandle) -> EvmResult { // Deposit only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()); + return Err(RevertReason::UnknownSelector.into()) } let caller: Runtime::AccountId = @@ -446,7 +446,7 @@ where let amount = Self::u256_to_amount(handle.context().apparent_value)?; if amount.into() == U256::from(0u32) { - return Err(revert("deposited amount must be non-zero")); + return Err(revert("deposited amount must be non-zero")) } handle.record_log_costs_manual(2, 32)?; @@ -476,7 +476,7 @@ where fn withdraw(handle: &mut impl PrecompileHandle, value: U256) -> EvmResult { // Withdraw only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()); + return Err(RevertReason::UnknownSelector.into()) } handle.record_log_costs_manual(2, 32)?; @@ -488,7 +488,7 @@ where }; if value > account_amount { - return Err(revert("Trying to withdraw more than owned")); + return Err(revert("Trying to withdraw more than owned")) } log2( @@ -548,7 +548,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/balances-erc20/src/tests.rs b/precompiles/balances-erc20/src/tests.rs index 6e176e80..f62c1a4d 100644 --- a/precompiles/balances-erc20/src/tests.rs +++ b/precompiles/balances-erc20/src/tests.rs @@ -306,8 +306,8 @@ fn transfer_not_enough_funds() { PCall::transfer { to: Address(Bob.into()), value: 1400.into() }, ) .execute_reverts(|output| { - from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") - && from_utf8(&output).unwrap().contains("FundsUnavailable") + from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") && + from_utf8(&output).unwrap().contains("FundsUnavailable") }); }); } diff --git a/precompiles/batch/src/lib.rs b/precompiles/batch/src/lib.rs index d26ac2ba..943216e3 100644 --- a/precompiles/batch/src/lib.rs +++ b/precompiles/batch/src/lib.rs @@ -146,9 +146,8 @@ where let forwarded_gas = match (remaining_gas.checked_sub(log_cost), mode) { (Some(remaining), _) => remaining, - (None, Mode::BatchAll) => { - return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) - }, + (None, Mode::BatchAll) => + return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), (None, _) => return Ok(()), }; @@ -163,11 +162,10 @@ where log.record(handle)?; match mode { - Mode::BatchAll => { + Mode::BatchAll => return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }) - }, + }), Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -184,11 +182,10 @@ where log.record(handle)?; match mode { - Mode::BatchAll => { + Mode::BatchAll => return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }) - }, + }), Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -219,23 +216,19 @@ where // How to proceed match (mode, reason) { // _: Fatal is always fatal - (_, ExitReason::Fatal(exit_status)) => { - return Err(PrecompileFailure::Fatal { exit_status }) - }, + (_, ExitReason::Fatal(exit_status)) => + return Err(PrecompileFailure::Fatal { exit_status }), // BatchAll : Reverts and errors are immediatly forwarded. - (Mode::BatchAll, ExitReason::Revert(exit_status)) => { - return Err(PrecompileFailure::Revert { exit_status, output }) - }, - (Mode::BatchAll, ExitReason::Error(exit_status)) => { - return Err(PrecompileFailure::Error { exit_status }) - }, + (Mode::BatchAll, ExitReason::Revert(exit_status)) => + return Err(PrecompileFailure::Revert { exit_status, output }), + (Mode::BatchAll, ExitReason::Error(exit_status)) => + return Err(PrecompileFailure::Error { exit_status }), // BatchSomeUntilFailure : Reverts and errors prevent subsequent subcalls to // be executed but the precompile still succeed. - (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => { - return Ok(()) - }, + (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => + return Ok(()), // Success or ignored revert/error. (_, _) => (), @@ -270,9 +263,8 @@ where match mode { Mode::BatchSome => Self::batch_some { to, value, call_data, gas_limit }, - Mode::BatchSomeUntilFailure => { - Self::batch_some_until_failure { to, value, call_data, gas_limit } - }, + Mode::BatchSomeUntilFailure => + Self::batch_some_until_failure { to, value, call_data, gas_limit }, Mode::BatchAll => Self::batch_all { to, value, call_data, gas_limit }, } } diff --git a/precompiles/call-permit/src/lib.rs b/precompiles/call-permit/src/lib.rs index ea1906ba..0f5df485 100644 --- a/precompiles/call-permit/src/lib.rs +++ b/precompiles/call-permit/src/lib.rs @@ -170,7 +170,7 @@ where .ok_or_else(|| revert("Call require too much gas (uint64 overflow)"))?; if total_cost > handle.remaining_gas() { - return Err(revert("Gaslimit is too low to dispatch provided call")); + return Err(revert("Gaslimit is too low to dispatch provided call")) } // VERIFY PERMIT @@ -216,9 +216,8 @@ where match reason { ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(_) => { - Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }) - }, + ExitReason::Revert(_) => + Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }), ExitReason::Succeed(_) => Ok(output.into()), } } diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index b8d54921..21707fef 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -82,7 +82,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; @@ -266,9 +266,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; // Get origin account. @@ -307,9 +306,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; let call = pallet_multi_asset_delegation::Call::::schedule_withdraw { @@ -351,9 +349,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; // Build call with origin. @@ -396,9 +393,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; // Build call with origin. @@ -435,9 +431,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; // Build call with origin. @@ -484,9 +479,8 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; // Build call with origin. diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index c6ed8d64..2c7d6533 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -432,8 +432,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Inactive + MultiAssetDelegation::operator_info(operator_account).unwrap().status == + OperatorStatus::Inactive ); PrecompilesValue::get() @@ -441,8 +441,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Active + MultiAssetDelegation::operator_info(operator_account).unwrap().status == + OperatorStatus::Active ); assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); diff --git a/precompiles/pallet-democracy/src/lib.rs b/precompiles/pallet-democracy/src/lib.rs index ca29013f..7371074c 100644 --- a/precompiles/pallet-democracy/src/lib.rs +++ b/precompiles/pallet-democracy/src/lib.rs @@ -467,7 +467,7 @@ where if !<::Preimages as QueryPreimage>::is_requested( &proposal_hash, ) { - return Err(revert("not imminent preimage (preimage not requested)")); + return Err(revert("not imminent preimage (preimage not requested)")) }; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); diff --git a/precompiles/pallet-democracy/src/tests.rs b/precompiles/pallet-democracy/src/tests.rs index 697eae1b..9fdb6a6f 100644 --- a/precompiles/pallet-democracy/src/tests.rs +++ b/precompiles/pallet-democracy/src/tests.rs @@ -220,9 +220,8 @@ fn lowest_unbaked_non_zero() { .dispatch(RuntimeOrigin::signed(Alice.into()))); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -244,9 +243,9 @@ fn lowest_unbaked_non_zero() { // Run it through until it is baked roll_to( - ::VotingPeriod::get() - + ::LaunchPeriod::get() - + 1000, + ::VotingPeriod::get() + + ::LaunchPeriod::get() + + 1000, ); precompiles() @@ -559,9 +558,8 @@ fn standard_vote_aye_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -644,9 +642,8 @@ fn standard_vote_nay_conviction_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -724,9 +721,8 @@ fn remove_vote_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; @@ -797,9 +793,8 @@ fn delegate_works() { ); let alice_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Delegating { balance, target, conviction, delegations, prior } => { - (balance, target, conviction, delegations, prior) - }, + Voting::Delegating { balance, target, conviction, delegations, prior } => + (balance, target, conviction, delegations, prior), _ => panic!("Votes are not delegating"), }; @@ -812,9 +807,8 @@ fn delegate_works() { let bob_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Bob)) { - Voting::Direct { votes, delegations, prior } => { - (votes.into_inner(), delegations, prior) - }, + Voting::Direct { votes, delegations, prior } => + (votes.into_inner(), delegations, prior), _ => panic!("Votes are not direct"), }; diff --git a/precompiles/precompile-registry/src/lib.rs b/precompiles/precompile-registry/src/lib.rs index 15e94ee0..554e1cd6 100644 --- a/precompiles/precompile-registry/src/lib.rs +++ b/precompiles/precompile-registry/src/lib.rs @@ -69,9 +69,8 @@ where .is_active_precompile(address.0, handle.remaining_gas()) { IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile), - IsPrecompileResult::OutOfGas => { - Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) - }, + IsPrecompileResult::OutOfGas => + Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), } } @@ -86,7 +85,7 @@ where // Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15) handle.record_db_read::(175)?; if !is_precompile_or_fail::(address.0, handle.remaining_gas())? { - return Err(revert("provided address is not a precompile")); + return Err(revert("provided address is not a precompile")) } // pallet_evm::create_account read storage item pallet_evm::AccountCodes diff --git a/precompiles/proxy/src/lib.rs b/precompiles/proxy/src/lib.rs index 8cf81816..92e27d5a 100644 --- a/precompiles/proxy/src/lib.rs +++ b/precompiles/proxy/src/lib.rs @@ -60,9 +60,8 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => { - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) - }, + Some(selector) => + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector), } } @@ -92,12 +91,11 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => { - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) - || ProxyPrecompileCall::::proxy_selectors().contains(&selector) - || ProxyPrecompileCall::::proxy_force_type_selectors() - .contains(&selector) - }, + Some(selector) => + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) || + ProxyPrecompileCall::::proxy_selectors().contains(&selector) || + ProxyPrecompileCall::::proxy_force_type_selectors() + .contains(&selector), } } @@ -187,7 +185,7 @@ where .iter() .any(|pd| pd.delegate == delegate) { - return Err(revert("Cannot add more than one proxy")); + return Err(revert("Cannot add more than one proxy")) } let delegate: ::Source = @@ -343,7 +341,7 @@ where // Check that we only perform proxy calls on behalf of externally owned accounts let AddressType::EOA = precompile_set::get_address_type::(handle, real.into())? else { - return Err(revert("real address must be EOA")); + return Err(revert("real address must be EOA")) }; // Read proxy @@ -419,9 +417,8 @@ where // Return subcall result match reason { ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(exit_status) => { - Err(PrecompileFailure::Revert { exit_status, output }) - }, + ExitReason::Revert(exit_status) => + Err(PrecompileFailure::Revert { exit_status, output }), ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Succeed(_) => Ok(()), } diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 7739a240..d9a3bea4 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -206,19 +206,18 @@ where (0, zero_address) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)) } (Asset::Erc20(erc20_token.into()), amount) }, (other_asset_id, zero_address) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)) } (Asset::Custom(other_asset_id.into()), amount) }, - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) - }, + (_other_asset_id, _erc20_token) => + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), }; let call = pallet_services::Call::::request { diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 7ab17b0b..76677de7 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -407,7 +407,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false; + return false } true } diff --git a/precompiles/services/src/mock_evm.rs b/precompiles/services/src/mock_evm.rs index cd0ccbcf..c3bdf41b 100644 --- a/precompiles/services/src/mock_evm.rs +++ b/precompiles/services/src/mock_evm.rs @@ -151,7 +151,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation as OnChargeEVMTransaction< @@ -168,7 +168,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation as OnChargeEVMTransaction< @@ -254,9 +254,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -266,9 +265,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), _ => None, } } diff --git a/precompiles/services/src/tests.rs b/precompiles/services/src/tests.rs index 43a0aa01..0cde095d 100644 --- a/precompiles/services/src/tests.rs +++ b/precompiles/services/src/tests.rs @@ -45,9 +45,8 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => { - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } - }, + MachineKind::Small => + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, } } diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index aa08dbe3..1ab81ec6 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -78,7 +78,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index b49fdc01..cabd6dd6 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -344,7 +344,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; diff --git a/precompiles/verify-bls381-signature/src/lib.rs b/precompiles/verify-bls381-signature/src/lib.rs index 08e14fd2..13695778 100644 --- a/precompiles/verify-bls381-signature/src/lib.rs +++ b/precompiles/verify-bls381-signature/src/lib.rs @@ -55,14 +55,14 @@ impl Bls381Precompile { { p_key } else { - return Ok(false); + return Ok(false) }; let signature = if let Ok(sig) = snowbridge_milagro_bls::Signature::from_bytes(&signature_bytes) { sig } else { - return Ok(false); + return Ok(false) }; let is_confirmed = signature.verify(&message, &public_key); diff --git a/precompiles/verify-schnorr-signatures/src/lib.rs b/precompiles/verify-schnorr-signatures/src/lib.rs index 19b5636b..24246325 100644 --- a/precompiles/verify-schnorr-signatures/src/lib.rs +++ b/precompiles/verify-schnorr-signatures/src/lib.rs @@ -55,7 +55,7 @@ pub fn to_slice_32(val: &[u8]) -> Option<[u8; 32]> { let mut key = [0u8; 32]; key[..32].copy_from_slice(val); - return Some(key); + return Some(key) } None } diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index d4c48406..173396a5 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -79,7 +79,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); + return Err(revert("Error while parsing staker's address")) }, }; @@ -153,7 +153,7 @@ where match pallet_vesting::Vesting::::get(origin.clone()) { Some(schedules) => { if index >= schedules.len() as u8 { - return Err(revert("Invalid vesting schedule index")); + return Err(revert("Invalid vesting schedule index")) } // Make the call to transfer the vested funds to the `target` account. let target = Self::convert_to_account_id(target)?; diff --git a/primitives/rpc/evm-tracing-events/src/evm.rs b/primitives/rpc/evm-tracing-events/src/evm.rs index 2b997eae..688861fd 100644 --- a/primitives/rpc/evm-tracing-events/src/evm.rs +++ b/primitives/rpc/evm-tracing-events/src/evm.rs @@ -61,9 +61,8 @@ impl From for CreateScheme { fn from(i: evm_runtime::CreateScheme) -> Self { match i { evm_runtime::CreateScheme::Legacy { caller } => Self::Legacy { caller }, - evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => { - Self::Create2 { caller, code_hash, salt } - }, + evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => + Self::Create2 { caller, code_hash, salt }, evm_runtime::CreateScheme::Fixed(address) => Self::Fixed(address), } } @@ -167,15 +166,12 @@ impl<'a> From> for EvmEvent { init_code: init_code.to_vec(), target_gas, }, - evm::tracing::Event::Suicide { address, target, balance } => { - Self::Suicide { address, target, balance } - }, - evm::tracing::Event::Exit { reason, return_value } => { - Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() } - }, - evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => { - Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit } - }, + evm::tracing::Event::Suicide { address, target, balance } => + Self::Suicide { address, target, balance }, + evm::tracing::Event::Exit { reason, return_value } => + Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() }, + evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => + Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit }, evm::tracing::Event::TransactCreate { caller, value, diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index 85d8352b..d1fbb453 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -59,15 +59,12 @@ pub enum GasometerEvent { impl From for GasometerEvent { fn from(i: evm_gasometer::tracing::Event) -> Self { match i { - evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => { - Self::RecordCost { cost, snapshot: snapshot.into() } - }, - evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => { - Self::RecordRefund { refund, snapshot: snapshot.into() } - }, - evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => { - Self::RecordStipend { stipend, snapshot: snapshot.into() } - }, + evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => + Self::RecordCost { cost, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => + Self::RecordRefund { refund, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => + Self::RecordStipend { stipend, snapshot: snapshot.into() }, evm_gasometer::tracing::Event::RecordDynamicCost { gas_cost, memory_gas, @@ -79,9 +76,8 @@ impl From for GasometerEvent { gas_refund, snapshot: snapshot.into(), }, - evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => { - Self::RecordTransaction { cost, snapshot: snapshot.into() } - }, + evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => + Self::RecordTransaction { cost, snapshot: snapshot.into() }, } } } diff --git a/primitives/rpc/evm-tracing-events/src/runtime.rs b/primitives/rpc/evm-tracing-events/src/runtime.rs index 089932d5..ad738f73 100644 --- a/primitives/rpc/evm-tracing-events/src/runtime.rs +++ b/primitives/rpc/evm-tracing-events/src/runtime.rs @@ -92,7 +92,7 @@ impl RuntimeEvent { filter: crate::StepEventFilter, ) -> Self { match i { - evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => { + evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => Self::Step { context: context.clone().into(), opcode: opcodes_string(opcode), @@ -102,8 +102,7 @@ impl RuntimeEvent { }, stack: if filter.enable_stack { Some(stack.into()) } else { None }, memory: if filter.enable_memory { Some(memory.into()) } else { None }, - } - }, + }, evm_runtime::tracing::Event::StepResult { result, return_value } => Self::StepResult { result: match result { Ok(_) => Ok(()), @@ -114,12 +113,10 @@ impl RuntimeEvent { }, return_value: return_value.to_vec(), }, - evm_runtime::tracing::Event::SLoad { address, index, value } => { - Self::SLoad { address, index, value } - }, - evm_runtime::tracing::Event::SStore { address, index, value } => { - Self::SStore { address, index, value } - }, + evm_runtime::tracing::Event::SLoad { address, index, value } => + Self::SLoad { address, index, value }, + evm_runtime::tracing::Event::SStore { address, index, value } => + Self::SStore { address, index, value }, } } } diff --git a/primitives/src/chain_identifier.rs b/primitives/src/chain_identifier.rs index 72155a8a..d916c2a2 100644 --- a/primitives/src/chain_identifier.rs +++ b/primitives/src/chain_identifier.rs @@ -65,14 +65,14 @@ impl TypedChainId { #[must_use] pub const fn underlying_chain_id(&self) -> u32 { match self { - TypedChainId::Evm(id) - | TypedChainId::Substrate(id) - | TypedChainId::PolkadotParachain(id) - | TypedChainId::KusamaParachain(id) - | TypedChainId::RococoParachain(id) - | TypedChainId::Cosmos(id) - | TypedChainId::Solana(id) - | TypedChainId::Ink(id) => *id, + TypedChainId::Evm(id) | + TypedChainId::Substrate(id) | + TypedChainId::PolkadotParachain(id) | + TypedChainId::KusamaParachain(id) | + TypedChainId::RococoParachain(id) | + TypedChainId::Cosmos(id) | + TypedChainId::Solana(id) | + TypedChainId::Ink(id) => *id, Self::None => 0, } } diff --git a/primitives/src/services/field.rs b/primitives/src/services/field.rs index c03869aa..8fd27a35 100644 --- a/primitives/src/services/field.rs +++ b/primitives/src/services/field.rs @@ -172,13 +172,13 @@ impl PartialEq for Field { (Self::AccountId(l0), Self::AccountId(r0)) => l0 == r0, (Self::Struct(l_name, l_fields), Self::Struct(r_name, r_fields)) => { if l_name != r_name || l_fields.len() != r_fields.len() { - return false; + return false } for ((l_field_name, l_field_value), (r_field_name, r_field_value)) in l_fields.iter().zip(r_fields.iter()) { if l_field_name != r_field_name || l_field_value != r_field_value { - return false; + return false } } true @@ -307,18 +307,16 @@ impl PartialEq for Field { (Self::Int64(_), FieldType::Int64) => true, (Self::String(_), FieldType::String) => true, (Self::Bytes(_), FieldType::Bytes) => true, - (Self::Array(a), FieldType::Array(len, b)) => { - a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())) - }, + (Self::Array(a), FieldType::Array(len, b)) => + a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())), (Self::List(a), FieldType::List(b)) => a.iter().all(|f| f.eq(b.as_ref())), (Self::AccountId(_), FieldType::AccountId) => true, - (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => { - fields_a.into_iter().len() == fields_b.into_iter().len() - && fields_a + (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => + fields_a.into_iter().len() == fields_b.into_iter().len() && + fields_a .into_iter() .zip(fields_b) - .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)) - }, + .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)), _ => false, } } @@ -422,7 +420,7 @@ impl Field { /// Encode the fields to ethabi bytes. pub fn encode_to_ethabi(fields: &[Self]) -> ethabi::Bytes { if fields.is_empty() { - return Default::default(); + return Default::default() } let tokens: Vec = fields.iter().map(Self::to_ethabi_token).collect(); ethabi::encode(&tokens) diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index ee4138bf..80c9e9fc 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -148,7 +148,7 @@ pub fn type_checker( return Err(TypeCheckError::NotEnoughArguments { expected: params.len() as u8, actual: args.len() as u8, - }); + }) } for i in 0..args.len() { let arg = &args[i]; @@ -158,7 +158,7 @@ pub fn type_checker( index: i as u8, expected: expected.clone(), actual: arg.clone().into(), - }); + }) } } Ok(()) @@ -472,12 +472,10 @@ impl ServiceBlueprint { }, // Master Manager Revision match self.master_manager_revision { - MasterBlueprintServiceManagerRevision::Latest => { - ethabi::Token::Uint(ethabi::Uint::MAX) - }, - MasterBlueprintServiceManagerRevision::Specific(rev) => { - ethabi::Token::Uint(rev.into()) - }, + MasterBlueprintServiceManagerRevision::Latest => + ethabi::Token::Uint(ethabi::Uint::MAX), + MasterBlueprintServiceManagerRevision::Specific(rev) => + ethabi::Token::Uint(rev.into()), }, // Gadget ? ]) diff --git a/primitives/src/verifier/circom.rs b/primitives/src/verifier/circom.rs index 4dbf7303..34251912 100644 --- a/primitives/src/verifier/circom.rs +++ b/primitives/src/verifier/circom.rs @@ -51,28 +51,28 @@ impl super::InstanceVerifier for CircomVerifierGroth16Bn254 { Ok(v) => v, Err(e) => { log::error!("Failed to convert public input bytes to field elements: {e:?}",); - return Err(e); + return Err(e) }, }; let vk = match ArkVerifyingKey::deserialize_compressed(vk_bytes) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize verifying key: {e:?}"); - return Err(e.into()); + return Err(e.into()) }, }; let proof = match Proof::decode(proof_bytes).and_then(|v| v.try_into()) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize proof: {e:?}"); - return Err(e); + return Err(e) }, }; let res = match verify_groth16(&vk, &public_input_field_elts, &proof) { Ok(v) => v, Err(e) => { log::error!("Failed to verify proof: {e:?}"); - return Err(e); + return Err(e) }, }; @@ -246,7 +246,7 @@ fn point_to_u256(point: F) -> Result { let point = point.into_bigint(); let point_bytes = point.to_bytes_be(); if point_bytes.len() != 32 { - return Err(CircomError::InvalidProofBytes.into()); + return Err(CircomError::InvalidProofBytes.into()) } Ok(U256::from(&point_bytes[..])) } diff --git a/runtime/mainnet/src/filters.rs b/runtime/mainnet/src/filters.rs index 1307096e..de74c9ff 100644 --- a/runtime/mainnet/src/filters.rs +++ b/runtime/mainnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for MainnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true; + return true } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false; + return false } true diff --git a/runtime/mainnet/src/frontier_evm.rs b/runtime/mainnet/src/frontier_evm.rs index 8f135bae..39b31cd1 100644 --- a/runtime/mainnet/src/frontier_evm.rs +++ b/runtime/mainnet/src/frontier_evm.rs @@ -61,7 +61,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) } None } @@ -119,21 +119,20 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { ) -> precompile_utils::EvmResult { Ok(match self { ProxyType::Any => true, - ProxyType::Governance => { - call.value == U256::zero() - && matches!( + ProxyType::Governance => + call.value == U256::zero() && + matches!( PrecompileName::from_address(call.to.0), Some(ref precompile) if is_governance_precompile(precompile) - ) - }, + ), // The proxy precompile does not contain method cancel_proxy ProxyType::CancelProxy => false, ProxyType::Balances => { // Allow only "simple" accounts as recipient (no code nor precompile). // Note: Checking the presence of the code is not enough because some precompiles // have no code. - !recipient_has_code - && !precompile_utils::precompile_set::is_precompile_or_fail::( + !recipient_has_code && + !precompile_utils::precompile_set::is_precompile_or_fail::( call.to.0, gas, )? }, diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index 5db6de9b..dad95a92 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -656,8 +656,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") - % max.saturating_add(1); + .expect("input is padded with zeroes; qed") % + max.saturating_add(1); random as usize }, }; @@ -1148,15 +1148,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) - | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) | + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) - | RuntimeCall::Council(..) - | RuntimeCall::Elections(..) - | RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | + RuntimeCall::Elections(..) | + RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1468,9 +1468,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -1480,11 +1479,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - }, + ))), _ => None, } } diff --git a/runtime/testnet/src/filters.rs b/runtime/testnet/src/filters.rs index d46f0914..65e021b6 100644 --- a/runtime/testnet/src/filters.rs +++ b/runtime/testnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for TestnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true; + return true } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false; + return false } true diff --git a/runtime/testnet/src/frontier_evm.rs b/runtime/testnet/src/frontier_evm.rs index 23fb1f1a..a11fe1f7 100644 --- a/runtime/testnet/src/frontier_evm.rs +++ b/runtime/testnet/src/frontier_evm.rs @@ -64,7 +64,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) } None } @@ -99,7 +99,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None); + return Ok(None) } // fallback to the default implementation > as OnChargeEVMTransaction< @@ -116,7 +116,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn; + return already_withdrawn } // fallback to the default implementation > as OnChargeEVMTransaction< diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 7fb9e15b..1a0974b5 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -663,8 +663,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") - % max.saturating_add(1); + .expect("input is padded with zeroes; qed") % + max.saturating_add(1); random as usize }, }; @@ -1146,15 +1146,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) - | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) | + RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) - | RuntimeCall::Council(..) - | RuntimeCall::Elections(..) - | RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) | + RuntimeCall::Council(..) | + RuntimeCall::Elections(..) | + RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1387,9 +1387,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), _ => None, } } @@ -1399,11 +1398,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - }, + ))), _ => None, } } From 130955cae5d49054140960d75255aa1a0791f753 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:28:09 +0530 Subject: [PATCH 21/63] use stable fmt --- .../evm-tracing/src/formatters/blockscout.rs | 2 +- .../evm-tracing/src/formatters/call_tracer.rs | 37 +++++---- .../src/formatters/trace_filter.rs | 15 ++-- client/evm-tracing/src/listeners/call_list.rs | 71 ++++++++++------- client/evm-tracing/src/listeners/raw.rs | 12 +-- client/evm-tracing/src/types/serialization.rs | 4 +- client/rpc-core/txpool/src/types/content.rs | 15 ++-- client/rpc/debug/src/lib.rs | 78 +++++++++++-------- client/rpc/trace/src/lib.rs | 47 ++++++----- client/rpc/txpool/src/lib.rs | 2 +- frost/frost-ristretto255/src/lib.rs | 5 +- frost/src/keys.rs | 2 +- frost/src/lib.rs | 10 +-- frost/src/round1.rs | 6 +- frost/src/scalar_mul.rs | 6 +- frost/src/signature.rs | 6 +- frost/src/signing_key.rs | 2 +- node/src/distributions/mainnet.rs | 42 +++++----- node/src/manual_seal.rs | 2 +- node/src/service.rs | 8 +- node/src/utils.rs | 2 +- pallets/claims/src/lib.rs | 15 ++-- pallets/claims/src/utils/mod.rs | 5 +- .../src/functions/delegate.rs | 2 +- .../src/functions/deposit.rs | 5 +- pallets/multi-asset-delegation/src/mock.rs | 5 +- .../multi-asset-delegation/src/mock_evm.rs | 14 ++-- .../src/tests/operator.rs | 6 +- pallets/services/rpc/src/lib.rs | 10 ++- pallets/services/src/functions.rs | 5 +- pallets/services/src/lib.rs | 5 +- pallets/services/src/mock.rs | 7 +- pallets/services/src/mock_evm.rs | 14 ++-- pallets/services/src/tests.rs | 5 +- pallets/tangle-lst/src/lib.rs | 11 +-- pallets/tangle-lst/src/types/bonded_pool.rs | 12 +-- pallets/tangle-lst/src/types/commission.rs | 8 +- precompiles/assets-erc20/src/lib.rs | 6 +- precompiles/assets-erc20/src/tests.rs | 4 +- precompiles/balances-erc20/src/lib.rs | 10 +-- precompiles/balances-erc20/src/tests.rs | 4 +- precompiles/batch/src/lib.rs | 40 ++++++---- precompiles/call-permit/src/lib.rs | 7 +- precompiles/multi-asset-delegation/src/lib.rs | 32 ++++---- .../multi-asset-delegation/src/tests.rs | 8 +- precompiles/pallet-democracy/src/lib.rs | 2 +- precompiles/pallet-democracy/src/tests.rs | 36 +++++---- precompiles/precompile-registry/src/lib.rs | 7 +- precompiles/proxy/src/lib.rs | 25 +++--- precompiles/services/src/lib.rs | 9 ++- precompiles/services/src/mock.rs | 2 +- precompiles/services/src/mock_evm.rs | 14 ++-- precompiles/services/src/tests.rs | 5 +- precompiles/staking/src/lib.rs | 2 +- precompiles/tangle-lst/src/lib.rs | 2 +- .../verify-bls381-signature/src/lib.rs | 4 +- .../verify-schnorr-signatures/src/lib.rs | 2 +- precompiles/vesting/src/lib.rs | 4 +- primitives/rpc/evm-tracing-events/src/evm.rs | 20 +++-- .../rpc/evm-tracing-events/src/gasometer.rs | 20 +++-- .../rpc/evm-tracing-events/src/runtime.rs | 15 ++-- primitives/src/chain_identifier.rs | 16 ++-- primitives/src/services/field.rs | 20 ++--- primitives/src/services/mod.rs | 14 ++-- primitives/src/verifier/circom.rs | 10 +-- runtime/mainnet/src/filters.rs | 4 +- runtime/mainnet/src/frontier_evm.rs | 15 ++-- runtime/mainnet/src/lib.rs | 26 ++++--- runtime/testnet/src/filters.rs | 4 +- runtime/testnet/src/frontier_evm.rs | 6 +- runtime/testnet/src/lib.rs | 26 ++++--- 71 files changed, 516 insertions(+), 408 deletions(-) diff --git a/client/evm-tracing/src/formatters/blockscout.rs b/client/evm-tracing/src/formatters/blockscout.rs index 9efe1505..61b8033e 100644 --- a/client/evm-tracing/src/formatters/blockscout.rs +++ b/client/evm-tracing/src/formatters/blockscout.rs @@ -36,7 +36,7 @@ impl super::ResponseFormatter for Formatter { if let Some(entry) = listener.entries.last() { return Some(TransactionTrace::CallList( entry.iter().map(|(_, value)| Call::Blockscout(value.clone())).collect(), - )) + )); } None } diff --git a/client/evm-tracing/src/formatters/call_tracer.rs b/client/evm-tracing/src/formatters/call_tracer.rs index b72ea0c9..6b2d7ae4 100644 --- a/client/evm-tracing/src/formatters/call_tracer.rs +++ b/client/evm-tracing/src/formatters/call_tracer.rs @@ -56,13 +56,14 @@ impl super::ResponseFormatter for Formatter { gas_used, trace_address: Some(trace_address.clone()), inner: match inner.clone() { - BlockscoutCallInner::Call { input, to, res, call_type } => + BlockscoutCallInner::Call { input, to, res, call_type } => { CallTracerInner::Call { call_type: match call_type { CallType::Call => "CALL".as_bytes().to_vec(), CallType::CallCode => "CALLCODE".as_bytes().to_vec(), - CallType::DelegateCall => - "DELEGATECALL".as_bytes().to_vec(), + CallType::DelegateCall => { + "DELEGATECALL".as_bytes().to_vec() + }, CallType::StaticCall => "STATICCALL".as_bytes().to_vec(), }, to, @@ -73,7 +74,8 @@ impl super::ResponseFormatter for Formatter { CallResult::Output { .. } => it.logs.clone(), CallResult::Error { .. } => Vec::new(), }, - }, + } + }, BlockscoutCallInner::Create { init, res } => CallTracerInner::Create { input: init, error: match res { @@ -87,19 +89,21 @@ impl super::ResponseFormatter for Formatter { CreateResult::Error { .. } => None, }, output: match res { - CreateResult::Success { created_contract_code, .. } => - Some(created_contract_code), + CreateResult::Success { created_contract_code, .. } => { + Some(created_contract_code) + }, CreateResult::Error { .. } => None, }, value, call_type: "CREATE".as_bytes().to_vec(), }, - BlockscoutCallInner::SelfDestruct { balance, to } => + BlockscoutCallInner::SelfDestruct { balance, to } => { CallTracerInner::SelfDestruct { value: balance, to, call_type: "SELFDESTRUCT".as_bytes().to_vec(), - }, + } + }, }, calls: Vec::new(), }) @@ -161,11 +165,11 @@ impl super::ResponseFormatter for Formatter { let sibling_greater_than = |a: &Vec, b: &Vec| -> bool { for (i, a_value) in a.iter().enumerate() { if a_value > &b[i] { - return true + return true; } else if a_value < &b[i] { - return false + return false; } else { - continue + continue; } } false @@ -189,10 +193,11 @@ impl super::ResponseFormatter for Formatter { ( Call::CallTracer(CallTracerCall { trace_address: Some(a), .. }), Call::CallTracer(CallTracerCall { trace_address: Some(b), .. }), - ) => - &b[..] == - a.get(0..a.len() - 1) - .expect("non-root element while traversing trace result"), + ) => { + &b[..] + == a.get(0..a.len() - 1) + .expect("non-root element while traversing trace result") + }, _ => unreachable!(), }) { // Remove `trace_address` from result. @@ -223,7 +228,7 @@ impl super::ResponseFormatter for Formatter { } } if traces.is_empty() { - return None + return None; } Some(traces) } diff --git a/client/evm-tracing/src/formatters/trace_filter.rs b/client/evm-tracing/src/formatters/trace_filter.rs index f8844c8f..9bb03210 100644 --- a/client/evm-tracing/src/formatters/trace_filter.rs +++ b/client/evm-tracing/src/formatters/trace_filter.rs @@ -56,11 +56,12 @@ impl super::ResponseFormatter for Formatter { // Can't be known here, must be inserted upstream. block_number: 0, output: match res { - CallResult::Output(output) => + CallResult::Output(output) => { TransactionTraceOutput::Result(TransactionTraceResult::Call { gas_used: trace.gas_used, output, - }), + }) + }, CallResult::Error(error) => TransactionTraceOutput::Error(error), }, subtraces: trace.subtraces, @@ -86,14 +87,16 @@ impl super::ResponseFormatter for Formatter { CreateResult::Success { created_contract_address_hash, created_contract_code, - } => + } => { TransactionTraceOutput::Result(TransactionTraceResult::Create { gas_used: trace.gas_used, code: created_contract_code, address: created_contract_address_hash, - }), - CreateResult::Error { error } => - TransactionTraceOutput::Error(error), + }) + }, + CreateResult::Error { error } => { + TransactionTraceOutput::Error(error) + }, }, subtraces: trace.subtraces, trace_address: trace.trace_address.clone(), diff --git a/client/evm-tracing/src/listeners/call_list.rs b/client/evm-tracing/src/listeners/call_list.rs index 5ca1eb15..9da8a66a 100644 --- a/client/evm-tracing/src/listeners/call_list.rs +++ b/client/evm-tracing/src/listeners/call_list.rs @@ -224,9 +224,9 @@ impl Listener { pub fn gasometer_event(&mut self, event: GasometerEvent) { match event { - GasometerEvent::RecordCost { snapshot, .. } | - GasometerEvent::RecordDynamicCost { snapshot, .. } | - GasometerEvent::RecordStipend { snapshot, .. } => { + GasometerEvent::RecordCost { snapshot, .. } + | GasometerEvent::RecordDynamicCost { snapshot, .. } + | GasometerEvent::RecordStipend { snapshot, .. } => { if let Some(context) = self.context_stack.last_mut() { if context.start_gas.is_none() { context.start_gas = Some(snapshot.gas()); @@ -497,12 +497,13 @@ impl Listener { // behavior (like batch precompile does) thus we simply consider this a call. self.call_type = Some(CallType::Call); }, - EvmEvent::Log { address, topics, data } => + EvmEvent::Log { address, topics, data } => { if self.with_log { if let Some(stack) = self.context_stack.last_mut() { stack.logs.push(Log { address, topics, data }); } - }, + } + }, // We ignore other kinds of message if any (new ones may be added in the future). #[allow(unreachable_patterns)] @@ -536,13 +537,15 @@ impl Listener { match context.context_type { ContextType::Call(call_type) => { let res = match &reason { - ExitReason::Succeed(ExitSucceed::Returned) => - CallResult::Output(return_value.to_vec()), + ExitReason::Succeed(ExitSucceed::Returned) => { + CallResult::Output(return_value.to_vec()) + }, ExitReason::Succeed(_) => CallResult::Output(vec![]), ExitReason::Error(error) => CallResult::Error(error_message(error)), - ExitReason::Revert(_) => - CallResult::Error(b"execution reverted".to_vec()), + ExitReason::Revert(_) => { + CallResult::Error(b"execution reverted".to_vec()) + }, ExitReason::Fatal(_) => CallResult::Error(vec![]), }; @@ -568,10 +571,12 @@ impl Listener { created_contract_address_hash: context.to, created_contract_code: return_value.to_vec(), }, - ExitReason::Error(error) => - CreateResult::Error { error: error_message(error) }, - ExitReason::Revert(_) => - CreateResult::Error { error: b"execution reverted".to_vec() }, + ExitReason::Error(error) => { + CreateResult::Error { error: error_message(error) } + }, + ExitReason::Revert(_) => { + CreateResult::Error { error: b"execution reverted".to_vec() } + }, ExitReason::Fatal(_) => CreateResult::Error { error: vec![] }, }; @@ -620,14 +625,15 @@ impl ListenerT for Listener { Event::Gasometer(gasometer_event) => self.gasometer_event(gasometer_event), Event::Runtime(runtime_event) => self.runtime_event(runtime_event), Event::Evm(evm_event) => self.evm_event(evm_event), - Event::CallListNew() => + Event::CallListNew() => { if !self.call_list_first_transaction { self.finish_transaction(); self.skip_next_context = false; self.entries.push(BTreeMap::new()); } else { self.call_list_first_transaction = false; - }, + } + }, }; } @@ -726,8 +732,9 @@ mod tests { target: H160::default(), balance: U256::zero(), }, - TestEvmEvent::Exit => - EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() }, + TestEvmEvent::Exit => { + EvmEvent::Exit { reason: exit_reason.unwrap(), return_value: Vec::new() } + }, TestEvmEvent::TransactCall => EvmEvent::TransactCall { caller: H160::default(), address: H160::default(), @@ -750,8 +757,9 @@ mod tests { gas_limit: 0u64, address: H160::default(), }, - TestEvmEvent::Log => - EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() }, + TestEvmEvent::Log => { + EvmEvent::Log { address: H160::default(), topics: Vec::new(), data: Vec::new() } + }, } } @@ -764,8 +772,9 @@ mod tests { stack: test_stack(), memory: test_memory(), }, - TestRuntimeEvent::StepResult => - RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() }, + TestRuntimeEvent::StepResult => { + RuntimeEvent::StepResult { result: Ok(()), return_value: Vec::new() } + }, TestRuntimeEvent::SLoad => RuntimeEvent::SLoad { address: H160::default(), index: H256::default(), @@ -781,20 +790,24 @@ mod tests { fn test_emit_gasometer_event(event_type: TestGasometerEvent) -> GasometerEvent { match event_type { - TestGasometerEvent::RecordCost => - GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() }, - TestGasometerEvent::RecordRefund => - GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() }, - TestGasometerEvent::RecordStipend => - GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordCost => { + GasometerEvent::RecordCost { cost: 0u64, snapshot: test_snapshot() } + }, + TestGasometerEvent::RecordRefund => { + GasometerEvent::RecordRefund { refund: 0i64, snapshot: test_snapshot() } + }, + TestGasometerEvent::RecordStipend => { + GasometerEvent::RecordStipend { stipend: 0u64, snapshot: test_snapshot() } + }, TestGasometerEvent::RecordDynamicCost => GasometerEvent::RecordDynamicCost { gas_cost: 0u64, memory_gas: 0u64, gas_refund: 0i64, snapshot: test_snapshot(), }, - TestGasometerEvent::RecordTransaction => - GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() }, + TestGasometerEvent::RecordTransaction => { + GasometerEvent::RecordTransaction { cost: 0u64, snapshot: test_snapshot() } + }, } } diff --git a/client/evm-tracing/src/listeners/raw.rs b/client/evm-tracing/src/listeners/raw.rs index 2b39fe23..483ea0a3 100644 --- a/client/evm-tracing/src/listeners/raw.rs +++ b/client/evm-tracing/src/listeners/raw.rs @@ -161,7 +161,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(memory.data.len())); if self.remaining_memory_usage.is_none() { - return + return; } Some(memory.data.clone()) @@ -176,7 +176,7 @@ impl Listener { .and_then(|inner| inner.checked_sub(stack.data.len())); if self.remaining_memory_usage.is_none() { - return + return; } Some(stack.data.clone()) @@ -205,7 +205,7 @@ impl Listener { }); if self.remaining_memory_usage.is_none() { - return + return; } Some(context.storage_cache.clone()) @@ -277,8 +277,8 @@ impl Listener { _ => (), } }, - RuntimeEvent::SLoad { address: _, index, value } | - RuntimeEvent::SStore { address: _, index, value } => { + RuntimeEvent::SLoad { address: _, index, value } + | RuntimeEvent::SStore { address: _, index, value } => { if let Some(context) = self.context_stack.last_mut() { if !self.disable_storage { context.storage_cache.insert(index, value); @@ -295,7 +295,7 @@ impl Listener { impl ListenerT for Listener { fn event(&mut self, event: Event) { if self.remaining_memory_usage.is_none() { - return + return; } match event { diff --git a/client/evm-tracing/src/types/serialization.rs b/client/evm-tracing/src/types/serialization.rs index 9f31f709..f786ffaf 100644 --- a/client/evm-tracing/src/types/serialization.rs +++ b/client/evm-tracing/src/types/serialization.rs @@ -54,7 +54,7 @@ where S: Serializer, { if let Some(bytes) = bytes.as_ref() { - return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))) + return serializer.serialize_str(&format!("0x{}", hex::encode(&bytes[..]))); } Err(S::Error::custom("String serialize error.")) } @@ -87,7 +87,7 @@ where let d = std::str::from_utf8(&value[..]) .map_err(|_| S::Error::custom("String serialize error."))? .to_string(); - return serializer.serialize_str(&d) + return serializer.serialize_str(&d); } Err(S::Error::custom("String serialize error.")) } diff --git a/client/rpc-core/txpool/src/types/content.rs b/client/rpc-core/txpool/src/types/content.rs index 581be173..ec98a00f 100644 --- a/client/rpc-core/txpool/src/types/content.rs +++ b/client/rpc-core/txpool/src/types/content.rs @@ -66,12 +66,15 @@ where impl GetT for Transaction { fn get(hash: H256, from_address: H160, txn: &EthereumTransaction) -> Self { let (nonce, action, value, gas_price, gas_limit, input) = match txn { - EthereumTransaction::Legacy(t) => - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), - EthereumTransaction::EIP2930(t) => - (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()), - EthereumTransaction::EIP1559(t) => - (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()), + EthereumTransaction::Legacy(t) => { + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) + }, + EthereumTransaction::EIP2930(t) => { + (t.nonce, t.action, t.value, t.gas_price, t.gas_limit, t.input.clone()) + }, + EthereumTransaction::EIP1559(t) => { + (t.nonce, t.action, t.value, t.max_fee_per_gas, t.gas_limit, t.input.clone()) + }, }; Self { hash, diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index c1878aca..aa85097d 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -353,12 +353,15 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => - Ok(BlockId::Number(client.info().best_number)), - RequestBlockId::Tag(RequestBlockTag::Earliest) => - Ok(BlockId::Number(0u32.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Pending) => - Err(internal_err("'pending' blocks are not supported")), + RequestBlockId::Tag(RequestBlockTag::Latest) => { + Ok(BlockId::Number(client.info().best_number)) + }, + RequestBlockId::Tag(RequestBlockTag::Earliest) => { + Ok(BlockId::Number(0u32.unique_saturated_into())) + }, + RequestBlockId::Tag(RequestBlockTag::Pending) => { + Err(internal_err("'pending' blocks are not supported")) + }, RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -378,7 +381,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -395,7 +398,7 @@ where // If there are no ethereum transactions in the block return empty trace right away. if eth_tx_hashes.is_empty() { - return Ok(Response::Block(vec![])) + return Ok(Response::Block(vec![])); } // Get block extrinsics. @@ -410,7 +413,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; // Trace the block. @@ -425,7 +428,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (core)".to_string())) + return Err(internal_err("Runtime api version call failed (core)".to_string())); }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -470,10 +473,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::CallTracer => + TracerInput::CallTracer => { client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, _ => Err(internal_err("Bug: failed to resolve the tracer format.".to_string())), }?; @@ -533,7 +537,7 @@ where let blockchain = backend.blockchain(); // Get the header I want to work with. let Ok(reference_hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(reference_hash) { Ok(Some(h)) => h, @@ -554,7 +558,7 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; let reference_block = overrides.current_block(reference_hash); @@ -576,7 +580,7 @@ where } else { return Err(internal_err( "Runtime api version call failed (core)".to_string(), - )) + )); }; // Initialize block: calls the "on_initialize" hook on every pallet @@ -608,17 +612,20 @@ where // Pre-london update, legacy transactions. match transaction { ethereum::TransactionV2::Legacy(tx) => + { #[allow(deprecated)] api.trace_transaction_before_version_4( parent_block_hash, exts, tx, - ), - _ => + ) + }, + _ => { return Err(internal_err( "Bug: pre-london runtime expects legacy transactions" .to_string(), - )), + )) + }, } } }; @@ -659,10 +666,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => + TracerInput::Blockscout => { client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) @@ -680,7 +688,7 @@ where "Bug: `handle_transaction_request` does not support {:?}.", not_supported ))), - } + }; } } Err(internal_err("Runtime block call failed".to_string())) @@ -698,12 +706,15 @@ where let reference_id: BlockId = match request_block_id { RequestBlockId::Number(n) => Ok(BlockId::Number(n.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Latest) => - Ok(BlockId::Number(client.info().best_number)), - RequestBlockId::Tag(RequestBlockTag::Earliest) => - Ok(BlockId::Number(0u32.unique_saturated_into())), - RequestBlockId::Tag(RequestBlockTag::Pending) => - Err(internal_err("'pending' blocks are not supported")), + RequestBlockId::Tag(RequestBlockTag::Latest) => { + Ok(BlockId::Number(client.info().best_number)) + }, + RequestBlockId::Tag(RequestBlockTag::Earliest) => { + Ok(BlockId::Number(0u32.unique_saturated_into())) + }, + RequestBlockId::Tag(RequestBlockTag::Pending) => { + Err(internal_err("'pending' blocks are not supported")) + }, RequestBlockId::Hash(eth_hash) => { match futures::executor::block_on(frontier_backend_client::load_hash::( client.as_ref(), @@ -721,7 +732,7 @@ where let api = client.runtime_api(); // Get the header I want to work with. let Ok(hash) = client.expect_block_hash_from_id(&reference_id) else { - return Err(internal_err("Block header not found")) + return Err(internal_err("Block header not found")); }; let header = match client.header(hash) { Ok(Some(h)) => h, @@ -736,11 +747,11 @@ where { api_version } else { - return Err(internal_err("Runtime api version call failed (trace)".to_string())) + return Err(internal_err("Runtime api version call failed (trace)".to_string())); }; if trace_api_version <= 5 { - return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())) + return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); } let TraceCallParams { @@ -795,7 +806,7 @@ where } else { return Err(internal_err( "block unavailable, cannot query gas limit".to_string(), - )) + )); } }, }; @@ -847,10 +858,11 @@ where proxy.using(f)?; proxy.finish_transaction(); let response = match tracer_input { - TracerInput::Blockscout => + TracerInput::Blockscout => { client_evm_tracing::formatters::Blockscout::format(proxy) .ok_or("Trace result is empty.") - .map_err(|e| internal_err(format!("{:?}", e))), + .map_err(|e| internal_err(format!("{:?}", e))) + }, TracerInput::CallTracer => { let mut res = client_evm_tracing::formatters::CallTracer::format(proxy) .ok_or("Trace result is empty.") diff --git a/client/rpc/trace/src/lib.rs b/client/rpc/trace/src/lib.rs index 4514ce79..72c564df 100644 --- a/client/rpc/trace/src/lib.rs +++ b/client/rpc/trace/src/lib.rs @@ -100,8 +100,9 @@ where .try_into() .map_err(|_| "Block number overflow")?), Some(RequestBlockId::Tag(RequestBlockTag::Earliest)) => Ok(0), - Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => - Err("'pending' is not supported"), + Some(RequestBlockId::Tag(RequestBlockTag::Pending)) => { + Err("'pending' is not supported") + }, Some(RequestBlockId::Hash(_)) => Err("Block hash not supported"), } } @@ -117,14 +118,14 @@ where return Err(format!( "count ({}) can't be greater than maximum ({})", count, self.max_count - )) + )); } // Build a list of all the Substrate block hashes that need to be traced. let mut block_hashes = vec![]; for block_height in block_heights { if block_height == 0 { - continue // no traces for genesis block. + continue; // no traces for genesis block. } let block_hash = self @@ -173,15 +174,18 @@ where let mut block_traces: Vec<_> = block_traces .iter() .filter(|trace| match trace.action { - block::TransactionTraceAction::Call { from, to, .. } => - (from_address.is_empty() || from_address.contains(&from)) && - (to_address.is_empty() || to_address.contains(&to)), - block::TransactionTraceAction::Create { from, .. } => - (from_address.is_empty() || from_address.contains(&from)) && - to_address.is_empty(), - block::TransactionTraceAction::Suicide { address, .. } => - (from_address.is_empty() || from_address.contains(&address)) && - to_address.is_empty(), + block::TransactionTraceAction::Call { from, to, .. } => { + (from_address.is_empty() || from_address.contains(&from)) + && (to_address.is_empty() || to_address.contains(&to)) + }, + block::TransactionTraceAction::Create { from, .. } => { + (from_address.is_empty() || from_address.contains(&from)) + && to_address.is_empty() + }, + block::TransactionTraceAction::Suicide { address, .. } => { + (from_address.is_empty() || from_address.contains(&address)) + && to_address.is_empty() + }, }) .cloned() .collect(); @@ -207,11 +211,11 @@ where "the amount of traces goes over the maximum ({}), please use 'after' \ and 'count' in your request", self.max_count - )) + )); } traces = traces.into_iter().take(count).collect(); - break + break; } } } @@ -648,8 +652,8 @@ where // We remove early the block cache if this batch is the last // pooling this block. if let Some(block_cache) = self.cached_blocks.get_mut(block) { - if block_cache.active_batch_count == 1 && - matches!( + if block_cache.active_batch_count == 1 + && matches!( block_cache.state, CacheBlockState::Pooled { started: false, .. } ) { @@ -756,11 +760,12 @@ where overrides.current_transaction_statuses(substrate_hash), ) { (Some(a), Some(b)) => (a, b), - _ => + _ => { return Err(format!( "Failed to get Ethereum block data for Substrate block {}", substrate_hash - )), + )) + }, }; let eth_block_hash = eth_block.header.hash(); @@ -781,7 +786,7 @@ where { api_version } else { - return Err("Runtime api version call failed (trace)".to_string()) + return Err("Runtime api version call failed (trace)".to_string()); }; // Trace the block. @@ -795,7 +800,7 @@ where { api_version } else { - return Err("Runtime api version call failed (core)".to_string()) + return Err("Runtime api version call failed (core)".to_string()); }; // Initialize block: calls the "on_initialize" hook on every pallet diff --git a/client/rpc/txpool/src/lib.rs b/client/rpc/txpool/src/lib.rs index c00ad935..101050c5 100644 --- a/client/rpc/txpool/src/lib.rs +++ b/client/rpc/txpool/src/lib.rs @@ -74,7 +74,7 @@ where if let Ok(Some(api_version)) = api.api_version::>(best_block) { api_version } else { - return Err(internal_err("failed to retrieve Runtime Api version".to_string())) + return Err(internal_err("failed to retrieve Runtime Api version".to_string())); }; let ethereum_txns: TxPoolResponse = if api_version == 1 { #[allow(deprecated)] diff --git a/frost/frost-ristretto255/src/lib.rs b/frost/frost-ristretto255/src/lib.rs index a3322ef4..a4d955fc 100644 --- a/frost/frost-ristretto255/src/lib.rs +++ b/frost/frost-ristretto255/src/lib.rs @@ -102,12 +102,13 @@ impl Group for RistrettoGroup { .map_err(|_| GroupError::MalformedElement)? .decompress() { - Some(point) => + Some(point) => { if point == RistrettoPoint::identity() { Err(GroupError::InvalidIdentityElement) } else { Ok(WrappedRistrettoPoint(point)) - }, + } + }, None => Err(GroupError::MalformedElement), } } diff --git a/frost/src/keys.rs b/frost/src/keys.rs index 5069d93f..1c2656da 100644 --- a/frost/src/keys.rs +++ b/frost/src/keys.rs @@ -384,7 +384,7 @@ where let result = evaluate_vss(self.identifier, &self.commitment); if !(f_result == result) { - return Err(Error::InvalidSecretShare) + return Err(Error::InvalidSecretShare); } Ok((VerifyingShare(result), self.commitment.verifying_key()?)) diff --git a/frost/src/lib.rs b/frost/src/lib.rs index 5bd2fdff..ede2024d 100644 --- a/frost/src/lib.rs +++ b/frost/src/lib.rs @@ -66,7 +66,7 @@ pub fn random_nonzero(rng: &mut R) -> Sc let scalar = <::Field>::random(rng); if scalar != <::Field>::zero() { - return scalar + return scalar; } } } @@ -203,7 +203,7 @@ fn compute_lagrange_coefficient( x_i: Identifier, ) -> Result, Error> { if x_set.is_empty() { - return Err(Error::IncorrectNumberOfIdentifiers) + return Err(Error::IncorrectNumberOfIdentifiers); } let mut num = <::Field>::one(); let mut den = <::Field>::one(); @@ -213,7 +213,7 @@ fn compute_lagrange_coefficient( for x_j in x_set.iter() { if x_i == *x_j { x_i_found = true; - continue + continue; } if let Some(x) = x { @@ -226,7 +226,7 @@ fn compute_lagrange_coefficient( } } if !x_i_found { - return Err(Error::UnknownIdentifier) + return Err(Error::UnknownIdentifier); } Ok(num * <::Field>::invert(&den).map_err(|_| Error::DuplicatedIdentifier)?) @@ -396,7 +396,7 @@ where // The following check prevents a party from accidentally revealing their share. // Note that the '&&' operator would be sufficient. if identity == commitment.binding.0 || identity == commitment.hiding.0 { - return Err(Error::IdentityCommitment) + return Err(Error::IdentityCommitment); } let binding_factor = diff --git a/frost/src/round1.rs b/frost/src/round1.rs index 52f7d61a..54039c00 100644 --- a/frost/src/round1.rs +++ b/frost/src/round1.rs @@ -106,9 +106,9 @@ where /// Checks if the commitments are valid. pub fn is_valid(&self) -> bool { - element_is_valid::(&self.hiding.0) && - element_is_valid::(&self.binding.0) && - self.hiding.0 != self.binding.0 + element_is_valid::(&self.hiding.0) + && element_is_valid::(&self.binding.0) + && self.hiding.0 != self.binding.0 } } diff --git a/frost/src/scalar_mul.rs b/frost/src/scalar_mul.rs index a80b98b3..8211ac83 100644 --- a/frost/src/scalar_mul.rs +++ b/frost/src/scalar_mul.rs @@ -118,7 +118,7 @@ where // If carry == 1 and window & 1 == 0, then bit_buf & 1 == 1 so the next carry should // be 1 pos += 1; - continue + continue; } if window < width / 2 { @@ -197,14 +197,14 @@ where .collect::>>()?; if nafs.len() != lookup_tables.len() { - return None + return None; } let mut r = ::identity(); // All NAFs will have the same size, so get it from the first if nafs.is_empty() { - return Some(r) + return Some(r); } let naf_length = nafs[0].len(); diff --git a/frost/src/signature.rs b/frost/src/signature.rs index c7f059e5..5a1f89be 100644 --- a/frost/src/signature.rs +++ b/frost/src/signature.rs @@ -210,10 +210,10 @@ where lambda_i: Scalar, challenge: &Challenge, ) -> Result<(), Error> { - if (::generator() * self.share) != - (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) + if (::generator() * self.share) + != (group_commitment_share.0 + (verifying_share.0 * challenge.0 * lambda_i)) { - return Err(Error::InvalidSignatureShare) + return Err(Error::InvalidSignatureShare); } Ok(()) diff --git a/frost/src/signing_key.rs b/frost/src/signing_key.rs index 9307d5ed..758600f5 100644 --- a/frost/src/signing_key.rs +++ b/frost/src/signing_key.rs @@ -44,7 +44,7 @@ where <::Field as Field>::deserialize(&bytes).map_err(Error::from)?; if scalar == <::Field as Field>::zero() { - return Err(Error::MalformedSigningKey) + return Err(Error::MalformedSigningKey); } Ok(Self { scalar }) diff --git a/node/src/distributions/mainnet.rs b/node/src/distributions/mainnet.rs index cfbec875..a88ba554 100644 --- a/node/src/distributions/mainnet.rs +++ b/node/src/distributions/mainnet.rs @@ -44,7 +44,7 @@ fn read_contents_to_substrate_accounts(path_str: &str) -> BTreeMap BTreeMap BTreeMap Result<(), S // Ensure key is present if !ensure_keytype_exists_in_keystore(key_type, key_store.clone()) { println!("{key_type:?} key not found!"); - return Err("Key not found!".to_string()) + return Err("Key not found!".to_string()); } } diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 40964208..161de15d 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -94,14 +94,16 @@ impl StatementKind { /// Convert this to the (English) statement it represents. fn to_text(self) -> &'static [u8] { match self { - StatementKind::Regular => + StatementKind::Regular => { &b"I hereby agree to the terms of the statement whose sha2256sum is \ 5627de05cfe235cd4ffa0d6375c8a5278b89cc9b9e75622fa2039f4d1b43dadf. (This may be found at the URL: \ - https://statement.tangle.tools/airdrop-statement.html)"[..], - StatementKind::Safe => + https://statement.tangle.tools/airdrop-statement.html)"[..] + }, + StatementKind::Safe => { &b"I hereby agree to the terms of the statement whose sha2256sum is \ 7eae145b00c1912c8b01674df5df4ad9abcf6d18ea3f33d27eb6897a762f4273. (This may be found at the URL: \ - https://statement.tangle.tools/safe-claim-statement)"[..], + https://statement.tangle.tools/safe-claim-statement)"[..] + }, } } } @@ -639,9 +641,10 @@ impl Pallet { statement: Vec, ) -> Result> { let signer = match signature { - MultiAddressSignature::EVM(ethereum_signature) => + MultiAddressSignature::EVM(ethereum_signature) => { Self::eth_recover(ðereum_signature, &data, &statement[..]) - .ok_or(Error::::InvalidEthereumSignature)?, + .ok_or(Error::::InvalidEthereumSignature)? + }, MultiAddressSignature::Native(sr25519_signature) => { ensure!(!signer.is_none(), Error::::InvalidNativeAccount); Self::sr25519_recover(signer.unwrap(), &sr25519_signature, &data, &statement[..]) diff --git a/pallets/claims/src/utils/mod.rs b/pallets/claims/src/utils/mod.rs index f2559685..a387457f 100644 --- a/pallets/claims/src/utils/mod.rs +++ b/pallets/claims/src/utils/mod.rs @@ -45,8 +45,9 @@ impl Hash for MultiAddress { impl MultiAddress { pub fn to_account_id_32(&self) -> AccountId32 { match self { - MultiAddress::EVM(ethereum_address) => - HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)), + MultiAddress::EVM(ethereum_address) => { + HashedAddressMapping::::into_account_id(H160::from(ethereum_address.0)) + }, MultiAddress::Native(substrate_address) => substrate_address.clone(), } } diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 73a85832..03c95e66 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -121,7 +121,7 @@ impl Pallet { // Update storage Operators::::insert(&operator, operator_metadata); } else { - return Err(Error::::NotAnOperator.into()) + return Err(Error::::NotAnOperator.into()); } Ok(()) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 34410afe..08cff321 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -190,7 +190,7 @@ impl Pallet { Preservation::Expendable, ) .is_ok(), - Asset::Erc20(asset_address) => + Asset::Erc20(asset_address) => { if let Some(evm_addr) = evm_address { if let Ok((success, _weight)) = Self::erc20_transfer( asset_address, @@ -204,7 +204,8 @@ impl Pallet { } } else { false - }, + } + }, } } else { true diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 32dbc36a..d5d9abd4 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -649,10 +649,11 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => + (left_val, right_val) => { if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - }, + } + }, }; } } diff --git a/pallets/multi-asset-delegation/src/mock_evm.rs b/pallets/multi-asset-delegation/src/mock_evm.rs index 86325eff..ece3807a 100644 --- a/pallets/multi-asset-delegation/src/mock_evm.rs +++ b/pallets/multi-asset-delegation/src/mock_evm.rs @@ -165,7 +165,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet multi_asset_delegation account free to use if who == &pallet_multi_asset_delegation_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation as OnChargeEVMTransaction< @@ -183,7 +183,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet multi_asset_delegation account free to use if who == &pallet_multi_asset_delegation_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation as OnChargeEVMTransaction< @@ -269,8 +269,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -280,8 +281,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, _ => None, } } diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 27ed16a1..69bec270 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -302,8 +302,8 @@ fn schedule_operator_unstake_success() { // Verify remaining stake is above minimum assert!( - operator_info.stake.saturating_sub(unstake_amount) >= - MinOperatorBondAmount::get().into() + operator_info.stake.saturating_sub(unstake_amount) + >= MinOperatorBondAmount::get().into() ); // Verify event @@ -373,7 +373,7 @@ fn schedule_operator_unstake_not_an_operator() { // // Attempt to schedule unstake with active services // assert_noop!( -// +// // MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), // unstake_amount), Error::::ActiveServicesUsingTNT // ); diff --git a/pallets/services/rpc/src/lib.rs b/pallets/services/rpc/src/lib.rs index e25f3c23..ce67fb1b 100644 --- a/pallets/services/rpc/src/lib.rs +++ b/pallets/services/rpc/src/lib.rs @@ -113,10 +113,12 @@ impl From for i32 { fn custom_error_into_rpc_err(err: Error) -> ErrorObjectOwned { match err { - Error::RuntimeError(e) => - ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))), - Error::DecodeError => - ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")), + Error::RuntimeError(e) => { + ErrorObject::owned(RUNTIME_ERROR, "Runtime error", Some(format!("{e}"))) + }, + Error::DecodeError => { + ErrorObject::owned(2, "Decode error", Some("Transaction was not decodable")) + }, Error::CustomDispatchError(msg) => ErrorObject::owned(3, "Dispatch error", Some(msg)), } } diff --git a/pallets/services/src/functions.rs b/pallets/services/src/functions.rs index 4fd786b7..5080ebe2 100644 --- a/pallets/services/src/functions.rs +++ b/pallets/services/src/functions.rs @@ -77,8 +77,9 @@ impl Pallet { pub fn mbsm_address_of(blueprint: &ServiceBlueprint) -> Result> { match blueprint.master_manager_revision { MasterBlueprintServiceManagerRevision::Specific(rev) => Self::mbsm_address(rev), - MasterBlueprintServiceManagerRevision::Latest => - Self::mbsm_address(Self::mbsm_latest_revision()), + MasterBlueprintServiceManagerRevision::Latest => { + Self::mbsm_address(Self::mbsm_latest_revision()) + }, other => unimplemented!("Got unexpected case for {:?}", other), } } diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index 06677d2f..7a8d82c3 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -1071,8 +1071,9 @@ pub mod module { .operators_with_approval_state .into_iter() .filter_map(|(v, state)| match state { - ApprovalState::Approved { restaking_percent } => - Some((v, restaking_percent)), + ApprovalState::Approved { restaking_percent } => { + Some((v, restaking_percent)) + }, // N.B: this should not happen, as all operators are approved and checked // above. _ => None, diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 3ba4c7c3..7f161aef 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -275,7 +275,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false + return false; } true } @@ -775,10 +775,11 @@ pub fn assert_events(mut expected: Vec) { for evt in expected { let next = actual.pop().expect("RuntimeEvent expected"); match (&next, &evt) { - (left_val, right_val) => + (left_val, right_val) => { if !(*left_val == *right_val) { panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - }, + } + }, }; } } diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index 46b7ea04..02bc329c 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -163,7 +163,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation as OnChargeEVMTransaction< @@ -180,7 +180,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation as OnChargeEVMTransaction< @@ -266,8 +266,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -277,8 +278,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, _ => None, } } diff --git a/pallets/services/src/tests.rs b/pallets/services/src/tests.rs index 0a4796ca..7a35b33c 100644 --- a/pallets/services/src/tests.rs +++ b/pallets/services/src/tests.rs @@ -59,8 +59,9 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, + MachineKind::Small => { + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } + }, } } diff --git a/pallets/tangle-lst/src/lib.rs b/pallets/tangle-lst/src/lib.rs index 028e5c54..b439669f 100644 --- a/pallets/tangle-lst/src/lib.rs +++ b/pallets/tangle-lst/src/lib.rs @@ -844,7 +844,7 @@ pub mod pallet { let pool_id = member.get_by_pool_id(current_era, pool_id); if pool_id.is_none() { - return Err(Error::::PoolNotFound.into()) + return Err(Error::::PoolNotFound.into()); } // checked above @@ -1506,7 +1506,7 @@ impl Pallet { let balance = T::U256ToBalance::convert; if current_balance.is_zero() || current_points.is_zero() || points.is_zero() { // There is nothing to unbond - return Zero::zero() + return Zero::zero(); } // Equivalent of (current_balance / current_points) * points @@ -1614,8 +1614,9 @@ impl Pallet { bonded_pool.ok_to_join()?; let (_points_issued, bonded) = match extra { - BondExtra::FreeBalance(amount) => - (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount), + BondExtra::FreeBalance(amount) => { + (bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount) + }, }; bonded_pool.ok_to_be_open()?; @@ -1681,7 +1682,7 @@ impl Pallet { let min_balance = T::Currency::minimum_balance(); if pre_frozen_balance == min_balance { - return Err(Error::::NothingToAdjust.into()) + return Err(Error::::NothingToAdjust.into()); } // Update frozen amount with current ED. diff --git a/pallets/tangle-lst/src/types/bonded_pool.rs b/pallets/tangle-lst/src/types/bonded_pool.rs index bcddfb94..bca83493 100644 --- a/pallets/tangle-lst/src/types/bonded_pool.rs +++ b/pallets/tangle-lst/src/types/bonded_pool.rs @@ -160,8 +160,8 @@ impl BondedPool { } pub fn can_nominate(&self, who: &T::AccountId) -> bool { - self.is_root(who) || - self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) + self.is_root(who) + || self.roles.nominator.as_ref().map_or(false, |nominator| nominator == who) } pub fn can_kick(&self, who: &T::AccountId) -> bool { @@ -262,9 +262,9 @@ impl BondedPool { // any unbond must comply with the balance condition: ensure!( - is_full_unbond || - balance_after_unbond >= - if is_depositor { + is_full_unbond + || balance_after_unbond + >= if is_depositor { Pallet::::depositor_min_bond() } else { MinJoinBond::::get() @@ -296,7 +296,7 @@ impl BondedPool { }, (false, true) => { // the depositor can simply not be unbonded permissionlessly, period. - return Err(Error::::DoesNotHavePermission.into()) + return Err(Error::::DoesNotHavePermission.into()); }, }; diff --git a/pallets/tangle-lst/src/types/commission.rs b/pallets/tangle-lst/src/types/commission.rs index 01ecdd0e..9fbee755 100644 --- a/pallets/tangle-lst/src/types/commission.rs +++ b/pallets/tangle-lst/src/types/commission.rs @@ -55,13 +55,13 @@ impl Commission { // do not throttle if `to` is the same or a decrease in commission. if *to <= commission_as_percent { - return false + return false; } // Test for `max_increase` throttling. // // Throttled if the attempted increase in commission is greater than `max_increase`. if (*to).saturating_sub(commission_as_percent) > t.max_increase { - return true + return true; } // Test for `min_delay` throttling. @@ -84,7 +84,7 @@ impl Commission { blocks_surpassed < t.min_delay } }, - ) + ); } false } @@ -145,7 +145,7 @@ impl Commission { ); if let Some(old) = self.max.as_mut() { if new_max > *old { - return Err(Error::::MaxCommissionRestricted.into()) + return Err(Error::::MaxCommissionRestricted.into()); } *old = new_max; } else { diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index fae8c1d3..91a07416 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -127,7 +127,7 @@ where fn discriminant(address: H160, gas: u64) -> DiscriminantResult> { let extra_cost = RuntimeHelper::::db_read_gas_cost(); if gas < extra_cost { - return DiscriminantResult::OutOfGas + return DiscriminantResult::OutOfGas; } let asset_id = match Runtime::address_to_asset_id(address) { @@ -254,8 +254,8 @@ where handle.record_db_read::(136)?; // If previous approval exists, we need to clean it - if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) != - 0u32.into() + if pallet_assets::Pallet::::allowance(asset_id.clone(), &owner, &spender) + != 0u32.into() { RuntimeHelper::::try_dispatch( handle, diff --git a/precompiles/assets-erc20/src/tests.rs b/precompiles/assets-erc20/src/tests.rs index 05d48cf8..7152d4c4 100644 --- a/precompiles/assets-erc20/src/tests.rs +++ b/precompiles/assets-erc20/src/tests.rs @@ -441,8 +441,8 @@ fn transfer_not_enough_founds() { ForeignPCall::transfer { to: Address(Charlie.into()), value: 50.into() }, ) .execute_reverts(|output| { - from_utf8(output).unwrap().contains("Dispatched call failed with error: ") && - from_utf8(output).unwrap().contains("BalanceLow") + from_utf8(output).unwrap().contains("Dispatched call failed with error: ") + && from_utf8(output).unwrap().contains("BalanceLow") }); }); } diff --git a/precompiles/balances-erc20/src/lib.rs b/precompiles/balances-erc20/src/lib.rs index 8c05ca46..aa3a6b4f 100644 --- a/precompiles/balances-erc20/src/lib.rs +++ b/precompiles/balances-erc20/src/lib.rs @@ -437,7 +437,7 @@ where fn deposit(handle: &mut impl PrecompileHandle) -> EvmResult { // Deposit only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()) + return Err(RevertReason::UnknownSelector.into()); } let caller: Runtime::AccountId = @@ -446,7 +446,7 @@ where let amount = Self::u256_to_amount(handle.context().apparent_value)?; if amount.into() == U256::from(0u32) { - return Err(revert("deposited amount must be non-zero")) + return Err(revert("deposited amount must be non-zero")); } handle.record_log_costs_manual(2, 32)?; @@ -476,7 +476,7 @@ where fn withdraw(handle: &mut impl PrecompileHandle, value: U256) -> EvmResult { // Withdraw only makes sense for the native currency. if !Metadata::is_native_currency() { - return Err(RevertReason::UnknownSelector.into()) + return Err(RevertReason::UnknownSelector.into()); } handle.record_log_costs_manual(2, 32)?; @@ -488,7 +488,7 @@ where }; if value > account_amount { - return Err(revert("Trying to withdraw more than owned")) + return Err(revert("Trying to withdraw more than owned")); } log2( @@ -548,7 +548,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/balances-erc20/src/tests.rs b/precompiles/balances-erc20/src/tests.rs index f62c1a4d..6e176e80 100644 --- a/precompiles/balances-erc20/src/tests.rs +++ b/precompiles/balances-erc20/src/tests.rs @@ -306,8 +306,8 @@ fn transfer_not_enough_funds() { PCall::transfer { to: Address(Bob.into()), value: 1400.into() }, ) .execute_reverts(|output| { - from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") && - from_utf8(&output).unwrap().contains("FundsUnavailable") + from_utf8(&output).unwrap().contains("Dispatched call failed with error: ") + && from_utf8(&output).unwrap().contains("FundsUnavailable") }); }); } diff --git a/precompiles/batch/src/lib.rs b/precompiles/batch/src/lib.rs index 943216e3..d26ac2ba 100644 --- a/precompiles/batch/src/lib.rs +++ b/precompiles/batch/src/lib.rs @@ -146,8 +146,9 @@ where let forwarded_gas = match (remaining_gas.checked_sub(log_cost), mode) { (Some(remaining), _) => remaining, - (None, Mode::BatchAll) => - return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), + (None, Mode::BatchAll) => { + return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) + }, (None, _) => return Ok(()), }; @@ -162,10 +163,11 @@ where log.record(handle)?; match mode { - Mode::BatchAll => + Mode::BatchAll => { return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }), + }) + }, Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -182,10 +184,11 @@ where log.record(handle)?; match mode { - Mode::BatchAll => + Mode::BatchAll => { return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, - }), + }) + }, Mode::BatchSomeUntilFailure => return Ok(()), Mode::BatchSome => continue, } @@ -216,19 +219,23 @@ where // How to proceed match (mode, reason) { // _: Fatal is always fatal - (_, ExitReason::Fatal(exit_status)) => - return Err(PrecompileFailure::Fatal { exit_status }), + (_, ExitReason::Fatal(exit_status)) => { + return Err(PrecompileFailure::Fatal { exit_status }) + }, // BatchAll : Reverts and errors are immediatly forwarded. - (Mode::BatchAll, ExitReason::Revert(exit_status)) => - return Err(PrecompileFailure::Revert { exit_status, output }), - (Mode::BatchAll, ExitReason::Error(exit_status)) => - return Err(PrecompileFailure::Error { exit_status }), + (Mode::BatchAll, ExitReason::Revert(exit_status)) => { + return Err(PrecompileFailure::Revert { exit_status, output }) + }, + (Mode::BatchAll, ExitReason::Error(exit_status)) => { + return Err(PrecompileFailure::Error { exit_status }) + }, // BatchSomeUntilFailure : Reverts and errors prevent subsequent subcalls to // be executed but the precompile still succeed. - (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => - return Ok(()), + (Mode::BatchSomeUntilFailure, ExitReason::Revert(_) | ExitReason::Error(_)) => { + return Ok(()) + }, // Success or ignored revert/error. (_, _) => (), @@ -263,8 +270,9 @@ where match mode { Mode::BatchSome => Self::batch_some { to, value, call_data, gas_limit }, - Mode::BatchSomeUntilFailure => - Self::batch_some_until_failure { to, value, call_data, gas_limit }, + Mode::BatchSomeUntilFailure => { + Self::batch_some_until_failure { to, value, call_data, gas_limit } + }, Mode::BatchAll => Self::batch_all { to, value, call_data, gas_limit }, } } diff --git a/precompiles/call-permit/src/lib.rs b/precompiles/call-permit/src/lib.rs index 0f5df485..ea1906ba 100644 --- a/precompiles/call-permit/src/lib.rs +++ b/precompiles/call-permit/src/lib.rs @@ -170,7 +170,7 @@ where .ok_or_else(|| revert("Call require too much gas (uint64 overflow)"))?; if total_cost > handle.remaining_gas() { - return Err(revert("Gaslimit is too low to dispatch provided call")) + return Err(revert("Gaslimit is too low to dispatch provided call")); } // VERIFY PERMIT @@ -216,8 +216,9 @@ where match reason { ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(_) => - Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }), + ExitReason::Revert(_) => { + Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, output }) + }, ExitReason::Succeed(_) => Ok(output.into()), } } diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 21707fef..b8d54921 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -82,7 +82,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; @@ -266,8 +266,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; // Get origin account. @@ -306,8 +307,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; let call = pallet_multi_asset_delegation::Call::::schedule_withdraw { @@ -349,8 +351,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; // Build call with origin. @@ -393,8 +396,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; // Build call with origin. @@ -431,8 +435,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; // Build call with origin. @@ -479,8 +484,9 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; // Build call with origin. diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index 2c7d6533..c6ed8d64 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -432,8 +432,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status == - OperatorStatus::Inactive + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Inactive ); PrecompilesValue::get() @@ -441,8 +441,8 @@ fn test_operator_go_offline_and_online() { .execute_returns(()); assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status == - OperatorStatus::Active + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Active ); assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); diff --git a/precompiles/pallet-democracy/src/lib.rs b/precompiles/pallet-democracy/src/lib.rs index 7371074c..ca29013f 100644 --- a/precompiles/pallet-democracy/src/lib.rs +++ b/precompiles/pallet-democracy/src/lib.rs @@ -467,7 +467,7 @@ where if !<::Preimages as QueryPreimage>::is_requested( &proposal_hash, ) { - return Err(revert("not imminent preimage (preimage not requested)")) + return Err(revert("not imminent preimage (preimage not requested)")); }; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); diff --git a/precompiles/pallet-democracy/src/tests.rs b/precompiles/pallet-democracy/src/tests.rs index 9fdb6a6f..697eae1b 100644 --- a/precompiles/pallet-democracy/src/tests.rs +++ b/precompiles/pallet-democracy/src/tests.rs @@ -220,8 +220,9 @@ fn lowest_unbaked_non_zero() { .dispatch(RuntimeOrigin::signed(Alice.into()))); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -243,9 +244,9 @@ fn lowest_unbaked_non_zero() { // Run it through until it is baked roll_to( - ::VotingPeriod::get() + - ::LaunchPeriod::get() + - 1000, + ::VotingPeriod::get() + + ::LaunchPeriod::get() + + 1000, ); precompiles() @@ -558,8 +559,9 @@ fn standard_vote_aye_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -642,8 +644,9 @@ fn standard_vote_nay_conviction_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -721,8 +724,9 @@ fn remove_vote_works() { ); let voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; @@ -793,8 +797,9 @@ fn delegate_works() { ); let alice_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Alice)) { - Voting::Delegating { balance, target, conviction, delegations, prior } => - (balance, target, conviction, delegations, prior), + Voting::Delegating { balance, target, conviction, delegations, prior } => { + (balance, target, conviction, delegations, prior) + }, _ => panic!("Votes are not delegating"), }; @@ -807,8 +812,9 @@ fn delegate_works() { let bob_voting = match pallet_democracy::VotingOf::::get(AccountId::from(Bob)) { - Voting::Direct { votes, delegations, prior } => - (votes.into_inner(), delegations, prior), + Voting::Direct { votes, delegations, prior } => { + (votes.into_inner(), delegations, prior) + }, _ => panic!("Votes are not direct"), }; diff --git a/precompiles/precompile-registry/src/lib.rs b/precompiles/precompile-registry/src/lib.rs index 554e1cd6..15e94ee0 100644 --- a/precompiles/precompile-registry/src/lib.rs +++ b/precompiles/precompile-registry/src/lib.rs @@ -69,8 +69,9 @@ where .is_active_precompile(address.0, handle.remaining_gas()) { IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile), - IsPrecompileResult::OutOfGas => - Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }), + IsPrecompileResult::OutOfGas => { + Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas }) + }, } } @@ -85,7 +86,7 @@ where // Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15) handle.record_db_read::(175)?; if !is_precompile_or_fail::(address.0, handle.remaining_gas())? { - return Err(revert("provided address is not a precompile")) + return Err(revert("provided address is not a precompile")); } // pallet_evm::create_account read storage item pallet_evm::AccountCodes diff --git a/precompiles/proxy/src/lib.rs b/precompiles/proxy/src/lib.rs index 92e27d5a..8cf81816 100644 --- a/precompiles/proxy/src/lib.rs +++ b/precompiles/proxy/src/lib.rs @@ -60,8 +60,9 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector), + Some(selector) => { + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) + }, } } @@ -91,11 +92,12 @@ where fn is_allowed(_caller: H160, selector: Option) -> bool { match selector { None => false, - Some(selector) => - ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) || - ProxyPrecompileCall::::proxy_selectors().contains(&selector) || - ProxyPrecompileCall::::proxy_force_type_selectors() - .contains(&selector), + Some(selector) => { + ProxyPrecompileCall::::is_proxy_selectors().contains(&selector) + || ProxyPrecompileCall::::proxy_selectors().contains(&selector) + || ProxyPrecompileCall::::proxy_force_type_selectors() + .contains(&selector) + }, } } @@ -185,7 +187,7 @@ where .iter() .any(|pd| pd.delegate == delegate) { - return Err(revert("Cannot add more than one proxy")) + return Err(revert("Cannot add more than one proxy")); } let delegate: ::Source = @@ -341,7 +343,7 @@ where // Check that we only perform proxy calls on behalf of externally owned accounts let AddressType::EOA = precompile_set::get_address_type::(handle, real.into())? else { - return Err(revert("real address must be EOA")) + return Err(revert("real address must be EOA")); }; // Read proxy @@ -417,8 +419,9 @@ where // Return subcall result match reason { ExitReason::Fatal(exit_status) => Err(PrecompileFailure::Fatal { exit_status }), - ExitReason::Revert(exit_status) => - Err(PrecompileFailure::Revert { exit_status, output }), + ExitReason::Revert(exit_status) => { + Err(PrecompileFailure::Revert { exit_status, output }) + }, ExitReason::Error(exit_status) => Err(PrecompileFailure::Error { exit_status }), ExitReason::Succeed(_) => Ok(()), } diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index d9a3bea4..7739a240 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -206,18 +206,19 @@ where (0, zero_address) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)) + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); } (Asset::Erc20(erc20_token.into()), amount) }, (other_asset_id, zero_address) => { if value != Default::default() { - return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)) + return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); } (Asset::Custom(other_asset_id.into()), amount) }, - (_other_asset_id, _erc20_token) => - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)), + (_other_asset_id, _erc20_token) => { + return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + }, }; let call = pallet_services::Call::::request { diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 76677de7..7ab17b0b 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -407,7 +407,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn is_operator_active(operator: &AccountId) -> bool { if operator == &mock_pub_key(10) { - return false + return false; } true } diff --git a/precompiles/services/src/mock_evm.rs b/precompiles/services/src/mock_evm.rs index c3bdf41b..cd0ccbcf 100644 --- a/precompiles/services/src/mock_evm.rs +++ b/precompiles/services/src/mock_evm.rs @@ -151,7 +151,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation as OnChargeEVMTransaction< @@ -168,7 +168,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation as OnChargeEVMTransaction< @@ -254,8 +254,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -265,8 +266,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))), + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, _ => None, } } diff --git a/precompiles/services/src/tests.rs b/precompiles/services/src/tests.rs index 0cde095d..43a0aa01 100644 --- a/precompiles/services/src/tests.rs +++ b/precompiles/services/src/tests.rs @@ -45,8 +45,9 @@ fn price_targets(kind: MachineKind) -> PriceTargets { storage_ssd: 100, storage_nvme: 150, }, - MachineKind::Small => - PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 }, + MachineKind::Small => { + PriceTargets { cpu: 500, mem: 250, storage_hdd: 25, storage_ssd: 50, storage_nvme: 75 } + }, } } diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index 1ab81ec6..aa08dbe3 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -78,7 +78,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index cabd6dd6..b49fdc01 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -344,7 +344,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; diff --git a/precompiles/verify-bls381-signature/src/lib.rs b/precompiles/verify-bls381-signature/src/lib.rs index 13695778..08e14fd2 100644 --- a/precompiles/verify-bls381-signature/src/lib.rs +++ b/precompiles/verify-bls381-signature/src/lib.rs @@ -55,14 +55,14 @@ impl Bls381Precompile { { p_key } else { - return Ok(false) + return Ok(false); }; let signature = if let Ok(sig) = snowbridge_milagro_bls::Signature::from_bytes(&signature_bytes) { sig } else { - return Ok(false) + return Ok(false); }; let is_confirmed = signature.verify(&message, &public_key); diff --git a/precompiles/verify-schnorr-signatures/src/lib.rs b/precompiles/verify-schnorr-signatures/src/lib.rs index 24246325..19b5636b 100644 --- a/precompiles/verify-schnorr-signatures/src/lib.rs +++ b/precompiles/verify-schnorr-signatures/src/lib.rs @@ -55,7 +55,7 @@ pub fn to_slice_32(val: &[u8]) -> Option<[u8; 32]> { let mut key = [0u8; 32]; key[..32].copy_from_slice(val); - return Some(key) + return Some(key); } None } diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index 173396a5..d4c48406 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -79,7 +79,7 @@ where }, _ => { // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")) + return Err(revert("Error while parsing staker's address")); }, }; @@ -153,7 +153,7 @@ where match pallet_vesting::Vesting::::get(origin.clone()) { Some(schedules) => { if index >= schedules.len() as u8 { - return Err(revert("Invalid vesting schedule index")) + return Err(revert("Invalid vesting schedule index")); } // Make the call to transfer the vested funds to the `target` account. let target = Self::convert_to_account_id(target)?; diff --git a/primitives/rpc/evm-tracing-events/src/evm.rs b/primitives/rpc/evm-tracing-events/src/evm.rs index 688861fd..2b997eae 100644 --- a/primitives/rpc/evm-tracing-events/src/evm.rs +++ b/primitives/rpc/evm-tracing-events/src/evm.rs @@ -61,8 +61,9 @@ impl From for CreateScheme { fn from(i: evm_runtime::CreateScheme) -> Self { match i { evm_runtime::CreateScheme::Legacy { caller } => Self::Legacy { caller }, - evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => - Self::Create2 { caller, code_hash, salt }, + evm_runtime::CreateScheme::Create2 { caller, code_hash, salt } => { + Self::Create2 { caller, code_hash, salt } + }, evm_runtime::CreateScheme::Fixed(address) => Self::Fixed(address), } } @@ -166,12 +167,15 @@ impl<'a> From> for EvmEvent { init_code: init_code.to_vec(), target_gas, }, - evm::tracing::Event::Suicide { address, target, balance } => - Self::Suicide { address, target, balance }, - evm::tracing::Event::Exit { reason, return_value } => - Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() }, - evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => - Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit }, + evm::tracing::Event::Suicide { address, target, balance } => { + Self::Suicide { address, target, balance } + }, + evm::tracing::Event::Exit { reason, return_value } => { + Self::Exit { reason: reason.clone(), return_value: return_value.to_vec() } + }, + evm::tracing::Event::TransactCall { caller, address, value, data, gas_limit } => { + Self::TransactCall { caller, address, value, data: data.to_vec(), gas_limit } + }, evm::tracing::Event::TransactCreate { caller, value, diff --git a/primitives/rpc/evm-tracing-events/src/gasometer.rs b/primitives/rpc/evm-tracing-events/src/gasometer.rs index d1fbb453..85d8352b 100644 --- a/primitives/rpc/evm-tracing-events/src/gasometer.rs +++ b/primitives/rpc/evm-tracing-events/src/gasometer.rs @@ -59,12 +59,15 @@ pub enum GasometerEvent { impl From for GasometerEvent { fn from(i: evm_gasometer::tracing::Event) -> Self { match i { - evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => - Self::RecordCost { cost, snapshot: snapshot.into() }, - evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => - Self::RecordRefund { refund, snapshot: snapshot.into() }, - evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => - Self::RecordStipend { stipend, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordCost { cost, snapshot } => { + Self::RecordCost { cost, snapshot: snapshot.into() } + }, + evm_gasometer::tracing::Event::RecordRefund { refund, snapshot } => { + Self::RecordRefund { refund, snapshot: snapshot.into() } + }, + evm_gasometer::tracing::Event::RecordStipend { stipend, snapshot } => { + Self::RecordStipend { stipend, snapshot: snapshot.into() } + }, evm_gasometer::tracing::Event::RecordDynamicCost { gas_cost, memory_gas, @@ -76,8 +79,9 @@ impl From for GasometerEvent { gas_refund, snapshot: snapshot.into(), }, - evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => - Self::RecordTransaction { cost, snapshot: snapshot.into() }, + evm_gasometer::tracing::Event::RecordTransaction { cost, snapshot } => { + Self::RecordTransaction { cost, snapshot: snapshot.into() } + }, } } } diff --git a/primitives/rpc/evm-tracing-events/src/runtime.rs b/primitives/rpc/evm-tracing-events/src/runtime.rs index ad738f73..089932d5 100644 --- a/primitives/rpc/evm-tracing-events/src/runtime.rs +++ b/primitives/rpc/evm-tracing-events/src/runtime.rs @@ -92,7 +92,7 @@ impl RuntimeEvent { filter: crate::StepEventFilter, ) -> Self { match i { - evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => + evm_runtime::tracing::Event::Step { context, opcode, position, stack, memory } => { Self::Step { context: context.clone().into(), opcode: opcodes_string(opcode), @@ -102,7 +102,8 @@ impl RuntimeEvent { }, stack: if filter.enable_stack { Some(stack.into()) } else { None }, memory: if filter.enable_memory { Some(memory.into()) } else { None }, - }, + } + }, evm_runtime::tracing::Event::StepResult { result, return_value } => Self::StepResult { result: match result { Ok(_) => Ok(()), @@ -113,10 +114,12 @@ impl RuntimeEvent { }, return_value: return_value.to_vec(), }, - evm_runtime::tracing::Event::SLoad { address, index, value } => - Self::SLoad { address, index, value }, - evm_runtime::tracing::Event::SStore { address, index, value } => - Self::SStore { address, index, value }, + evm_runtime::tracing::Event::SLoad { address, index, value } => { + Self::SLoad { address, index, value } + }, + evm_runtime::tracing::Event::SStore { address, index, value } => { + Self::SStore { address, index, value } + }, } } } diff --git a/primitives/src/chain_identifier.rs b/primitives/src/chain_identifier.rs index d916c2a2..72155a8a 100644 --- a/primitives/src/chain_identifier.rs +++ b/primitives/src/chain_identifier.rs @@ -65,14 +65,14 @@ impl TypedChainId { #[must_use] pub const fn underlying_chain_id(&self) -> u32 { match self { - TypedChainId::Evm(id) | - TypedChainId::Substrate(id) | - TypedChainId::PolkadotParachain(id) | - TypedChainId::KusamaParachain(id) | - TypedChainId::RococoParachain(id) | - TypedChainId::Cosmos(id) | - TypedChainId::Solana(id) | - TypedChainId::Ink(id) => *id, + TypedChainId::Evm(id) + | TypedChainId::Substrate(id) + | TypedChainId::PolkadotParachain(id) + | TypedChainId::KusamaParachain(id) + | TypedChainId::RococoParachain(id) + | TypedChainId::Cosmos(id) + | TypedChainId::Solana(id) + | TypedChainId::Ink(id) => *id, Self::None => 0, } } diff --git a/primitives/src/services/field.rs b/primitives/src/services/field.rs index 8fd27a35..c03869aa 100644 --- a/primitives/src/services/field.rs +++ b/primitives/src/services/field.rs @@ -172,13 +172,13 @@ impl PartialEq for Field { (Self::AccountId(l0), Self::AccountId(r0)) => l0 == r0, (Self::Struct(l_name, l_fields), Self::Struct(r_name, r_fields)) => { if l_name != r_name || l_fields.len() != r_fields.len() { - return false + return false; } for ((l_field_name, l_field_value), (r_field_name, r_field_value)) in l_fields.iter().zip(r_fields.iter()) { if l_field_name != r_field_name || l_field_value != r_field_value { - return false + return false; } } true @@ -307,16 +307,18 @@ impl PartialEq for Field { (Self::Int64(_), FieldType::Int64) => true, (Self::String(_), FieldType::String) => true, (Self::Bytes(_), FieldType::Bytes) => true, - (Self::Array(a), FieldType::Array(len, b)) => - a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())), + (Self::Array(a), FieldType::Array(len, b)) => { + a.len() == *len as usize && a.iter().all(|f| f.eq(b.as_ref())) + }, (Self::List(a), FieldType::List(b)) => a.iter().all(|f| f.eq(b.as_ref())), (Self::AccountId(_), FieldType::AccountId) => true, - (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => - fields_a.into_iter().len() == fields_b.into_iter().len() && - fields_a + (Self::Struct(_, fields_a), FieldType::Struct(_, fields_b)) => { + fields_a.into_iter().len() == fields_b.into_iter().len() + && fields_a .into_iter() .zip(fields_b) - .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)), + .all(|((_, v_a), (_, v_b))| v_a.as_ref().eq(v_b)) + }, _ => false, } } @@ -420,7 +422,7 @@ impl Field { /// Encode the fields to ethabi bytes. pub fn encode_to_ethabi(fields: &[Self]) -> ethabi::Bytes { if fields.is_empty() { - return Default::default() + return Default::default(); } let tokens: Vec = fields.iter().map(Self::to_ethabi_token).collect(); ethabi::encode(&tokens) diff --git a/primitives/src/services/mod.rs b/primitives/src/services/mod.rs index 80c9e9fc..ee4138bf 100644 --- a/primitives/src/services/mod.rs +++ b/primitives/src/services/mod.rs @@ -148,7 +148,7 @@ pub fn type_checker( return Err(TypeCheckError::NotEnoughArguments { expected: params.len() as u8, actual: args.len() as u8, - }) + }); } for i in 0..args.len() { let arg = &args[i]; @@ -158,7 +158,7 @@ pub fn type_checker( index: i as u8, expected: expected.clone(), actual: arg.clone().into(), - }) + }); } } Ok(()) @@ -472,10 +472,12 @@ impl ServiceBlueprint { }, // Master Manager Revision match self.master_manager_revision { - MasterBlueprintServiceManagerRevision::Latest => - ethabi::Token::Uint(ethabi::Uint::MAX), - MasterBlueprintServiceManagerRevision::Specific(rev) => - ethabi::Token::Uint(rev.into()), + MasterBlueprintServiceManagerRevision::Latest => { + ethabi::Token::Uint(ethabi::Uint::MAX) + }, + MasterBlueprintServiceManagerRevision::Specific(rev) => { + ethabi::Token::Uint(rev.into()) + }, }, // Gadget ? ]) diff --git a/primitives/src/verifier/circom.rs b/primitives/src/verifier/circom.rs index 34251912..4dbf7303 100644 --- a/primitives/src/verifier/circom.rs +++ b/primitives/src/verifier/circom.rs @@ -51,28 +51,28 @@ impl super::InstanceVerifier for CircomVerifierGroth16Bn254 { Ok(v) => v, Err(e) => { log::error!("Failed to convert public input bytes to field elements: {e:?}",); - return Err(e) + return Err(e); }, }; let vk = match ArkVerifyingKey::deserialize_compressed(vk_bytes) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize verifying key: {e:?}"); - return Err(e.into()) + return Err(e.into()); }, }; let proof = match Proof::decode(proof_bytes).and_then(|v| v.try_into()) { Ok(v) => v, Err(e) => { log::error!("Failed to deserialize proof: {e:?}"); - return Err(e) + return Err(e); }, }; let res = match verify_groth16(&vk, &public_input_field_elts, &proof) { Ok(v) => v, Err(e) => { log::error!("Failed to verify proof: {e:?}"); - return Err(e) + return Err(e); }, }; @@ -246,7 +246,7 @@ fn point_to_u256(point: F) -> Result { let point = point.into_bigint(); let point_bytes = point.to_bytes_be(); if point_bytes.len() != 32 { - return Err(CircomError::InvalidProofBytes.into()) + return Err(CircomError::InvalidProofBytes.into()); } Ok(U256::from(&point_bytes[..])) } diff --git a/runtime/mainnet/src/filters.rs b/runtime/mainnet/src/filters.rs index de74c9ff..1307096e 100644 --- a/runtime/mainnet/src/filters.rs +++ b/runtime/mainnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for MainnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true + return true; } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false + return false; } true diff --git a/runtime/mainnet/src/frontier_evm.rs b/runtime/mainnet/src/frontier_evm.rs index 39b31cd1..8f135bae 100644 --- a/runtime/mainnet/src/frontier_evm.rs +++ b/runtime/mainnet/src/frontier_evm.rs @@ -61,7 +61,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); } None } @@ -119,20 +119,21 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { ) -> precompile_utils::EvmResult { Ok(match self { ProxyType::Any => true, - ProxyType::Governance => - call.value == U256::zero() && - matches!( + ProxyType::Governance => { + call.value == U256::zero() + && matches!( PrecompileName::from_address(call.to.0), Some(ref precompile) if is_governance_precompile(precompile) - ), + ) + }, // The proxy precompile does not contain method cancel_proxy ProxyType::CancelProxy => false, ProxyType::Balances => { // Allow only "simple" accounts as recipient (no code nor precompile). // Note: Checking the presence of the code is not enough because some precompiles // have no code. - !recipient_has_code && - !precompile_utils::precompile_set::is_precompile_or_fail::( + !recipient_has_code + && !precompile_utils::precompile_set::is_precompile_or_fail::( call.to.0, gas, )? }, diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index dad95a92..5db6de9b 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -656,8 +656,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") % - max.saturating_add(1); + .expect("input is padded with zeroes; qed") + % max.saturating_add(1); random as usize }, }; @@ -1148,15 +1148,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) | - RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) + | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) | - RuntimeCall::Council(..) | - RuntimeCall::Elections(..) | - RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) + | RuntimeCall::Council(..) + | RuntimeCall::Elections(..) + | RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1468,8 +1468,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -1479,10 +1480,11 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))), + ))) + }, _ => None, } } diff --git a/runtime/testnet/src/filters.rs b/runtime/testnet/src/filters.rs index 65e021b6..d46f0914 100644 --- a/runtime/testnet/src/filters.rs +++ b/runtime/testnet/src/filters.rs @@ -22,14 +22,14 @@ impl Contains for TestnetCallFilter { let is_core_call = matches!(call, RuntimeCall::System(_) | RuntimeCall::Timestamp(_)); if is_core_call { // always allow core call - return true + return true; } let is_allowed_to_dispatch = as Contains>::contains(call); if !is_allowed_to_dispatch { // tx is paused and not allowed to dispatch. - return false + return false; } true diff --git a/runtime/testnet/src/frontier_evm.rs b/runtime/testnet/src/frontier_evm.rs index a11fe1f7..23fb1f1a 100644 --- a/runtime/testnet/src/frontier_evm.rs +++ b/runtime/testnet/src/frontier_evm.rs @@ -64,7 +64,7 @@ impl> FindAuthor for FindAuthorTruncated { { if let Some(author_index) = F::find_author(digests) { let authority_id = Babe::authorities()[author_index as usize].clone(); - return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])) + return Some(H160::from_slice(&authority_id.0.to_raw_vec()[4..24])); } None } @@ -99,7 +99,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return Ok(None) + return Ok(None); } // fallback to the default implementation > as OnChargeEVMTransaction< @@ -116,7 +116,7 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { let pallet_services_address = pallet_services::Pallet::::address(); // Make pallet services account free to use if who == &pallet_services_address { - return already_withdrawn + return already_withdrawn; } // fallback to the default implementation > as OnChargeEVMTransaction< diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 1a0974b5..7fb9e15b 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -663,8 +663,8 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") % - max.saturating_add(1); + .expect("input is padded with zeroes; qed") + % max.saturating_add(1); random as usize }, }; @@ -1146,15 +1146,15 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances(..) | - RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) + RuntimeCall::Balances(..) + | RuntimeCall::Vesting(pallet_vesting::Call::vested_transfer { .. }) ), ProxyType::Governance => matches!( c, - RuntimeCall::Democracy(..) | - RuntimeCall::Council(..) | - RuntimeCall::Elections(..) | - RuntimeCall::Treasury(..) + RuntimeCall::Democracy(..) + | RuntimeCall::Council(..) + | RuntimeCall::Elections(..) + | RuntimeCall::Treasury(..) ), ProxyType::Staking => { matches!(c, RuntimeCall::Staking(..)) @@ -1387,8 +1387,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { match self { - RuntimeCall::Ethereum(call) => - call.pre_dispatch_self_contained(info, dispatch_info, len), + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, _ => None, } } @@ -1398,10 +1399,11 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { info: Self::SignedInfo, ) -> Option>> { match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { Some(call.dispatch(RuntimeOrigin::from( pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))), + ))) + }, _ => None, } } From 59b2375e4678c00d94bf7fda3a2df7fbf6422f7d Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:30:25 +0530 Subject: [PATCH 22/63] cleanup clippy --- client/rpc/debug/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/rpc/debug/src/lib.rs b/client/rpc/debug/src/lib.rs index aa85097d..09b2b932 100644 --- a/client/rpc/debug/src/lib.rs +++ b/client/rpc/debug/src/lib.rs @@ -751,7 +751,9 @@ where }; if trace_api_version <= 5 { - return Err(internal_err("debug_traceCall not supported with old runtimes".to_string())); + return Err(internal_err( + "debug_traceCall not supported with old runtimes".to_string(), + )); } let TraceCallParams { From f59c794284955d5ae05459847cc4a0c72c00f1a7 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 02:41:16 +0530 Subject: [PATCH 23/63] cleanup tests --- pallets/multi-asset-delegation/src/mock.rs | 2 +- .../src/tests/delegate.rs | 12 +- .../src/tests/operator.rs | 3 +- .../src/tests/session_manager.rs | 2 +- .../src/types/delegator.rs | 222 ------------------ .../src/types/operator.rs | 118 ---------- 6 files changed, 10 insertions(+), 349 deletions(-) diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index d5d9abd4..cf20c7dc 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -302,7 +302,7 @@ parameter_types! { pub const MinOperatorBondAmount: u64 = 10_000; pub const BondDuration: u32 = 10; pub PID: PalletId = PalletId(*b"PotStake"); - pub const SlashedAmountRecipient : AccountId = mock_pub_key(ALICE).into(); + pub SlashedAmountRecipient : AccountId = Alice.to_account_id(); #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub const MaxDelegatorBlueprints : u32 = 50; #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 7fd0c479..5f93fb94 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -36,7 +36,7 @@ fn delegate_should_work() { 10_000 )); - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone().into(), amount); // Deposit first assert_ok!(MultiAssetDelegation::deposit( @@ -47,7 +47,7 @@ fn delegate_should_work() { )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone().into()), operator.into(), asset_id, amount, @@ -55,7 +55,7 @@ fn delegate_should_work() { )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.deposits.get(&asset_id).is_none()); assert_eq!(metadata.delegations.len(), 1); let delegation = &metadata.delegations[0]; @@ -83,7 +83,7 @@ fn schedule_delegator_unstake_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone().into(), amount); assert_ok!(MultiAssetDelegation::join_operators( RuntimeOrigin::signed(operator.into()), @@ -98,7 +98,7 @@ fn schedule_delegator_unstake_should_work() { None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone().into()), operator.into(), asset_id, amount, @@ -106,7 +106,7 @@ fn schedule_delegator_unstake_should_work() { )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone().into()), operator.into(), asset_id, amount, diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 69bec270..08752228 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -755,7 +755,8 @@ fn slash_delegator_fixed_blueprint_not_selected() { assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(Bob.to_account_id()), Asset::Custom(1), - 5_000 + 5_000, + None )); assert_ok!(MultiAssetDelegation::add_blueprint_id( diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index acdba2f7..6b760073 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -140,7 +140,7 @@ fn handle_round_change_with_unstake_should_work() { let snapshot2 = MultiAssetDelegation::at_stake(current_round, operator2).unwrap(); assert_eq!(snapshot2.stake, 10000); assert_eq!(snapshot2.delegations.len(), 1); - assert_eq!(snapshot2.delegations[0].delegator, delegator2); + assert_eq!(snapshot2.delegations[0].delegator, delegator2.clone()); assert_eq!(snapshot2.delegations[0].amount, amount2); assert_eq!(snapshot2.delegations[0].asset_id, asset_id); }); diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 4885c8c3..774b8f46 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -217,225 +217,3 @@ pub struct BondInfoDelegator, } - -// ------ Test for helper functions ------ // - -#[cfg(test)] -mod tests { - use super::*; - use core::ops::Add; - use frame_support::{parameter_types, BoundedVec}; - use sp_runtime::traits::Zero; - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy, Default)] - pub struct MockBalance(pub u32); - - impl Zero for MockBalance { - fn zero() -> Self { - MockBalance(0) - } - - fn is_zero(&self) -> bool { - self.0 == 0 - } - } - - impl Add for MockBalance { - type Output = Self; - - fn add(self, other: Self) -> Self { - Self(self.0 + other.0) - } - } - - impl core::ops::AddAssign for MockBalance { - fn add_assign(&mut self, other: Self) { - self.0 += other.0; - } - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy)] - pub struct MockAccountId(pub u32); - - #[derive( - Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, - )] - pub struct MockAssetId(pub u32); - - parameter_types! { - pub const MaxWithdrawRequests: u32 = 10; - pub const MaxDelegations: u32 = 10; - pub const MaxUnstakeRequests: u32 = 10; - #[derive( - Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, - )] - pub const MaxBlueprints: u32 = 10; - } - - type TestDelegatorMetadata = DelegatorMetadata< - MockAccountId, - MockBalance, - MockAssetId, - MaxWithdrawRequests, - MaxDelegations, - MaxUnstakeRequests, - MaxBlueprints, - >; - - #[test] - fn get_withdraw_requests_should_work() { - let withdraw_requests = vec![ - WithdrawRequest { - asset_id: MockAssetId(1), - amount: MockBalance(50), - requested_round: 1, - }, - WithdrawRequest { - asset_id: MockAssetId(2), - amount: MockBalance(75), - requested_round: 2, - }, - ]; - let metadata = TestDelegatorMetadata { - withdraw_requests: BoundedVec::try_from(withdraw_requests.clone()).unwrap(), - ..Default::default() - }; - - assert_eq!(metadata.get_withdraw_requests(), &withdraw_requests); - } - - #[test] - fn get_delegations_should_work() { - let delegations = vec![ - BondInfoDelegator { - operator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }, - BondInfoDelegator { - operator: MockAccountId(2), - amount: MockBalance(75), - asset_id: MockAssetId(2), - blueprint_selection: Default::default(), - }, - ]; - - let metadata = TestDelegatorMetadata { - delegations: delegations.clone().try_into().unwrap(), - ..Default::default() - }; - - assert_eq!(metadata.get_delegations(), &delegations); - } - - #[test] - fn get_delegator_unstake_requests_should_work() { - let unstake_requests = vec![ - BondLessRequest { - asset_id: MockAssetId(1), - amount: MockBalance(50), - requested_round: 1, - operator: MockAccountId(1), - blueprint_selection: Default::default(), - }, - BondLessRequest { - asset_id: MockAssetId(2), - amount: MockBalance(75), - requested_round: 2, - operator: MockAccountId(1), - blueprint_selection: Default::default(), - }, - ]; - let metadata = TestDelegatorMetadata { - delegator_unstake_requests: BoundedVec::try_from(unstake_requests.clone()).unwrap(), - ..Default::default() - }; - - assert_eq!(metadata.get_delegator_unstake_requests(), &unstake_requests); - } - - #[test] - fn is_delegations_empty_should_work() { - let metadata_with_delegations = TestDelegatorMetadata { - delegations: BoundedVec::try_from(vec![BondInfoDelegator { - operator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }]) - .unwrap(), - ..Default::default() - }; - - let metadata_without_delegations = TestDelegatorMetadata::default(); - - assert!(!metadata_with_delegations.is_delegations_empty()); - assert!(metadata_without_delegations.is_delegations_empty()); - } - - #[test] - fn calculate_delegation_by_asset_should_work() { - let delegations = vec![ - BondInfoDelegator { - operator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }, - BondInfoDelegator { - operator: MockAccountId(2), - amount: MockBalance(75), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }, - BondInfoDelegator { - operator: MockAccountId(3), - amount: MockBalance(25), - asset_id: MockAssetId(2), - blueprint_selection: Default::default(), - }, - ]; - let metadata = TestDelegatorMetadata { - delegations: BoundedVec::try_from(delegations).unwrap(), - ..Default::default() - }; - - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(1)), MockBalance(125)); - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(2)), MockBalance(25)); - assert_eq!(metadata.calculate_delegation_by_asset(MockAssetId(3)), MockBalance(0)); - } - - #[test] - fn calculate_delegation_by_operator_should_work() { - let delegations = vec![ - BondInfoDelegator { - operator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }, - BondInfoDelegator { - operator: MockAccountId(1), - amount: MockBalance(75), - asset_id: MockAssetId(2), - blueprint_selection: Default::default(), - }, - BondInfoDelegator { - operator: MockAccountId(2), - amount: MockBalance(25), - asset_id: MockAssetId(1), - blueprint_selection: Default::default(), - }, - ]; - let metadata = TestDelegatorMetadata { - delegations: BoundedVec::try_from(delegations).unwrap(), - ..Default::default() - }; - - let result = metadata.calculate_delegation_by_operator(MockAccountId(1)); - assert_eq!(result.len(), 2); - assert_eq!(result[0].operator, MockAccountId(1)); - assert_eq!(result[1].operator, MockAccountId(1)); - } -} diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 88f81670..e0e7ca27 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -137,121 +137,3 @@ pub struct DelegatorBond { /// The ID of the bonded asset. pub asset_id: Asset, } - -// ------ Test for helper functions ------ // - -#[cfg(test)] -mod tests { - use super::*; - use core::ops::Add; - use frame_support::{parameter_types, BoundedVec}; - use sp_runtime::traits::Zero; - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy, Default)] - pub struct MockBalance(pub u32); - - impl Zero for MockBalance { - fn zero() -> Self { - MockBalance(0) - } - - fn is_zero(&self) -> bool { - self.0 == 0 - } - } - - impl Add for MockBalance { - type Output = Self; - - fn add(self, other: Self) -> Self { - Self(self.0 + other.0) - } - } - - impl core::ops::AddAssign for MockBalance { - fn add_assign(&mut self, other: Self) { - self.0 += other.0; - } - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy)] - pub struct MockAccountId(pub u32); - - #[derive( - Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, - )] - pub struct MockAssetId(pub u32); - - parameter_types! { - pub const MaxDelegators: u32 = 10; - pub const MaxUnstakeRequests: u32 = 10; - pub const MaxBlueprints: u32 = 10; - } - - #[test] - fn get_stake_by_asset_id_should_work() { - let snapshot: OperatorSnapshot = - OperatorSnapshot { - stake: MockBalance(100), - delegations: BoundedVec::try_from(vec![ - DelegatorBond { - delegator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - }, - DelegatorBond { - delegator: MockAccountId(2), - amount: MockBalance(75), - asset_id: MockAssetId(1), - }, - DelegatorBond { - delegator: MockAccountId(3), - amount: MockBalance(25), - asset_id: MockAssetId(2), - }, - ]) - .unwrap(), - }; - - assert_eq!(snapshot.get_stake_by_asset_id(MockAssetId(1)).0, 125); - assert_eq!(snapshot.get_stake_by_asset_id(MockAssetId(2)).0, 25); - assert_eq!(snapshot.get_stake_by_asset_id(MockAssetId(3)).0, 0); - } - - #[test] - fn get_total_stake_by_assets_should_work() { - let snapshot: OperatorSnapshot = - OperatorSnapshot { - stake: MockBalance(100), - delegations: BoundedVec::try_from(vec![ - DelegatorBond { - delegator: MockAccountId(1), - amount: MockBalance(50), - asset_id: MockAssetId(1), - }, - DelegatorBond { - delegator: MockAccountId(2), - amount: MockBalance(75), - asset_id: MockAssetId(1), - }, - DelegatorBond { - delegator: MockAccountId(3), - amount: MockBalance(25), - asset_id: MockAssetId(2), - }, - DelegatorBond { - delegator: MockAccountId(4), - amount: MockBalance(100), - asset_id: MockAssetId(2), - }, - ]) - .unwrap(), - }; - - let result = snapshot.get_total_stake_by_assets(); - let expected_result = - vec![(MockAssetId(1), MockBalance(125)), (MockAssetId(2), MockBalance(125))]; - - assert_eq!(result, expected_result); - } -} From 0e72e7452ad556e1e39a8040164a255ce76bbe39 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 02:49:26 +0530 Subject: [PATCH 24/63] cleanup tests --- pallets/multi-asset-delegation/src/mock.rs | 2 +- .../src/tests/delegate.rs | 152 +++++++++--------- .../src/tests/deposit.rs | 111 +++++++------ .../src/tests/session_manager.rs | 46 +++--- 4 files changed, 158 insertions(+), 153 deletions(-) diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index cf20c7dc..99c4f2f5 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -302,7 +302,7 @@ parameter_types! { pub const MinOperatorBondAmount: u64 = 10_000; pub const BondDuration: u32 = 10; pub PID: PalletId = PalletId(*b"PotStake"); - pub SlashedAmountRecipient : AccountId = Alice.to_account_id(); + pub SlashedAmountRecipient : AccountId = ALICE.into(); #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub const MaxDelegatorBlueprints : u32 = 50; #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 5f93fb94..1f6940c8 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -32,23 +32,23 @@ fn delegate_should_work() { let amount = 100; assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); - create_and_mint_tokens(VDOT, who.clone().into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone().into()), - operator.into(), + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() @@ -59,7 +59,7 @@ fn delegate_should_work() { assert!(metadata.deposits.get(&asset_id).is_none()); assert_eq!(metadata.delegations.len(), 1); let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator.into()); + assert_eq!(delegation.operator, operator.clone()); assert_eq!(delegation.amount, amount); assert_eq!(delegation.asset_id, asset_id); @@ -68,7 +68,7 @@ fn delegate_should_work() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.into()); + assert_eq!(operator_delegation.delegator, who.clone()); assert_eq!(operator_delegation.amount, amount); assert_eq!(operator_delegation.asset_id, asset_id); }); @@ -83,31 +83,31 @@ fn schedule_delegator_unstake_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.clone().into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit and delegate first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone().into()), - operator.into(), + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone().into()), - operator.into(), + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, )); @@ -136,30 +136,30 @@ fn execute_delegator_unstake_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, )); @@ -168,7 +168,7 @@ fn execute_delegator_unstake_should_work() { CurrentRound::::put(10); assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed( - who.into() + who.clone() ),)); // Assert @@ -188,31 +188,31 @@ fn cancel_delegator_unstake_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, )); @@ -231,8 +231,8 @@ fn cancel_delegator_unstake_should_work() { assert_eq!(operator_metadata.delegations.len(), 0); assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount )); @@ -247,7 +247,7 @@ fn cancel_delegator_unstake_should_work() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who); + assert_eq!(operator_delegation.delegator, who.clone()); assert_eq!(operator_delegation.amount, amount); // Amount added back assert_eq!(operator_delegation.asset_id, asset_id); }); @@ -262,31 +262,31 @@ fn cancel_delegator_unstake_should_update_already_existing() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, 10, )); @@ -304,13 +304,13 @@ fn cancel_delegator_unstake_should_update_already_existing() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who); + assert_eq!(operator_delegation.delegator, who.clone()); assert_eq!(operator_delegation.amount, amount - 10); assert_eq!(operator_delegation.asset_id, asset_id); assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, 10 )); @@ -325,7 +325,7 @@ fn cancel_delegator_unstake_should_update_already_existing() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who); + assert_eq!(operator_delegation.delegator, who.clone()); assert_eq!(operator_delegation.amount, amount); // Amount added back assert_eq!(operator_delegation.asset_id, asset_id); }); @@ -340,15 +340,15 @@ fn delegate_should_fail_if_not_enough_balance() { let asset_id = Asset::Custom(VDOT); let amount = 10_000; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount - 20, None @@ -356,8 +356,8 @@ fn delegate_should_fail_if_not_enough_balance() { assert_noop!( MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() @@ -376,16 +376,16 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None @@ -393,8 +393,8 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { assert_noop!( MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, ), @@ -412,23 +412,23 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who.into(), amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() @@ -436,8 +436,8 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { assert_noop!( MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount ), @@ -445,14 +445,14 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { ); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, )); assert_noop!( - MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who.into()),), + MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who.clone()),), Error::::BondLessNotReady ); }); @@ -469,15 +469,15 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { let additional_amount = 50; assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.into()), + RuntimeOrigin::signed(operator.clone()), 10_000 )); - create_and_mint_tokens(VDOT, who, amount + additional_amount); + create_and_mint_tokens(VDOT, who.clone(), amount + additional_amount); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.into()), + RuntimeOrigin::signed(who.clone()), asset_id, amount + additional_amount, None @@ -485,19 +485,19 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { // Delegate first time assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() )); // Assert first delegation - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.deposits.get(&asset_id).is_some()); assert_eq!(metadata.delegations.len(), 1); let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator); + assert_eq!(delegation.operator, operator.clone()); assert_eq!(delegation.amount, amount); assert_eq!(delegation.asset_id, asset_id); @@ -506,25 +506,25 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who); + assert_eq!(operator_delegation.delegator, who.clone()); assert_eq!(operator_delegation.amount, amount); assert_eq!(operator_delegation.asset_id, asset_id); // Delegate additional amount assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.into()), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, additional_amount, Default::default() )); // Assert updated delegation - let updated_metadata = MultiAssetDelegation::delegators(who).unwrap(); + let updated_metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(updated_metadata.deposits.get(&asset_id).is_none()); assert_eq!(updated_metadata.delegations.len(), 1); let updated_delegation = &updated_metadata.delegations[0]; - assert_eq!(updated_delegation.operator, operator); + assert_eq!(updated_delegation.operator, operator.clone()); assert_eq!(updated_delegation.amount, amount + additional_amount); assert_eq!(updated_delegation.asset_id, asset_id); @@ -533,7 +533,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_operator_metadata.delegation_count, 1); assert_eq!(updated_operator_metadata.delegations.len(), 1); let updated_operator_delegation = &updated_operator_metadata.delegations[0]; - assert_eq!(updated_operator_delegation.delegator, who); + assert_eq!(updated_operator_delegation.delegator, who.clone()); assert_eq!(updated_operator_delegation.amount, amount + additional_amount); assert_eq!(updated_operator_delegation.asset_id, asset_id); }); diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 684a8d06..16ba8339 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -26,8 +26,8 @@ pub fn create_and_mint_tokens( recipient: ::AccountId, amount: Balance, ) { - assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient, false, 1)); - assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient), asset_id, recipient, amount)); + assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient.clone(), false, 1)); + assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient.clone()), asset_id, recipient, amount)); } pub fn mint_tokens( @@ -46,22 +46,22 @@ fn deposit_should_work_for_fungible_asset() { let who: AccountId = Bob.into(); let amount = 200; - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, None )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who, + who: who.clone(), amount, asset_id: Asset::Custom(VDOT), }) @@ -76,41 +76,41 @@ fn multiple_deposit_should_work() { let who: AccountId = Bob.into(); let amount = 200; - create_and_mint_tokens(VDOT, who, amount * 4); + create_and_mint_tokens(VDOT, who.clone(), amount * 4); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, None )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who, + who: who.clone(), amount, asset_id: Asset::Custom(VDOT), }) ); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, None )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount * 2).as_ref()); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount * 2)); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who, + who: who.clone(), amount, asset_id: Asset::Custom(VDOT), }) @@ -125,11 +125,11 @@ fn deposit_should_fail_for_insufficient_balance() { let who: AccountId = Bob.into(); let amount = 2000; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); assert_noop!( MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, None @@ -146,11 +146,11 @@ fn deposit_should_fail_for_bond_too_low() { let who: AccountId = Bob.into(); let amount = 50; // Below the minimum stake amount - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.clone(), amount); assert_noop!( MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, None @@ -168,24 +168,24 @@ fn schedule_withdraw_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert_eq!(metadata.deposits.get(&asset_id), None); assert!(!metadata.withdraw_requests.is_empty()); let request = metadata.withdraw_requests.first().unwrap(); @@ -202,10 +202,10 @@ fn schedule_withdraw_should_fail_if_not_delegator() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); assert_noop!( - MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who), asset_id, amount,), + MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount,), Error::::NotDelegator ); }); @@ -219,13 +219,18 @@ fn schedule_withdraw_should_fail_for_insufficient_balance() { let asset_id = Asset::Custom(VDOT); let amount = 200; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit first - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(who), asset_id, 100, None)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + 100, + None + )); assert_noop!( - MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who), asset_id, amount,), + MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount,), Error::::InsufficientBalance ); }); @@ -239,11 +244,11 @@ fn schedule_withdraw_should_fail_if_withdraw_request_exists() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None @@ -251,7 +256,7 @@ fn schedule_withdraw_should_fail_if_withdraw_request_exists() { // Schedule the first withdraw assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, )); @@ -266,17 +271,17 @@ fn execute_withdraw_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit and schedule withdraw first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, )); @@ -285,15 +290,15 @@ fn execute_withdraw_should_work() { let current_round = 1; >::put(current_round); - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None)); + assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None)); // Assert - let metadata = MultiAssetDelegation::delegators(who); + let metadata = MultiAssetDelegation::delegators(who.clone()); assert!(metadata.unwrap().withdraw_requests.is_empty()); // Check event System::assert_last_event(RuntimeEvent::MultiAssetDelegation( - crate::Event::Executedwithdraw { who }, + crate::Event::Executedwithdraw { who: who.clone() }, )); }); } @@ -305,7 +310,7 @@ fn execute_withdraw_should_fail_if_not_delegator() { let who: AccountId = Bob.into(); assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None), + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), Error::::NotDelegator ); }); @@ -319,18 +324,18 @@ fn execute_withdraw_should_fail_if_no_withdraw_request() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None), + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), Error::::NowithdrawRequests ); }); @@ -344,17 +349,17 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit and schedule withdraw first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, )); @@ -364,9 +369,9 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { >::put(current_round); // should not actually withdraw anything - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who), None)); + assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None)); - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(!metadata.withdraw_requests.is_empty()); }); } @@ -379,36 +384,36 @@ fn cancel_withdraw_should_work() { let asset_id = Asset::Custom(VDOT); let amount = 100; - create_and_mint_tokens(VDOT, who, 100); + create_and_mint_tokens(VDOT, who.clone(), 100); // Deposit and schedule withdraw first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, )); assert_ok!(MultiAssetDelegation::cancel_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount )); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.withdraw_requests.is_empty()); assert_eq!(metadata.deposits.get(&asset_id), Some(&amount)); assert_eq!(metadata.status, DelegatorStatus::Active); // Check event System::assert_last_event(RuntimeEvent::MultiAssetDelegation( - crate::Event::Cancelledwithdraw { who }, + crate::Event::Cancelledwithdraw { who: who.clone() }, )); }); } @@ -421,7 +426,7 @@ fn cancel_withdraw_should_fail_if_not_delegator() { assert_noop!( MultiAssetDelegation::cancel_withdraw( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), 1 ), @@ -449,7 +454,7 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { )); assert_noop!( - MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who), asset_id, amount), + MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount), Error::::NoMatchingwithdrawRequest ); }); diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 6b760073..5b3d6dc9 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -30,21 +30,21 @@ fn handle_round_change_should_work() { CurrentRound::::put(1); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator.clone()), 10_000)); - create_and_mint_tokens(VDOT, who, amount); + create_and_mint_tokens(VDOT, who.clone(), amount); // Deposit first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who), + RuntimeOrigin::signed(who.clone()), asset_id, amount, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who), - operator, + RuntimeOrigin::signed(who.clone()), + operator.clone(), asset_id, amount, Default::default() @@ -56,7 +56,7 @@ fn handle_round_change_should_work() { let current_round = MultiAssetDelegation::current_round(); assert_eq!(current_round, 2); - let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator).unwrap(); + let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator.clone()).unwrap(); assert_eq!(snapshot1.stake, 10_000); assert_eq!(snapshot1.delegations.len(), 1); assert_eq!(snapshot1.delegations[0].amount, amount); @@ -73,42 +73,42 @@ fn handle_round_change_with_unstake_should_work() { let operator1 = Charlie.to_account_id(); let operator2 = Dave.to_account_id(); let asset_id = Asset::Custom(VDOT); - let amount1 = 100; - let amount2 = 200; + let amount1 = 1_000_000_000_000; + let amount2 = 1_000_000_000_000; let unstake_amount = 50; CurrentRound::::put(1); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator1), 10_000)); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator2), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator1.clone()), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator2.clone()), 10_000)); - create_and_mint_tokens(VDOT, delegator1, amount1); - mint_tokens(delegator1, VDOT, delegator2, amount2); + create_and_mint_tokens(VDOT, delegator1.clone(), amount1); + mint_tokens(delegator1.clone(), VDOT, delegator2.clone(), amount2); // Deposit and delegate first assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1), + RuntimeOrigin::signed(delegator1.clone()), asset_id, amount1, None, )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator1), - operator1, + RuntimeOrigin::signed(delegator1.clone()), + operator1.clone(), asset_id, amount1, Default::default() )); assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2), + RuntimeOrigin::signed(delegator2.clone()), asset_id, amount2, None )); assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator2), - operator2, + RuntimeOrigin::signed(delegator2.clone()), + operator2.clone(), asset_id, amount2, Default::default() @@ -116,8 +116,8 @@ fn handle_round_change_with_unstake_should_work() { // Delegator1 schedules unstake assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(delegator1), - operator1, + RuntimeOrigin::signed(delegator1.clone()), + operator1.clone(), asset_id, unstake_amount, )); @@ -129,15 +129,15 @@ fn handle_round_change_with_unstake_should_work() { assert_eq!(current_round, 2); // Check the snapshot for operator1 - let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator1).unwrap(); + let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator1.clone()).unwrap(); assert_eq!(snapshot1.stake, 10_000); assert_eq!(snapshot1.delegations.len(), 1); - assert_eq!(snapshot1.delegations[0].delegator, delegator1); + assert_eq!(snapshot1.delegations[0].delegator, delegator1.clone()); assert_eq!(snapshot1.delegations[0].amount, amount1 - unstake_amount); // Amount reduced by unstake_amount assert_eq!(snapshot1.delegations[0].asset_id, asset_id); // Check the snapshot for operator2 - let snapshot2 = MultiAssetDelegation::at_stake(current_round, operator2).unwrap(); + let snapshot2 = MultiAssetDelegation::at_stake(current_round, operator2.clone()).unwrap(); assert_eq!(snapshot2.stake, 10000); assert_eq!(snapshot2.delegations.len(), 1); assert_eq!(snapshot2.delegations[0].delegator, delegator2.clone()); From ec342415edafba22304971f9bca6cd08fd9070d5 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 02:49:39 +0530 Subject: [PATCH 25/63] cleanup fmt --- .../src/tests/deposit.rs | 28 +++++++++++++++---- .../src/tests/session_manager.rs | 15 ++++++++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 16ba8339..193e1e2b 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -205,7 +205,11 @@ fn schedule_withdraw_should_fail_if_not_delegator() { create_and_mint_tokens(VDOT, who.clone(), 100); assert_noop!( - MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount,), + MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + ), Error::::NotDelegator ); }); @@ -230,7 +234,11 @@ fn schedule_withdraw_should_fail_for_insufficient_balance() { )); assert_noop!( - MultiAssetDelegation::schedule_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount,), + MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + ), Error::::InsufficientBalance ); }); @@ -290,7 +298,10 @@ fn execute_withdraw_should_work() { let current_round = 1; >::put(current_round); - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None)); + assert_ok!(MultiAssetDelegation::execute_withdraw( + RuntimeOrigin::signed(who.clone()), + None + )); // Assert let metadata = MultiAssetDelegation::delegators(who.clone()); @@ -369,7 +380,10 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { >::put(current_round); // should not actually withdraw anything - assert_ok!(MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None)); + assert_ok!(MultiAssetDelegation::execute_withdraw( + RuntimeOrigin::signed(who.clone()), + None + )); let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(!metadata.withdraw_requests.is_empty()); @@ -454,7 +468,11 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { )); assert_noop!( - MultiAssetDelegation::cancel_withdraw(RuntimeOrigin::signed(who.clone()), asset_id, amount), + MultiAssetDelegation::cancel_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount + ), Error::::NoMatchingwithdrawRequest ); }); diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 5b3d6dc9..8e7c5558 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -30,7 +30,10 @@ fn handle_round_change_should_work() { CurrentRound::::put(1); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator.clone()), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); create_and_mint_tokens(VDOT, who.clone(), amount); @@ -79,8 +82,14 @@ fn handle_round_change_with_unstake_should_work() { CurrentRound::::put(1); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator1.clone()), 10_000)); - assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(operator2.clone()), 10_000)); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator1.clone()), + 10_000 + )); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator2.clone()), + 10_000 + )); create_and_mint_tokens(VDOT, delegator1.clone(), amount1); mint_tokens(delegator1.clone(), VDOT, delegator2.clone(), amount2); From 99c6b086eb1ee44451510be7b03bcb02db17a99e Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:24:55 +0530 Subject: [PATCH 26/63] more tests passing --- .../src/functions/deposit.rs | 2 +- pallets/multi-asset-delegation/src/mock.rs | 88 +++++++++++-------- .../src/tests/delegate.rs | 83 ++++++++--------- .../src/tests/deposit.rs | 2 +- .../src/tests/operator.rs | 6 +- 5 files changed, 100 insertions(+), 81 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 08cff321..0f3b572b 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -55,7 +55,7 @@ impl Pallet { &Self::pallet_account(), amount, Preservation::Expendable, - ); + )?; }, Asset::Erc20(asset_address) => { let sender = evm_sender.ok_or(Error::::ERC20TransferFailed)?; diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 99c4f2f5..a82c6812 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -36,6 +36,7 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use serde_json::json; use sp_core::{sr25519, H160}; +use sp_keyring::AccountKeyring; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; use sp_runtime::{ testing::UintAuthorityId, @@ -52,9 +53,6 @@ pub type Balance = u128; type Nonce = u32; pub type AssetId = u128; -// AssetIds for tests -pub const VDOT: AssetId = 1; - // AccountIds for tests pub const ALICE: u8 = 1; pub const BOB: u8 = 2; @@ -302,7 +300,7 @@ parameter_types! { pub const MinOperatorBondAmount: u64 = 10_000; pub const BondDuration: u32 = 10; pub PID: PalletId = PalletId(*b"PotStake"); - pub SlashedAmountRecipient : AccountId = ALICE.into(); + pub SlashedAmountRecipient : AccountId = AccountKeyring::Alice.into(); #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub const MaxDelegatorBlueprints : u32 = 50; #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] @@ -399,18 +397,31 @@ pub const CGGMP21_BLUEPRINT: H160 = H160([0x21; 20]); pub const HOOKS_TEST: H160 = H160([0x22; 20]); pub const USDC_ERC20: H160 = H160([0x23; 20]); -pub const TNT: AssetId = 0; pub const USDC: AssetId = 1; pub const WETH: AssetId = 2; pub const WBTC: AssetId = 3; +pub const VDOT: AssetId = 4; // This function basically just builds a genesis storage key/value store according to // our desired mockup. pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); // We use default for brevity, but you can configure as desired if needed. - let authorities = vec![mock_pub_key(1), mock_pub_key(2), mock_pub_key(3)]; - let balances: Vec<_> = authorities.iter().map(|i| (i.clone(), 20_000_u128)).collect(); + let authorities: Vec = vec![ + AccountKeyring::Alice.into(), + AccountKeyring::Bob.into(), + AccountKeyring::Charlie.into(), + ]; + let mut balances: Vec<_> = authorities.iter().map(|i| (i.clone(), 200_000_u128)).collect(); + + // Add test accounts with enough balance + let test_accounts = vec![ + AccountKeyring::Dave.into(), + AccountKeyring::Eve.into(), + MultiAssetDelegation::pallet_account(), + ]; + balances.extend(test_accounts.iter().map(|i: &AccountId| (i.clone(), 1_000_000_u128))); + pallet_balances::GenesisConfig:: { balances } .assimilate_storage(&mut t) .unwrap(); @@ -464,34 +475,41 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { evm_config.assimilate_storage(&mut t).unwrap(); - let assets_config = pallet_assets::GenesisConfig:: { - assets: vec![ - (USDC, authorities[0].clone(), true, 100_000), // 1 cent. - (WETH, authorities[1].clone(), true, 100), // 100 wei. - (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. - ], - metadata: vec![ - (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), - (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), - (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), - ], - accounts: vec![ - (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), - (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), - (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), - // - (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), - (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), - (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), - // - (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), - (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), - (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), - ], - next_asset_id: Some(4), - }; - - assets_config.assimilate_storage(&mut t).unwrap(); + // let assets_config = pallet_assets::GenesisConfig:: { + // assets: vec![ + // (USDC, authorities[0].clone(), true, 100_000), // 1 cent. + // (WETH, authorities[1].clone(), true, 100), // 100 wei. + // (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. + // (VDOT, authorities[0].clone(), true, 100), + // ], + // metadata: vec![ + // (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), + // (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), + // (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), + // (VDOT, Vec::from(b"VeChain"), Vec::from(b"VDOT"), 18), + // ], + // accounts: vec![ + // (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), + // // + // (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), + // // + // (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), + + // // + // (VDOT, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), + // (VDOT, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), + // (VDOT, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), + // ], + // next_asset_id: Some(4), + // }; + + // assets_config.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); ext.execute_with(|| System::set_block_number(1)); diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 1f6940c8..0a35b4f8 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -41,7 +41,7 @@ fn delegate_should_work() { // Deposit first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); @@ -49,7 +49,7 @@ fn delegate_should_work() { assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -64,7 +64,7 @@ fn delegate_should_work() { assert_eq!(delegation.asset_id, asset_id); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; @@ -93,14 +93,14 @@ fn schedule_delegator_unstake_should_work() { // Deposit and delegate first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -108,20 +108,20 @@ fn schedule_delegator_unstake_should_work() { assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, )); // Assert // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(!metadata.delegator_unstake_requests.is_empty()); let request = &metadata.delegator_unstake_requests[0]; assert_eq!(request.asset_id, asset_id); assert_eq!(request.amount, amount); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 0); assert_eq!(operator_metadata.delegations.len(), 0); }); @@ -146,21 +146,21 @@ fn execute_delegator_unstake_should_work() { // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, )); @@ -172,7 +172,7 @@ fn execute_delegator_unstake_should_work() { ),)); // Assert - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.delegator_unstake_requests.is_empty()); assert!(metadata.deposits.get(&asset_id).is_some()); assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); @@ -198,14 +198,14 @@ fn cancel_delegator_unstake_should_work() { // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -213,37 +213,37 @@ fn cancel_delegator_unstake_should_work() { assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, )); // Assert // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(!metadata.delegator_unstake_requests.is_empty()); let request = &metadata.delegator_unstake_requests[0]; assert_eq!(request.asset_id, asset_id); assert_eq!(request.amount, amount); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 0); assert_eq!(operator_metadata.delegations.len(), 0); assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount )); // Assert // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.delegator_unstake_requests.is_empty()); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; @@ -272,14 +272,14 @@ fn cancel_delegator_unstake_should_update_already_existing() { // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -287,20 +287,20 @@ fn cancel_delegator_unstake_should_update_already_existing() { assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), 10, )); // Assert // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(!metadata.delegator_unstake_requests.is_empty()); let request = &metadata.delegator_unstake_requests[0]; assert_eq!(request.asset_id, asset_id); assert_eq!(request.amount, 10); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; @@ -311,17 +311,17 @@ fn cancel_delegator_unstake_should_update_already_existing() { assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), 10 )); // Assert // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who).unwrap(); + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.delegator_unstake_requests.is_empty()); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; @@ -349,7 +349,7 @@ fn delegate_should_fail_if_not_enough_balance() { assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount - 20, None )); @@ -358,7 +358,7 @@ fn delegate_should_fail_if_not_enough_balance() { MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() ), @@ -386,7 +386,7 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { // Deposit first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); @@ -395,7 +395,7 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, ), Error::::NoActiveDelegation @@ -422,14 +422,14 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { // Deposit, delegate and schedule unstake first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount, None )); assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -438,7 +438,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { MultiAssetDelegation::cancel_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount ), Error::::NoBondLessRequest @@ -447,7 +447,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, )); @@ -478,7 +478,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { // Deposit first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(who.clone()), - asset_id, + asset_id.clone(), amount + additional_amount, None )); @@ -487,7 +487,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), amount, Default::default() )); @@ -502,7 +502,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(delegation.asset_id, asset_id); // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(operator_metadata.delegation_count, 1); assert_eq!(operator_metadata.delegations.len(), 1); let operator_delegation = &operator_metadata.delegations[0]; @@ -514,7 +514,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(who.clone()), operator.clone(), - asset_id, + asset_id.clone(), additional_amount, Default::default() )); @@ -529,7 +529,8 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_delegation.asset_id, asset_id); // Check the updated operator metadata - let updated_operator_metadata = MultiAssetDelegation::operator_info(operator).unwrap(); + let updated_operator_metadata = + MultiAssetDelegation::operator_info(operator.clone()).unwrap(); assert_eq!(updated_operator_metadata.delegation_count, 1); assert_eq!(updated_operator_metadata.delegations.len(), 1); let updated_operator_delegation = &updated_operator_metadata.delegations[0]; diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 193e1e2b..9a99faa5 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -106,7 +106,7 @@ fn multiple_deposit_should_work() { // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount * 2)); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&(amount * 2))); assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 08752228..7a53c260 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -83,11 +83,11 @@ fn join_operator_insufficient_bond() { #[test] fn join_operator_insufficient_funds() { new_test_ext().execute_with(|| { - let bond_amount = 15_000; // User 4 has only 5_000 + let bond_amount = 350_000; // User 4 has only 200_000 assert_noop!( MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Eve.to_account_id()), + RuntimeOrigin::signed(Alice.to_account_id()), bond_amount ), pallet_balances::Error::::InsufficientBalance @@ -259,7 +259,7 @@ fn operator_bond_more_not_an_operator() { fn operator_bond_more_insufficient_balance() { new_test_ext().execute_with(|| { let bond_amount = 10_000; - let additional_bond = 115_000; // Exceeds available balance + let additional_bond = 1150_000; // Exceeds available balance // Join operator first assert_ok!(MultiAssetDelegation::join_operators( From eeb5487cc468056deedfd9f73952ceef95610487 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:38:47 +0530 Subject: [PATCH 27/63] cleanup clippy --- .../src/functions/delegate.rs | 15 +- .../src/functions/deposit.rs | 18 +- pallets/multi-asset-delegation/src/mock.rs | 7 +- .../multi-asset-delegation/src/mock_evm.rs | 1 - .../src/tests/delegate.rs | 6 +- .../src/tests/deposit.rs | 2 +- .../src/tests/operator.rs | 37 +- .../src/tests/session_manager.rs | 2 +- pallets/services/src/mock.rs | 6 +- pallets/services/src/mock_evm.rs | 4 +- precompiles/multi-asset-delegation/Cargo.toml | 81 ++++- precompiles/multi-asset-delegation/src/lib.rs | 8 +- .../multi-asset-delegation/src/mock_evm.rs | 329 ++++++++++++++++++ precompiles/services/src/lib.rs | 6 +- precompiles/services/src/mock.rs | 6 +- precompiles/services/src/mock_evm.rs | 7 +- 16 files changed, 464 insertions(+), 71 deletions(-) create mode 100644 precompiles/multi-asset-delegation/src/mock_evm.rs diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 03c95e66..43342f6b 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -25,6 +25,7 @@ use sp_runtime::{ DispatchError, Percent, }; use sp_std::vec::Vec; +use tangle_primitives::services::EvmAddressMapping; use tangle_primitives::{services::Asset, BlueprintId}; impl Pallet { @@ -403,10 +404,16 @@ impl Pallet { ); }, Asset::Erc20(address) => { - // TODO : Handle it - // let (success, _weight) = - // Self::erc20_transfer(address, &caller, Self::address(), value)?; - // ensure!(success, Error::::ERC20TransferFailed); + let slashed_amount_recipient_evm = + T::EvmAddressMapping::into_address(T::SlashedAmountRecipient::get()); + let (success, _weight) = Self::erc20_transfer( + address, + &Self::pallet_evm_account(), + slashed_amount_recipient_evm, + slash_amount, + ) + .map_err(|e| Error::::ERC20TransferFailed)?; + ensure!(success, Error::::ERC20TransferFailed); }, } diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 0f3b572b..b2f36302 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -179,9 +179,11 @@ impl Pallet { let delay = T::LeaveDelegatorsDelay::get(); // Process all ready withdraw requests - metadata.withdraw_requests.retain(|request| { + let mut i = 0; + while i < metadata.withdraw_requests.len() { + let request = &metadata.withdraw_requests[i]; if current_round >= delay + request.requested_round { - match request.asset_id { + let transfer_success = match request.asset_id { Asset::Custom(asset_id) => T::Fungibles::transfer( asset_id, &Self::pallet_account(), @@ -206,11 +208,19 @@ impl Pallet { false } }, + }; + + if transfer_success { + // Remove the completed request + metadata.withdraw_requests.remove(i); + } else { + // Only increment if we didn't remove the request + i += 1; } } else { - true + i += 1; } - }); + } Ok(()) }) diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index a82c6812..a633decd 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -28,7 +28,6 @@ use frame_support::{ traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, PalletId, }; -use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; @@ -40,10 +39,10 @@ use sp_keyring::AccountKeyring; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; use sp_runtime::{ testing::UintAuthorityId, - traits::{ConstU64, ConvertInto, IdentityLookup}, + traits::{ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; -use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner, RunnerError}; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; use core::ops::Mul; use std::{collections::BTreeMap, sync::Arc}; @@ -428,7 +427,7 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { let mut evm_accounts = BTreeMap::new(); - let mut create_contract = |bytecode: &str, address: H160| { + let create_contract = |bytecode: &str, address: H160| { let mut raw_hex = bytecode.replace("0x", "").replace("\n", ""); // fix odd length if raw_hex.len() % 2 != 0 { diff --git a/pallets/multi-asset-delegation/src/mock_evm.rs b/pallets/multi-asset-delegation/src/mock_evm.rs index ece3807a..f9d9646a 100644 --- a/pallets/multi-asset-delegation/src/mock_evm.rs +++ b/pallets/multi-asset-delegation/src/mock_evm.rs @@ -35,7 +35,6 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionValidityError}, ConsensusEngineId, }; -use tangle_primitives::services::{EvmRunner, RunnerError}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 0a35b4f8..92a7316d 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -15,11 +15,9 @@ // along with Tangle. If not, see . #![allow(clippy::all)] use super::*; -use crate::{types::*, CurrentRound, Error}; +use crate::{CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie, One, Two}; -use sp_runtime::Percent; -use std::collections::BTreeMap; +use sp_keyring::AccountKeyring::{Alice, Bob}; use tangle_primitives::services::Asset; #[test] diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 9a99faa5..88105005 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -16,7 +16,7 @@ use super::*; use crate::{types::DelegatorStatus, CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie, One, Two}; +use sp_keyring::AccountKeyring::Bob; use sp_runtime::ArithmeticError; use tangle_primitives::services::Asset; diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 7a53c260..210b49f4 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -19,7 +19,7 @@ use crate::{ CurrentRound, Error, }; use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve}; +use sp_keyring::AccountKeyring::{Alice, Bob, Eve}; use sp_runtime::Percent; use tangle_primitives::services::Asset; @@ -259,7 +259,7 @@ fn operator_bond_more_not_an_operator() { fn operator_bond_more_insufficient_balance() { new_test_ext().execute_with(|| { let bond_amount = 10_000; - let additional_bond = 1150_000; // Exceeds available balance + let additional_bond = 1_150_000; // Exceeds available balance // Join operator first assert_ok!(MultiAssetDelegation::join_operators( @@ -651,22 +651,6 @@ fn slash_operator_success() { Fixed(vec![blueprint_id].try_into().unwrap()), )); - // Setup delegator with all blueprints - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(Bob.to_account_id()), - asset_id, - delegator_stake, - None - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(Bob.to_account_id()), - Alice.to_account_id(), - asset_id, - delegator_stake, - Fixed(vec![blueprint_id].try_into().unwrap()), - )); - // Slash 50% of stakes let slash_percentage = Percent::from_percent(50); assert_ok!(MultiAssetDelegation::slash_operator( @@ -679,23 +663,14 @@ fn slash_operator_success() { let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); assert_eq!(operator_info.stake, operator_stake / 2); - // Verify fixed delegator stake was slashed - let delegator_2 = MultiAssetDelegation::delegators(Charlie.to_account_id()).unwrap(); - let delegation_2 = delegator_2 - .delegations - .iter() - .find(|d| d.operator == Alice.to_account_id()) - .unwrap(); - assert_eq!(delegation_2.amount, delegator_stake / 2); - - // Verify all-blueprints delegator stake was slashed - let delegator_3 = MultiAssetDelegation::delegators(Charlie.to_account_id()).unwrap(); - let delegation_3 = delegator_3 + // Verify delegator stake was slashed + let delegator = MultiAssetDelegation::delegators(Bob.to_account_id()).unwrap(); + let delegation = delegator .delegations .iter() .find(|d| d.operator == Alice.to_account_id()) .unwrap(); - assert_eq!(delegation_3.amount, delegator_stake / 2); + assert_eq!(delegation.amount, delegator_stake / 2); // Verify event System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorSlashed { diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 8e7c5558..7174d5f5 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -16,7 +16,7 @@ use super::*; use crate::CurrentRound; use frame_support::assert_ok; -use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave, Eve}; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave}; use tangle_primitives::services::Asset; #[test] diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 7f161aef..a35511cc 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -37,6 +37,8 @@ use sp_runtime::{ traits::{ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; +use tangle_primitives::services::Asset; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping}; use core::ops::Mul; use std::{collections::BTreeMap, sync::Arc}; @@ -290,14 +292,14 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn get_total_delegation_by_asset_id( _operator: &AccountId, - _asset_id: &Self::AssetId, + _asset_id: &Asset, ) -> Balance { Default::default() } fn get_delegators_for_operator( _operator: &AccountId, - ) -> Vec<(AccountId, Balance, Self::AssetId)> { + ) -> Vec<(AccountId, Balance, Asset)> { Default::default() } diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index 02bc329c..cfc4aef4 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -299,7 +299,7 @@ impl pallet_services::EvmRunner for MockedEvmRunner { gas_limit: u64, is_transactional: bool, validate: bool, - ) -> Result> { + ) -> Result> { let max_fee_per_gas = FixedGasPrice::min_gas_price().0; let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); let nonce = None; @@ -322,7 +322,7 @@ impl pallet_services::EvmRunner for MockedEvmRunner { proof_size_base_cost, ::config(), ) - .map_err(|o| pallet_services::traits::RunnerError { error: o.error, weight: o.weight }) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) } } diff --git a/precompiles/multi-asset-delegation/Cargo.toml b/precompiles/multi-asset-delegation/Cargo.toml index b412cf18..b6b38178 100644 --- a/precompiles/multi-asset-delegation/Cargo.toml +++ b/precompiles/multi-asset-delegation/Cargo.toml @@ -31,6 +31,14 @@ derive_more = { workspace = true, features = ["full"] } hex-literal = { workspace = true } serde = { workspace = true } sha3 = { workspace = true } +ethereum = { workspace = true, features = ["with-codec"] } +ethers = "2.0" +hex = { workspace = true } +num_enum = { workspace = true } +libsecp256k1 = { workspace = true } +serde_json = { workspace = true } +smallvec = { workspace = true } +sp-keystore = { workspace = true } # Moonbeam precompile-utils = { workspace = true, features = ["std", "testing"] } @@ -42,6 +50,37 @@ pallet-timestamp = { workspace = true, features = ["std"] } scale-info = { workspace = true, features = ["derive", "std"] } sp-io = { workspace = true, features = ["std"] } +# Frontier Primitive +fp-account = { workspace = true } +fp-consensus = { workspace = true } +fp-dynamic-fee = { workspace = true } +fp-ethereum = { workspace = true } +fp-rpc = { workspace = true } +fp-self-contained = { workspace = true } +fp-storage = { workspace = true } + +# Frontier FRAME +pallet-base-fee = { workspace = true } +pallet-dynamic-fee = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } + +pallet-evm-precompile-blake2 = { workspace = true } +pallet-evm-precompile-bn128 = { workspace = true } +pallet-evm-precompile-curve25519 = { workspace = true } +pallet-evm-precompile-ed25519 = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-sha3fips = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } + +pallet-session = { workspace = true } +pallet-staking = { workspace = true } +sp-staking = { workspace = true } +frame-election-provider-support = { workspace = true } + +ethabi = { workspace = true } + [features] default = ["std"] std = [ @@ -57,5 +96,43 @@ std = [ "sp-runtime/std", "sp-std/std", "tangle-primitives/std", - "pallet-assets/std" -] + "pallet-assets/std", + "hex/std", + "scale-info/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-core/std", + "sp-std/std", + "sp-io/std", + "tangle-primitives/std", + "pallet-balances/std", + "pallet-timestamp/std", + "fp-account/std", + "fp-consensus/std", + "fp-dynamic-fee/std", + "fp-ethereum/std", + "fp-evm/std", + "fp-rpc/std", + "fp-self-contained/std", + "fp-storage/std", + "pallet-base-fee/std", + "pallet-dynamic-fee/std", + "pallet-ethereum/std", + "pallet-evm/std", + "pallet-evm-chain-id/std", + + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-precompile-blake2/std", + "pallet-evm-precompile-bn128/std", + "pallet-evm-precompile-curve25519/std", + "pallet-evm-precompile-ed25519/std", + "precompile-utils/std", + "serde/std", + "pallet-session/std", + "pallet-staking/std", + "sp-staking/std", + "frame-election-provider-support/std", +] \ No newline at end of file diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index b8d54921..55b61738 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -36,6 +36,8 @@ #[cfg(test)] mod mock; #[cfg(test)] +mod mock_evm; +#[cfg(test)] mod tests; use fp_evm::{PrecompileFailure, PrecompileHandle}; @@ -122,12 +124,6 @@ where { // Errors for the `MultiAssetDelegation` precompile. - /// Found an invalid amount / value. - const INVALID_AMOUNT: [u8; 32] = keccak256!("InvalidAmount()"); - /// Value must be zero for ERC20 payment asset. - const VALUE_NOT_ZERO_FOR_ERC20: [u8; 32] = keccak256!("ValueMustBeZeroForERC20()"); - /// Value must be zero for custom payment asset. - const VALUE_NOT_ZERO_FOR_CUSTOM_ASSET: [u8; 32] = keccak256!("ValueMustBeZeroForCustomAsset()"); /// Payment asset should be either custom or ERC20. const PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20: [u8; 32] = keccak256!("PaymentAssetShouldBeCustomOrERC20()"); diff --git a/precompiles/multi-asset-delegation/src/mock_evm.rs b/precompiles/multi-asset-delegation/src/mock_evm.rs new file mode 100644 index 00000000..9d087828 --- /dev/null +++ b/precompiles/multi-asset-delegation/src/mock_evm.rs @@ -0,0 +1,329 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use crate::{ + mock::{AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp}, + ServicesPrecompile, ServicesPrecompileCall, +}; +use fp_evm::FeeCalculator; +use frame_support::{ + parameter_types, + traits::{Currency, FindAuthor, OnUnbalanced}, + weights::Weight, + PalletId, +}; +use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; +use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, OnChargeEVMTransaction}; +use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; +use sp_core::{keccak_256, ConstU32, H160, H256, U256}; +use sp_runtime::{ + traits::{DispatchInfoOf, Dispatchable}, + transaction_validity::{TransactionValidity, TransactionValidityError}, + ConsensusEngineId, +}; +use tangle_primitives::services::EvmRunner; + +pub type Precompiles = + PrecompileSetBuilder, ServicesPrecompile>,)>; + +pub type PCall = ServicesPrecompileCall; + +parameter_types! { + pub const MinimumPeriod: u64 = 6000 / 2; +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + (1.into(), Weight::zero()) + } +} + +pub struct EnsureAddressAlways; +impl EnsureAddressOrigin for EnsureAddressAlways { + type Success = (); + + fn try_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } + + fn ensure_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } +} + +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(address_build(0).address) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub const TransactionByteFee: u64 = 1; + pub const ChainId: u64 = 42; + pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); + pub PrecompilesValue: Precompiles = Precompiles::new(); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); +} + +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(_fees_then_tips: impl Iterator) { + // whatever + } +} +pub struct FreeEVMExecution; + +impl OnChargeEVMTransaction for FreeEVMExecution { + type LiquidityInfo = (); + + fn withdraw_fee( + _who: &H160, + _fee: U256, + ) -> Result> { + Ok(()) + } + + fn correct_and_deposit_fee( + _who: &H160, + _corrected_fee: U256, + _base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + already_withdrawn + } + + fn pay_priority_fee(_tip: Self::LiquidityInfo) {} +} + +/// Type alias for negative imbalance during fees +type RuntimeNegativeImbalance = + ::AccountId>>::NegativeImbalance; + +/// See: [`pallet_evm::EVMCurrencyAdapter`] +pub struct CustomEVMCurrencyAdapter; + +impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { + type LiquidityInfo = Option; + + fn withdraw_fee( + who: &H160, + fee: U256, + ) -> Result> { + let pallet_services_address = pallet_services::Pallet::::address(); + // Make pallet services account free to use + if who == &pallet_services_address { + return Ok(None); + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::withdraw_fee(who, fee) + } + + fn correct_and_deposit_fee( + who: &H160, + corrected_fee: U256, + base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + let pallet_services_address = pallet_services::Pallet::::address(); + // Make pallet services account free to use + if who == &pallet_services_address { + return already_withdrawn; + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) + } + + fn pay_priority_fee(tip: Self::LiquidityInfo) { + as OnChargeEVMTransaction< + Runtime, + >>::pay_priority_fee(tip) + } +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = EthereumBlockHashMapping; + type CallOrigin = EnsureAddressAlways; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = crate::mock::TestAccount; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = ChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = CustomEVMCurrencyAdapter; + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, + _ => None, + } + } +} + +pub struct MockedEvmRunner; + +impl EvmRunner for MockedEvmRunner { + type Error = pallet_evm::Error; + + fn call( + source: sp_core::H160, + target: sp_core::H160, + input: Vec, + value: sp_core::U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result> { + let max_fee_per_gas = FixedGasPrice::min_gas_price().0; + let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); + let nonce = None; + let access_list = Default::default(); + let weight_limit = None; + let proof_size_base_cost = None; + <::Runner as pallet_evm::Runner>::call( + source, + target, + input, + value, + gas_limit, + Some(max_fee_per_gas), + Some(max_priority_fee_per_gas), + nonce, + access_list, + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + ::config(), + ) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) + } +} + +pub struct AccountInfo { + pub address: H160, +} + +pub fn address_build(seed: u8) -> AccountInfo { + let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); + let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); + let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; + let address = H160::from(H256::from(keccak_256(public_key))); + + AccountInfo { address } +} diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 7739a240..91d2bc2d 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -199,18 +199,18 @@ where .map_err(|_| revert_custom_error(Self::INVALID_AMOUNT))? }; - const zero_address: [u8; 20] = [0; 20]; + const ZERO_ADDRESS: [u8; 20] = [0; 20]; let (payment_asset, amount) = match (payment_asset_id.as_u32(), payment_token_address.0 .0) { - (0, zero_address) => (Asset::Custom(0u32.into()), value), + (0, ZERO_ADDRESS) => (Asset::Custom(0u32.into()), value), (0, erc20_token) => { if value != Default::default() { return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_ERC20)); } (Asset::Erc20(erc20_token.into()), amount) }, - (other_asset_id, zero_address) => { + (other_asset_id, ZERO_ADDRESS) => { if value != Default::default() { return Err(revert_custom_error(Self::VALUE_NOT_ZERO_FOR_CUSTOM_ASSET)); } diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 7ab17b0b..7ba2ddc8 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -30,7 +30,6 @@ use frame_support::{ use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; -use pallet_services::{traits::EvmRunner, EvmAddressMapping, EvmGasWeightMapping}; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; @@ -42,6 +41,7 @@ use sp_runtime::{ testing::UintAuthorityId, traits::ConvertInto, AccountId32, BuildStorage, Perbill, }; use std::{collections::BTreeMap, sync::Arc}; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; pub type AccountId = AccountId32; pub type Balance = u128; @@ -418,14 +418,14 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo fn get_total_delegation_by_asset_id( _operator: &AccountId, - _asset_id: &Self::AssetId, + _asset_id: &Asset, ) -> Balance { Default::default() } fn get_delegators_for_operator( _operator: &AccountId, - ) -> Vec<(AccountId, Balance, Self::AssetId)> { + ) -> Vec<(AccountId, Balance, Asset)> { Default::default() } diff --git a/precompiles/services/src/mock_evm.rs b/precompiles/services/src/mock_evm.rs index cd0ccbcf..9d087828 100644 --- a/precompiles/services/src/mock_evm.rs +++ b/precompiles/services/src/mock_evm.rs @@ -34,6 +34,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionValidityError}, ConsensusEngineId, }; +use tangle_primitives::services::EvmRunner; pub type Precompiles = PrecompileSetBuilder, ServicesPrecompile>,)>; @@ -276,7 +277,7 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { pub struct MockedEvmRunner; -impl pallet_services::EvmRunner for MockedEvmRunner { +impl EvmRunner for MockedEvmRunner { type Error = pallet_evm::Error; fn call( @@ -287,7 +288,7 @@ impl pallet_services::EvmRunner for MockedEvmRunner { gas_limit: u64, is_transactional: bool, validate: bool, - ) -> Result> { + ) -> Result> { let max_fee_per_gas = FixedGasPrice::min_gas_price().0; let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); let nonce = None; @@ -310,7 +311,7 @@ impl pallet_services::EvmRunner for MockedEvmRunner { proof_size_base_cost, ::config(), ) - .map_err(|o| pallet_services::traits::RunnerError { error: o.error, weight: o.weight }) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) } } From 44500a536565854a675df7a9aac1b0eed847c926 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:57:26 +0530 Subject: [PATCH 28/63] clipyy fixes --- Cargo.lock | 31 +++++ .../src/functions/delegate.rs | 2 +- .../src/functions/deposit.rs | 2 +- .../src/functions/evm.rs | 16 --- .../src/functions/rewards.rs | 6 +- pallets/services/src/mock.rs | 1 + pallets/services/src/mock_evm.rs | 2 +- precompiles/multi-asset-delegation/src/lib.rs | 16 +-- .../multi-asset-delegation/src/mock.rs | 113 ++++++------------ .../multi-asset-delegation/src/mock_evm.rs | 16 +-- .../multi-asset-delegation/src/tests.rs | 91 ++++++++++---- 11 files changed, 163 insertions(+), 133 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e4a2151..cee5c7a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7740,23 +7740,54 @@ name = "pallet-evm-precompile-multi-asset-delegation" version = "0.1.0" dependencies = [ "derive_more 1.0.0", + "ethabi", + "ethereum", + "ethers", + "fp-account", + "fp-consensus", + "fp-dynamic-fee", + "fp-ethereum", "fp-evm", + "fp-rpc", + "fp-self-contained", + "fp-storage", + "frame-election-provider-support", "frame-support", "frame-system", + "hex", "hex-literal 0.4.1", + "libsecp256k1", + "num_enum", "pallet-assets", "pallet-balances", + "pallet-base-fee", + "pallet-dynamic-fee", + "pallet-ethereum", "pallet-evm", + "pallet-evm-chain-id", + "pallet-evm-precompile-blake2", + "pallet-evm-precompile-bn128", + "pallet-evm-precompile-curve25519", + "pallet-evm-precompile-ed25519", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", "pallet-multi-asset-delegation", + "pallet-session", + "pallet-staking", "pallet-timestamp", "parity-scale-codec", "precompile-utils", "scale-info", "serde", + "serde_json", "sha3", + "smallvec", "sp-core", "sp-io", + "sp-keystore", "sp-runtime", + "sp-staking", "sp-std", "tangle-primitives", ] diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 43342f6b..eac6ad6d 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -412,7 +412,7 @@ impl Pallet { slashed_amount_recipient_evm, slash_amount, ) - .map_err(|e| Error::::ERC20TransferFailed)?; + .map_err(|_| Error::::ERC20TransferFailed)?; ensure!(success, Error::::ERC20TransferFailed); }, } diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index b2f36302..5f7a17fa 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -65,7 +65,7 @@ impl Pallet { Self::pallet_evm_account(), amount, ) - .map_err(|e| Error::::ERC20TransferFailed)?; + .map_err(|_| Error::::ERC20TransferFailed)?; ensure!(success, Error::::ERC20TransferFailed); }, } diff --git a/pallets/multi-asset-delegation/src/functions/evm.rs b/pallets/multi-asset-delegation/src/functions/evm.rs index 7c307c82..e2cb6140 100644 --- a/pallets/multi-asset-delegation/src/functions/evm.rs +++ b/pallets/multi-asset-delegation/src/functions/evm.rs @@ -72,22 +72,6 @@ impl Pallet { Ok((success, weight)) } - /// Dispatches a hook to the EVM and returns if the result with the used weight. - fn dispatch_evm_call( - contract: H160, - f: Function, - args: &[ethabi::Token], - value: BalanceOf, - ) -> Result<(fp_evm::CallInfo, Weight), DispatchErrorWithPostInfo> { - log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(f.short_signature()), f.signature()); - let data = f.encode_input(args).map_err(|_| Error::::EVMAbiEncode)?; - let gas_limit = 300_000; - let value = value.using_encoded(U256::from_little_endian); - let info = Self::evm_call(Self::pallet_evm_account(), contract, value, data, gas_limit)?; - let weight = Self::weight_from_call_info(&info); - Ok((info, weight)) - } - /// Dispatches a call to the EVM and returns the result. fn evm_call( from: H160, diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs index 6341fa7e..23288fce 100644 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ b/pallets/multi-asset-delegation/src/functions/rewards.rs @@ -22,7 +22,7 @@ use tangle_primitives::{services::Asset, RoundIndex}; impl Pallet { #[allow(clippy::type_complexity)] - pub fn distribute_rewards(round: RoundIndex) -> DispatchResult { + pub fn distribute_rewards(_round: RoundIndex) -> DispatchResult { // let mut delegation_info: BTreeMap< // T::AssetId, // Vec, T::AssetId>>, @@ -75,7 +75,7 @@ impl Pallet { Ok(()) } - fn calculate_total_reward( + fn _calculate_total_reward( apy: sp_runtime::Percent, total_amount: BalanceOf, ) -> Result, DispatchError> { @@ -83,7 +83,7 @@ impl Pallet { Ok(total_reward) } - fn distribute_reward_to_delegator( + fn _distribute_reward_to_delegator( delegator: &T::AccountId, reward: BalanceOf, ) -> DispatchResult { diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index a35511cc..41744031 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -25,6 +25,7 @@ use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, }; +use tangle_primitives::services::EvmRunner; use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; diff --git a/pallets/services/src/mock_evm.rs b/pallets/services/src/mock_evm.rs index cfc4aef4..c4600040 100644 --- a/pallets/services/src/mock_evm.rs +++ b/pallets/services/src/mock_evm.rs @@ -288,7 +288,7 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { pub struct MockedEvmRunner; -impl pallet_services::EvmRunner for MockedEvmRunner { +impl tangle_primitives::services::EvmRunner for MockedEvmRunner { type Error = pallet_evm::Error; fn call( diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index 55b61738..eecbe642 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -250,7 +250,7 @@ where Ok(()) } - #[precompile::public("deposit(uint256,uint256)")] + #[precompile::public("deposit(uint256,address,uint256)")] fn deposit( handle: &mut impl PrecompileHandle, asset_id: U256, @@ -262,7 +262,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { + _ => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, }; @@ -284,7 +284,7 @@ where Ok(()) } - #[precompile::public("schedule_withdraw(uint256,uint256)")] + #[precompile::public("schedule_withdraw(uint256,address,uint256)")] fn schedule_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, @@ -302,7 +302,7 @@ where let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), + (other_asset_id, _zero_address) => (Asset::Custom(other_asset_id.into()), amount), (_other_asset_id, _erc20_token) => { return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) }, @@ -331,7 +331,7 @@ where Ok(()) } - #[precompile::public("cancel_withdraw(uint256,uint256)")] + #[precompile::public("cancel_withdraw(uint256,address,uint256)")] fn cancel_withdraw( handle: &mut impl PrecompileHandle, asset_id: U256, @@ -364,7 +364,7 @@ where Ok(()) } - #[precompile::public("delegate(bytes32,uint256,uint256,uint64[])")] + #[precompile::public("delegate(bytes32,uint256,address,uint256,uint64[])")] fn delegate( handle: &mut impl PrecompileHandle, operator: H256, @@ -411,7 +411,7 @@ where Ok(()) } - #[precompile::public("schedule_delegator_unstake(bytes32,uint256,uint256)")] + #[precompile::public("schedule_delegator_unstake(bytes32,uint256,address,uint256)")] fn schedule_delegator_unstake( handle: &mut impl PrecompileHandle, operator: H256, @@ -460,7 +460,7 @@ where Ok(()) } - #[precompile::public("cancelDelegatorUnstake(bytes32,uint256,uint256)")] + #[precompile::public("cancelDelegatorUnstake(bytes32,uint256,address,uint256)")] fn cancel_delegator_unstake( handle: &mut impl PrecompileHandle, operator: H256, diff --git a/precompiles/multi-asset-delegation/src/mock.rs b/precompiles/multi-asset-delegation/src/mock.rs index 2f65902d..1363148b 100644 --- a/precompiles/multi-asset-delegation/src/mock.rs +++ b/precompiles/multi-asset-delegation/src/mock.rs @@ -16,27 +16,28 @@ //! Test utilities use super::*; -use crate::{MultiAssetDelegationPrecompile, MultiAssetDelegationPrecompileCall}; +use crate::mock_evm::*; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU64}, weights::Weight, PalletId, }; -use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, SubstrateBlockHashMapping}; +use pallet_evm::GasWeightMapping; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_core::{ self, sr25519::{Public as sr25519Public, Signature}, - ConstU32, H160, U256, + ConstU32, H160, }; use sp_runtime::{ traits::{IdentifyAccount, Verify}, AccountId32, BuildStorage, }; +use tangle_primitives::services::EvmAddressMapping; +use tangle_primitives::services::EvmGasWeightMapping; use tangle_primitives::ServiceManager; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; @@ -157,6 +158,7 @@ construct_runtime!( System: frame_system, Balances: pallet_balances, Evm: pallet_evm, + Ethereum: pallet_ethereum, Timestamp: pallet_timestamp, Assets: pallet_assets, MultiAssetDelegation: pallet_multi_asset_delegation, @@ -211,77 +213,6 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = (); } -pub type Precompiles = - PrecompileSetBuilder, MultiAssetDelegationPrecompile>,)>; - -pub type PCall = MultiAssetDelegationPrecompileCall; - -pub struct EnsureAddressAlways; -impl EnsureAddressOrigin for EnsureAddressAlways { - type Success = (); - - fn try_address_origin( - _address: &H160, - _origin: OuterOrigin, - ) -> Result { - Ok(()) - } - - fn ensure_address_origin( - _address: &H160, - _origin: OuterOrigin, - ) -> Result { - Ok(()) - } -} - -const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; - -parameter_types! { - pub BlockGasLimit: U256 = U256::from(u64::MAX); - pub PrecompilesValue: Precompiles = Precompiles::new(); - pub const WeightPerGas: Weight = Weight::from_parts(1, 0); - pub GasLimitPovSizeRatio: u64 = { - let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); - block_gas_limit.saturating_div(MAX_POV_SIZE) - }; - pub SuicideQuickClearLimit: u32 = 0; - -} -impl pallet_evm::Config for Runtime { - type FeeCalculator = (); - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type CallOrigin = EnsureAddressAlways; - type WithdrawOrigin = EnsureAddressNever; - type AddressMapping = TestAccount; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = Precompiles; - type PrecompilesValue = PrecompilesValue; - type ChainId = (); - type OnChargeTransaction = (); - type BlockGasLimit = BlockGasLimit; - type BlockHashMapping = SubstrateBlockHashMapping; - type FindAuthor = (); - type OnCreate = (); - type SuicideQuickClearLimit = SuicideQuickClearLimit; - type GasLimitPovSizeRatio = GasLimitPovSizeRatio; - type Timestamp = Timestamp; - type WeightInfo = pallet_evm::weights::SubstrateWeight; -} - -parameter_types! { - pub const MinimumPeriod: u64 = 5; -} -impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = u64; @@ -327,6 +258,35 @@ impl ServiceManager for MockServiceManager { } } +pub struct PalletEVMGasWeightMapping; + +impl EvmGasWeightMapping for PalletEVMGasWeightMapping { + fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { + pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) + } + + fn weight_to_gas(weight: Weight) -> u64 { + pallet_evm::FixedGasWeightMapping::::weight_to_gas(weight) + } +} + +pub struct PalletEVMAddressMapping; + +impl EvmAddressMapping for PalletEVMAddressMapping { + fn into_account_id(address: H160) -> AccountId { + use pallet_evm::AddressMapping; + ::AddressMapping::into_account_id(address) + } + + fn into_address(account_id: AccountId) -> H160 { + account_id.using_encoded(|b| { + let mut addr = [0u8; 20]; + addr.copy_from_slice(&b[0..20]); + H160(addr) + }) + } +} + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaxLocks: u32 = 50; @@ -353,6 +313,9 @@ impl pallet_multi_asset_delegation::Config for Runtime { type BondDuration = BondDuration; type ServiceManager = MockServiceManager; type LeaveOperatorsDelay = ConstU32<10>; + type EvmRunner = MockedEvmRunner; + type EvmAddressMapping = PalletEVMAddressMapping; + type EvmGasWeightMapping = PalletEVMGasWeightMapping; type OperatorBondLessDelay = ConstU32<1>; type LeaveDelegatorsDelay = ConstU32<1>; type DelegationBondLessDelay = ConstU32<5>; diff --git a/precompiles/multi-asset-delegation/src/mock_evm.rs b/precompiles/multi-asset-delegation/src/mock_evm.rs index 9d087828..958342ea 100644 --- a/precompiles/multi-asset-delegation/src/mock_evm.rs +++ b/precompiles/multi-asset-delegation/src/mock_evm.rs @@ -16,7 +16,7 @@ #![allow(clippy::all)] use crate::{ mock::{AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp}, - ServicesPrecompile, ServicesPrecompileCall, + MultiAssetDelegationPrecompile, MultiAssetDelegationPrecompileCall, }; use fp_evm::FeeCalculator; use frame_support::{ @@ -37,9 +37,9 @@ use sp_runtime::{ use tangle_primitives::services::EvmRunner; pub type Precompiles = - PrecompileSetBuilder, ServicesPrecompile>,)>; + PrecompileSetBuilder, MultiAssetDelegationPrecompile>,)>; -pub type PCall = ServicesPrecompileCall; +pub type PCall = MultiAssetDelegationPrecompileCall; parameter_types! { pub const MinimumPeriod: u64 = 6000 / 2; @@ -149,9 +149,10 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { who: &H160, fee: U256, ) -> Result> { - let pallet_services_address = pallet_services::Pallet::::address(); + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet services account free to use - if who == &pallet_services_address { + if who == &pallet_multi_asset_delegation_address { return Ok(None); } // fallback to the default implementation @@ -166,9 +167,10 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { base_fee: U256, already_withdrawn: Self::LiquidityInfo, ) -> Self::LiquidityInfo { - let pallet_services_address = pallet_services::Pallet::::address(); + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); // Make pallet services account free to use - if who == &pallet_services_address { + if who == &pallet_multi_asset_delegation_address { return already_withdrawn; } // fallback to the default implementation diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index c6ed8d64..b7dfdfbd 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -1,8 +1,9 @@ -use crate::{mock::*, U256}; +use crate::{mock::*, mock_evm::*, U256}; use frame_support::{assert_ok, traits::Currency}; use pallet_multi_asset_delegation::{types::OperatorStatus, CurrentRound, Delegators, Operators}; use precompile_utils::testing::*; use sp_core::H160; +use tangle_primitives::services::Asset; // Helper function for creating and minting tokens pub fn create_and_mint_tokens( @@ -79,7 +80,7 @@ fn test_delegate_assets_invalid_operator() { Balances::make_free_balance_be(&delegator_account, 500); create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), 1, 200)); + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); PrecompilesValue::get() .prepare_test( @@ -90,9 +91,10 @@ fn test_delegate_assets_invalid_operator() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 5, error: [2, 0, 0, 0], message: Some(\"NotAnOperator\") })"); + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [2, 0, 0, 0], message: Some(\"NotAnOperator\") })"); assert_eq!(Balances::free_balance(delegator_account), 500); }); @@ -113,7 +115,12 @@ fn test_delegate_assets() { )); create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), 1, 200)); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator_account), + Asset::Custom(1), + 200, + Some(TestAccount::Alex.into()) + )); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit PrecompilesValue::get() @@ -125,6 +132,7 @@ fn test_delegate_assets() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) .execute_returns(()); @@ -149,7 +157,7 @@ fn test_delegate_assets_insufficient_balance() { create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), 1, 200)); + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); PrecompilesValue::get() .prepare_test( @@ -160,9 +168,10 @@ fn test_delegate_assets_insufficient_balance() { asset_id: U256::from(1), amount: U256::from(300), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 5, error: [15, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [15, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); assert_eq!(Balances::free_balance(delegator_account), 500); }); @@ -188,7 +197,11 @@ fn test_schedule_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::deposit { asset_id: U256::from(1), amount: U256::from(200) }, + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, ) .execute_returns(()); @@ -203,6 +216,7 @@ fn test_schedule_withdraw() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) .execute_returns(()); @@ -213,12 +227,16 @@ fn test_schedule_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::schedule_withdraw { asset_id: U256::from(1), amount: U256::from(100) }, + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, ) .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&1), None); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); assert!(!metadata.withdraw_requests.is_empty()); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change @@ -243,7 +261,11 @@ fn test_execute_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::deposit { asset_id: U256::from(1), amount: U256::from(200) }, + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, ) .execute_returns(()); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit @@ -257,6 +279,7 @@ fn test_execute_withdraw() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) .execute_returns(()); @@ -267,12 +290,16 @@ fn test_execute_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::schedule_withdraw { asset_id: U256::from(1), amount: U256::from(100) }, + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, ) .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&1), None); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); assert!(!metadata.withdraw_requests.is_empty()); >::put(3); @@ -282,7 +309,7 @@ fn test_execute_withdraw() { .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&1), None); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); assert!(metadata.withdraw_requests.is_empty()); assert_eq!(Assets::balance(1, delegator_account), 500 - 100); // deposited 200, withdrew 100 @@ -308,7 +335,11 @@ fn test_execute_withdraw_before_due() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::deposit { asset_id: U256::from(1), amount: U256::from(200) }, + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, ) .execute_returns(()); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit @@ -322,6 +353,7 @@ fn test_execute_withdraw_before_due() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) .execute_returns(()); @@ -333,12 +365,16 @@ fn test_execute_withdraw_before_due() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::schedule_withdraw { asset_id: U256::from(1), amount: U256::from(100) }, + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, ) .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&1), None); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); assert!(!metadata.withdraw_requests.is_empty()); PrecompilesValue::get() @@ -368,7 +404,11 @@ fn test_cancel_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::deposit { asset_id: U256::from(1), amount: U256::from(200) }, + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, ) .execute_returns(()); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit @@ -382,6 +422,7 @@ fn test_cancel_withdraw() { asset_id: U256::from(1), amount: U256::from(100), blueprint_selection: Default::default(), + token_address: Default::default(), }, ) .execute_returns(()); @@ -392,24 +433,32 @@ fn test_cancel_withdraw() { .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::schedule_withdraw { asset_id: U256::from(1), amount: U256::from(100) }, + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, ) .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&1), None); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); assert!(!metadata.withdraw_requests.is_empty()); PrecompilesValue::get() .prepare_test( TestAccount::Alex, H160::from_low_u64_be(1), - PCall::cancel_withdraw { asset_id: U256::from(1), amount: U256::from(100) }, + PCall::cancel_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, ) .execute_returns(()); let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert!(metadata.deposits.contains_key(&1)); + assert!(metadata.deposits.contains_key(&Asset::Custom(1))); assert!(metadata.withdraw_requests.is_empty()); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change From b2815d3caa70ce413bf7f74e0cde9e732ad9c177 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:11:54 +0530 Subject: [PATCH 29/63] cleanup clippy --- pallets/multi-asset-delegation/src/mock.rs | 137 +++----- .../src/tests/deposit.rs | 30 ++ pallets/services/src/mock.rs | 2 +- precompiles/multi-asset-delegation/src/lib.rs | 322 +++++++----------- 4 files changed, 196 insertions(+), 295 deletions(-) diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index a633decd..1314749b 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -52,13 +52,6 @@ pub type Balance = u128; type Nonce = u32; pub type AssetId = u128; -// AccountIds for tests -pub const ALICE: u8 = 1; -pub const BOB: u8 = 2; -pub const CHARLIE: u8 = 3; -pub const DAVE: u8 = 4; -pub const EVE: u8 = 5; - #[frame_support::derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { type BaseCallFilter = frame_support::traits::Everything; @@ -378,27 +371,19 @@ pub fn account_id_to_address(account_id: AccountId) -> H160 { H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) } -pub fn address_to_account_id(address: H160) -> AccountId { - use pallet_evm::AddressMapping; - ::AddressMapping::into_account_id(address) -} - -pub fn mock_authorities(vec: Vec) -> Vec { - vec.into_iter().map(|id| mock_pub_key(id)).collect() -} +// pub fn address_to_account_id(address: H160) -> AccountId { +// use pallet_evm::AddressMapping; +// ::AddressMapping::into_account_id(address) +// } pub fn new_test_ext() -> sp_io::TestExternalities { new_test_ext_raw_authorities() } -pub const MBSM: H160 = H160([0x12; 20]); -pub const CGGMP21_BLUEPRINT: H160 = H160([0x21; 20]); -pub const HOOKS_TEST: H160 = H160([0x22; 20]); pub const USDC_ERC20: H160 = H160([0x23; 20]); - -pub const USDC: AssetId = 1; -pub const WETH: AssetId = 2; -pub const WBTC: AssetId = 3; +// pub const USDC: AssetId = 1; +// pub const WETH: AssetId = 2; +// pub const WBTC: AssetId = 3; pub const VDOT: AssetId = 4; // This function basically just builds a genesis storage key/value store according to @@ -427,24 +412,6 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { let mut evm_accounts = BTreeMap::new(); - let create_contract = |bytecode: &str, address: H160| { - let mut raw_hex = bytecode.replace("0x", "").replace("\n", ""); - // fix odd length - if raw_hex.len() % 2 != 0 { - raw_hex = format!("0{}", raw_hex); - } - let code = hex::decode(raw_hex).unwrap(); - evm_accounts.insert( - address, - fp_evm::GenesisAccount { - code, - storage: Default::default(), - nonce: Default::default(), - balance: Default::default(), - }, - ); - }; - for i in 1..=authorities.len() { evm_accounts.insert( mock_address(i as u8), @@ -616,61 +583,35 @@ macro_rules! evm_log { }; } -/// Asserts that the EVM logs are as expected. -#[track_caller] -pub fn assert_evm_logs(expected: &[fp_evm::Log]) { - assert_evm_events_contains(expected.iter().cloned().collect()) -} - -/// Asserts that the EVM events are as expected. -#[track_caller] -fn assert_evm_events_contains(expected: Vec) { - let actual: Vec = System::events() - .iter() - .filter_map(|e| match e.event { - RuntimeEvent::EVM(pallet_evm::Event::Log { ref log }) => Some(log.clone()), - _ => None, - }) - .collect(); - - // Check if `expected` is a subset of `actual` - let mut any_matcher = false; - for evt in expected { - if !actual.contains(&evt) { - panic!("Events don't match\nactual: {actual:?}\nexpected: {evt:?}"); - } else { - any_matcher = true; - } - } - - // At least one event should be present - if !any_matcher { - panic!("No events found"); - } -} - -// Checks events against the latest. A contiguous set of events must be -// provided. They must include the most recent RuntimeEvent, but do not have to include -// every past RuntimeEvent. -#[track_caller] -pub fn assert_events(mut expected: Vec) { - let mut actual: Vec = System::events() - .iter() - .filter_map(|e| match e.event { - RuntimeEvent::MultiAssetDelegation(_) => Some(e.event.clone()), - _ => None, - }) - .collect(); - - expected.reverse(); - for evt in expected { - let next = actual.pop().expect("RuntimeEvent expected"); - match (&next, &evt) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - panic!("Events don't match\nactual: {actual:#?}\nexpected: {evt:#?}"); - } - }, - }; - } -} +// /// Asserts that the EVM logs are as expected. +// #[track_caller] +// pub fn assert_evm_logs(expected: &[fp_evm::Log]) { +// assert_evm_events_contains(expected.iter().cloned().collect()) +// } + +// /// Asserts that the EVM events are as expected. +// #[track_caller] +// fn assert_evm_events_contains(expected: Vec) { +// let actual: Vec = System::events() +// .iter() +// .filter_map(|e| match e.event { +// RuntimeEvent::EVM(pallet_evm::Event::Log { ref log }) => Some(log.clone()), +// _ => None, +// }) +// .collect(); + +// // Check if `expected` is a subset of `actual` +// let mut any_matcher = false; +// for evt in expected { +// if !actual.contains(&evt) { +// panic!("Events don't match\nactual: {actual:?}\nexpected: {evt:?}"); +// } else { +// any_matcher = true; +// } +// } + +// // At least one event should be present +// if !any_matcher { +// panic!("No events found"); +// } +// } diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 88105005..d72c669e 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -69,6 +69,36 @@ fn deposit_should_work_for_fungible_asset() { }); } +#[test] +fn deposit_should_work_for_evm_asset() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 200; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + assert_eq!( + System::events().last().unwrap().event, + RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { + who: who.clone(), + amount, + asset_id: Asset::Custom(VDOT), + }) + ); + }); +} + #[test] fn multiple_deposit_should_work() { new_test_ext().execute_with(|| { diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 41744031..a8066592 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -25,7 +25,6 @@ use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, }; -use tangle_primitives::services::EvmRunner; use frame_system::EnsureRoot; use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; @@ -39,6 +38,7 @@ use sp_runtime::{ AccountId32, BuildStorage, Perbill, }; use tangle_primitives::services::Asset; +use tangle_primitives::services::EvmRunner; use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping}; use core::ops::Mul; diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index eecbe642..330b4247 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -40,7 +40,7 @@ mod mock_evm; #[cfg(test)] mod tests; -use fp_evm::{PrecompileFailure, PrecompileHandle}; +use fp_evm::PrecompileHandle; use frame_support::{ dispatch::{GetDispatchInfo, PostDispatchInfo}, traits::Currency, @@ -62,55 +62,6 @@ type AssetIdOf = ::As pub struct MultiAssetDelegationPrecompile(PhantomData); -impl MultiAssetDelegationPrecompile -where - Runtime: pallet_multi_asset_delegation::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, - BalanceOf: TryFrom + Into + solidity::Codec, - AssetIdOf: TryFrom + Into, - Runtime::AccountId: From, -{ - /// Helper method to parse SS58 address - fn parse_32byte_address(addr: Vec) -> EvmResult { - let addr: Runtime::AccountId = match addr.len() { - // public address of the ss58 account has 32 bytes - 32 => { - let mut addr_bytes = [0_u8; 32]; - addr_bytes[..].clone_from_slice(&addr[0..32]); - - WrappedAccountId32(addr_bytes).into() - }, - _ => { - // Return err if account length is wrong - return Err(revert("Error while parsing staker's address")); - }, - }; - - Ok(addr) - } - - /// Helper for converting from u8 to RewardDestination - fn convert_to_account_id(payee: H256) -> EvmResult { - let payee = match payee { - H256( - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _], - ) => { - let ethereum_address = Address(H160::from_slice(&payee.0[12..])); - Runtime::AddressMapping::into_account_id(ethereum_address.0) - }, - H256(account) => Self::parse_32byte_address(account.to_vec())?, - }; - - Ok(payee) - } - - fn u256_to_amount(amount: U256) -> EvmResult> { - amount.try_into().map_err(|_| revert("Invalid amount")) - } -} - #[precompile_utils::precompile] impl MultiAssetDelegationPrecompile where @@ -122,12 +73,6 @@ where AssetIdOf: TryFrom + Into + From, Runtime::AccountId: From, { - // Errors for the `MultiAssetDelegation` precompile. - - /// Payment asset should be either custom or ERC20. - const PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20: [u8; 32] = - keccak256!("PaymentAssetShouldBeCustomOrERC20()"); - #[precompile::public("joinOperators(uint256)")] fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -188,6 +133,19 @@ where Ok(()) } + #[precompile::public("executeWithdraw()")] + fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::execute_withdraw { + evm_address: Some(handle.context().caller), + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + #[precompile::public("scheduleOperatorUnstake(uint256)")] fn schedule_operator_unstake( handle: &mut impl PrecompileHandle, @@ -257,29 +215,29 @@ where token_address: Address, amount: U256, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - _ => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); - - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::deposit { - asset_id: deposit_asset, - amount, - evm_address: Some(msg_sender), - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::deposit { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + evm_address: Some(caller), + }, + )?; Ok(()) } @@ -291,42 +249,28 @@ where token_address: Address, amount: U256, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; - - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, _zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - let call = pallet_multi_asset_delegation::Call::::schedule_withdraw { - asset_id: deposit_asset, - amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeWithdraw()")] - fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_withdraw { - evm_address: Some(handle.context().caller), - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::schedule_withdraw { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; Ok(()) } @@ -338,28 +282,28 @@ where token_address: Address, amount: U256, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::cancel_withdraw { - asset_id: deposit_asset, - amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::cancel_withdraw { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; Ok(()) } @@ -373,40 +317,36 @@ where amount: U256, blueprint_selection: Vec, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; - - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); - - // Parse operator address - let operator = Self::convert_to_account_id(operator)?; - - // Parse blueprint selection - let bounded_blueprint_selection: frame_support::BoundedVec<_, _> = - frame_support::BoundedVec::try_from(blueprint_selection) - .map_err(|_| revert("error converting blueprint selection"))?; + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let blueprint_selection = DelegatorBlueprintSelection::Fixed(bounded_blueprint_selection); + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::delegate { - operator, - asset_id: deposit_asset, - amount, - blueprint_selection, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::delegate { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + blueprint_selection: DelegatorBlueprintSelection::Fixed( + blueprint_selection.try_into().map_err(|_| { + RevertReason::custom("Too many blueprint ids for fixed selection") + })?, + ), + }, + )?; Ok(()) } @@ -419,32 +359,31 @@ where token_address: Address, amount: U256, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; - - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - // Parse operator address - let operator = Self::convert_to_account_id(operator)?; + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { - operator, - asset_id: deposit_asset, - amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; Ok(()) } @@ -468,41 +407,32 @@ where token_address: Address, amount: U256, ) -> EvmResult { - let amount = Self::u256_to_amount(amount)?; - - // Get origin account. - let msg_sender = handle.context().caller; - let origin = Runtime::AddressMapping::into_account_id(msg_sender); + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - // Parse operator address - let operator = Self::convert_to_account_id(operator)?; + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) => (Asset::Erc20(erc20_token.into()), amount), - (other_asset_id, zero_address) => (Asset::Custom(other_asset_id.into()), amount), - (_other_asset_id, _erc20_token) => { - return Err(revert_custom_error(Self::PAYMENT_ASSET_SHOULD_BE_CUSTOM_OR_ERC20)) + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - // Build call with origin. - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let call = pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { - operator, - asset_id: deposit_asset, - amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; Ok(()) } } - -/// Revert with Custom Error Selector -fn revert_custom_error(err: [u8; 32]) -> PrecompileFailure { - let selector = &err[0..4]; - let mut output = sp_std::vec![0u8; 32]; - output[0..4].copy_from_slice(selector); - PrecompileFailure::Revert { exit_status: fp_evm::ExitRevert::Reverted, output } -} From e7c6dbe375d7a7d77eb42785e5611b6c781bd9e0 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:17:08 +0530 Subject: [PATCH 30/63] import oracle pallet --- Cargo.lock | 18 ++ pallets/oracle/Cargo.toml | 52 +++ pallets/oracle/README.md | 8 + pallets/oracle/runtime-api/Cargo.toml | 17 + pallets/oracle/runtime-api/src/lib.rs | 21 ++ pallets/oracle/src/benchmarking.rs | 54 ++++ pallets/oracle/src/default_combine_data.rs | 40 +++ pallets/oracle/src/lib.rs | 297 +++++++++++++++++ pallets/oracle/src/mock.rs | 107 +++++++ pallets/oracle/src/tests.rs | 356 +++++++++++++++++++++ pallets/oracle/src/weights.rs | 51 +++ 11 files changed, 1021 insertions(+) create mode 100644 pallets/oracle/Cargo.toml create mode 100644 pallets/oracle/README.md create mode 100644 pallets/oracle/runtime-api/Cargo.toml create mode 100644 pallets/oracle/runtime-api/src/lib.rs create mode 100644 pallets/oracle/src/benchmarking.rs create mode 100644 pallets/oracle/src/default_combine_data.rs create mode 100644 pallets/oracle/src/lib.rs create mode 100644 pallets/oracle/src/mock.rs create mode 100644 pallets/oracle/src/tests.rs create mode 100644 pallets/oracle/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index cee5c7a3..993b3408 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7230,6 +7230,24 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "orml-oracle" +version = "1.1.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "tangle-primitives", +] + [[package]] name = "overload" version = "0.1.1" diff --git a/pallets/oracle/Cargo.toml b/pallets/oracle/Cargo.toml new file mode 100644 index 00000000..e0047b86 --- /dev/null +++ b/pallets/oracle/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "orml-oracle" +description = "Oracle module that makes off-chain data available on-chain." +repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/oracle" +license = "Apache-2.0" +version = "1.1.0" +authors = ["Laminar Developers "] +edition = "2021" + +[dependencies] +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +serde = { workspace = true, optional = true } + +frame-support = { workspace = true } +frame-system = { workspace = true } +sp-application-crypto = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } +tangle-primitives = { workspace = true } + +[dev-dependencies] +sp-core = { workspace = true } + +[features] +default = [ "std" ] +std = [ + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "tangle-primitives/std", + "parity-scale-codec/std", + "scale-info/std", + "serde", + "sp-application-crypto/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/pallets/oracle/README.md b/pallets/oracle/README.md new file mode 100644 index 00000000..4e05724d --- /dev/null +++ b/pallets/oracle/README.md @@ -0,0 +1,8 @@ +# Oracle module + +### Overview + +This module exposes capabilities for oracle operators to feed external offchain data. +The raw values can be combined to provide an aggregated value. + +The data is valid only if feeded by an authorized operator. This module implements `frame_support::traits::InitializeMembers` and `frame_support::traits::ChangeMembers`, to provide a way to manage operators membership. Typically it could be leveraged to `pallet_membership` in FRAME. diff --git a/pallets/oracle/runtime-api/Cargo.toml b/pallets/oracle/runtime-api/Cargo.toml new file mode 100644 index 00000000..db12b5d4 --- /dev/null +++ b/pallets/oracle/runtime-api/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "orml-oracle-runtime-api" +version = "1.1.0" +authors = ["Laminar Developers "] +edition = "2021" +license = "Apache-2.0" +description = "Runtime API module for orml-oracle." +repository = "https://github.com/open-web3-stack/open-runtime-module-library" + +[dependencies] +parity-scale-codec = { version = "3.0.0", default-features = false, features = ["derive"] } +sp-api = { workspace = true } +sp-std = { workspace = true } + +[features] +default = [ "std" ] +std = [ "parity-scale-codec/std", "sp-api/std", "sp-std/std" ] diff --git a/pallets/oracle/runtime-api/src/lib.rs b/pallets/oracle/runtime-api/src/lib.rs new file mode 100644 index 00000000..7a87dbe4 --- /dev/null +++ b/pallets/oracle/runtime-api/src/lib.rs @@ -0,0 +1,21 @@ +//! Runtime API definition for oracle module. + +#![cfg_attr(not(feature = "std"), no_std)] +// The `too_many_arguments` warning originates from `decl_runtime_apis` macro. +#![allow(clippy::too_many_arguments)] +// The `unnecessary_mut_passed` warning originates from `decl_runtime_apis` macro. +#![allow(clippy::unnecessary_mut_passed)] + +use parity_scale_codec::Codec; +use sp_std::prelude::Vec; + +sp_api::decl_runtime_apis! { + pub trait OracleApi where + ProviderId: Codec, + Key: Codec, + Value: Codec, + { + fn get_value(provider_id: ProviderId, key: Key) -> Option; + fn get_all_values(provider_id: ProviderId) -> Vec<(Key, Option)>; + } +} diff --git a/pallets/oracle/src/benchmarking.rs b/pallets/oracle/src/benchmarking.rs new file mode 100644 index 00000000..7c8cc8f2 --- /dev/null +++ b/pallets/oracle/src/benchmarking.rs @@ -0,0 +1,54 @@ +use super::*; +use crate::Pallet as Oracle; + +use frame_benchmarking::v2::*; + +use frame_support::assert_ok; +use frame_system::{Pallet as System, RawOrigin}; + +#[instance_benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn feed_values(x: Linear<0, { T::BenchmarkHelper::get_currency_id_value_pairs().len() as u32 }>) { + // Register the caller + let caller: T::AccountId = whitelisted_caller(); + T::Members::add(&caller); + + let values = T::BenchmarkHelper::get_currency_id_value_pairs()[..x as usize] + .to_vec() + .try_into() + .expect("Must succeed since at worst the length remained the same."); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), values); + + assert!(HasDispatched::::get().contains(&caller)); + } + + #[benchmark] + fn on_finalize() { + // Register the caller + let caller: T::AccountId = whitelisted_caller(); + T::Members::add(&caller); + + // Feed some values before running `on_finalize` hook + System::::set_block_number(1u32.into()); + let values = T::BenchmarkHelper::get_currency_id_value_pairs(); + assert_ok!(Oracle::::feed_values(RawOrigin::Signed(caller).into(), values)); + + #[block] + { + Oracle::::on_finalize(System::::block_number()); + } + + assert!(!HasDispatched::::exists()); + } + + impl_benchmark_test_suite! { + Oracle, + crate::mock::new_test_ext(), + crate::mock::Test, + } +} diff --git a/pallets/oracle/src/default_combine_data.rs b/pallets/oracle/src/default_combine_data.rs new file mode 100644 index 00000000..e294d2ce --- /dev/null +++ b/pallets/oracle/src/default_combine_data.rs @@ -0,0 +1,40 @@ +use crate::{Config, MomentOf, TimestampedValueOf}; +use frame_support::traits::{Get, Time}; +use orml_traits::CombineData; +use sp_runtime::traits::Saturating; +use sp_std::{marker, prelude::*}; + +/// Sort by value and returns median timestamped value. +/// Returns prev_value if not enough valid values. +pub struct DefaultCombineData(marker::PhantomData<(T, I, MinimumCount, ExpiresIn)>); + +impl CombineData<>::OracleKey, TimestampedValueOf> + for DefaultCombineData +where + T: Config, + I: 'static, + MinimumCount: Get, + ExpiresIn: Get>, +{ + fn combine_data( + _key: &>::OracleKey, + mut values: Vec>, + prev_value: Option>, + ) -> Option> { + let expires_in = ExpiresIn::get(); + let now = T::Time::now(); + + values.retain(|x| x.timestamp.saturating_add(expires_in) > now); + + let count = values.len() as u32; + let minimum_count = MinimumCount::get(); + if count < minimum_count || count == 0 { + return prev_value; + } + + let mid_index = count / 2; + // Won't panic as `values` ensured not empty. + let (_, value, _) = values.select_nth_unstable_by(mid_index as usize, |a, b| a.value.cmp(&b.value)); + Some(value.clone()) + } +} diff --git a/pallets/oracle/src/lib.rs b/pallets/oracle/src/lib.rs new file mode 100644 index 00000000..ce7ac307 --- /dev/null +++ b/pallets/oracle/src/lib.rs @@ -0,0 +1,297 @@ +//! # Oracle +//! A module to allow oracle operators to feed external data. +//! +//! - [`Config`](./trait.Config.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) +//! +//! ## Overview +//! +//! This module exposes capabilities for oracle operators to feed external +//! offchain data. The raw values can be combined to provide an aggregated +//! value. +//! +//! The data is valid only if feeded by an authorized operator. +//! `pallet_membership` in FRAME can be used to as source of `T::Members`. + +#![cfg_attr(not(feature = "std"), no_std)] +// Disable the following two lints since they originate from an external macro (namely decl_storage) +#![allow(clippy::string_lit_as_bytes)] +#![allow(clippy::unused_unit)] + +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; + +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; + +use frame_support::{ + dispatch::Pays, + ensure, + pallet_prelude::*, + traits::{ChangeMembers, Get, SortedMembers, Time}, + weights::Weight, + Parameter, +}; +use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; +pub use orml_traits::{CombineData, DataFeeder, DataProvider, DataProviderExtended, OnNewData}; +use orml_utilities::OrderedSet; +use scale_info::TypeInfo; +use sp_runtime::{traits::Member, DispatchResult, RuntimeDebug}; +use sp_std::{prelude::*, vec}; + +pub use crate::default_combine_data::DefaultCombineData; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +mod default_combine_data; +mod mock; +mod tests; +mod weights; + +pub use module::*; +pub use weights::WeightInfo; + +#[cfg(feature = "runtime-benchmarks")] +/// Helper trait for benchmarking. +pub trait BenchmarkHelper> { + /// Returns a list of `(oracle_key, oracle_value)` pairs to be used for + /// benchmarking. + /// + /// NOTE: User should ensure to at least submit two values, otherwise the + /// benchmark linear analysis might fail. + fn get_currency_id_value_pairs() -> BoundedVec<(OracleKey, OracleValue), L>; +} + +#[cfg(feature = "runtime-benchmarks")] +impl> BenchmarkHelper for () { + fn get_currency_id_value_pairs() -> BoundedVec<(OracleKey, OracleValue), L> { + BoundedVec::default() + } +} + +#[frame_support::pallet] +pub mod module { + use super::*; + + pub(crate) type MomentOf = <>::Time as Time>::Moment; + pub(crate) type TimestampedValueOf = TimestampedValue<>::OracleValue, MomentOf>; + + #[derive(Encode, Decode, RuntimeDebug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, TypeInfo, MaxEncodedLen)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] + pub struct TimestampedValue { + pub value: Value, + pub timestamp: Moment, + } + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Hook on new data received + type OnNewData: OnNewData; + + /// Provide the implementation to combine raw values to produce + /// aggregated value + type CombineData: CombineData>; + + /// Time provider + type Time: Time; + + /// The data key type + type OracleKey: Parameter + Member + MaxEncodedLen; + + /// The data value type + type OracleValue: Parameter + Member + Ord + MaxEncodedLen; + + /// The root operator account id, record all sudo feeds on this account. + #[pallet::constant] + type RootOperatorAccountId: Get; + + /// Oracle operators. + type Members: SortedMembers; + + /// Weight information for extrinsics in this module. + type WeightInfo: WeightInfo; + + /// Maximum size of HasDispatched + #[pallet::constant] + type MaxHasDispatchedSize: Get; + + /// Maximum size the vector used for feed values + #[pallet::constant] + type MaxFeedValues: Get; + + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper: BenchmarkHelper; + } + + #[pallet::error] + pub enum Error { + /// Sender does not have permission + NoPermission, + /// Feeder has already feeded at this block + AlreadyFeeded, + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// New feed data is submitted. + NewFeedData { + sender: T::AccountId, + values: Vec<(T::OracleKey, T::OracleValue)>, + }, + } + + /// Raw values for each oracle operators + #[pallet::storage] + #[pallet::getter(fn raw_values)] + pub type RawValues, I: 'static = ()> = + StorageDoubleMap<_, Twox64Concat, T::AccountId, Twox64Concat, T::OracleKey, TimestampedValueOf>; + + /// Up to date combined value from Raw Values + #[pallet::storage] + #[pallet::getter(fn values)] + pub type Values, I: 'static = ()> = + StorageMap<_, Twox64Concat, >::OracleKey, TimestampedValueOf>; + + /// If an oracle operator has fed a value in this block + #[pallet::storage] + pub(crate) type HasDispatched, I: 'static = ()> = + StorageValue<_, OrderedSet, ValueQuery>; + + #[pallet::pallet] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + /// `on_initialize` to return the weight used in `on_finalize`. + fn on_initialize(_n: BlockNumberFor) -> Weight { + T::WeightInfo::on_finalize() + } + + fn on_finalize(_n: BlockNumberFor) { + // cleanup for next block + >::kill(); + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + /// Feed the external value. + /// + /// Require authorized operator. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::feed_values(values.len() as u32))] + pub fn feed_values( + origin: OriginFor, + values: BoundedVec<(T::OracleKey, T::OracleValue), T::MaxFeedValues>, + ) -> DispatchResultWithPostInfo { + let feeder = ensure_signed(origin.clone()) + .map(Some) + .or_else(|_| ensure_root(origin).map(|_| None))?; + + let who = Self::ensure_account(feeder)?; + + // ensure account hasn't dispatched an updated yet + ensure!( + HasDispatched::::mutate(|set| set.insert(who.clone())), + Error::::AlreadyFeeded + ); + + Self::do_feed_values(who, values.into())?; + Ok(Pays::No.into()) + } + } +} + +impl, I: 'static> Pallet { + pub fn read_raw_values(key: &T::OracleKey) -> Vec> { + T::Members::sorted_members() + .iter() + .chain([T::RootOperatorAccountId::get()].iter()) + .filter_map(|x| Self::raw_values(x, key)) + .collect() + } + + /// Fetch current combined value. + pub fn get(key: &T::OracleKey) -> Option> { + Self::values(key) + } + + #[allow(clippy::complexity)] + pub fn get_all_values() -> Vec<(T::OracleKey, Option>)> { + >::iter().map(|(k, v)| (k, Some(v))).collect() + } + + fn combined(key: &T::OracleKey) -> Option> { + let values = Self::read_raw_values(key); + T::CombineData::combine_data(key, values, Self::values(key)) + } + + fn ensure_account(who: Option) -> Result { + // ensure feeder is authorized + if let Some(who) = who { + ensure!(T::Members::contains(&who), Error::::NoPermission); + Ok(who) + } else { + Ok(T::RootOperatorAccountId::get()) + } + } + + fn do_feed_values(who: T::AccountId, values: Vec<(T::OracleKey, T::OracleValue)>) -> DispatchResult { + let now = T::Time::now(); + for (key, value) in &values { + let timestamped = TimestampedValue { + value: value.clone(), + timestamp: now, + }; + RawValues::::insert(&who, key, timestamped); + + // Update `Values` storage if `combined` yielded result. + if let Some(combined) = Self::combined(key) { + >::insert(key, combined); + } + + T::OnNewData::on_new_data(&who, key, value); + } + Self::deposit_event(Event::NewFeedData { sender: who, values }); + Ok(()) + } +} + +impl, I: 'static> ChangeMembers for Pallet { + fn change_members_sorted(_incoming: &[T::AccountId], outgoing: &[T::AccountId], _new: &[T::AccountId]) { + // remove values + for removed in outgoing { + let _ = RawValues::::clear_prefix(removed, u32::MAX, None); + } + } + + fn set_prime(_prime: Option) { + // nothing + } +} + +impl, I: 'static> DataProvider for Pallet { + fn get(key: &T::OracleKey) -> Option { + Self::get(key).map(|timestamped_value| timestamped_value.value) + } +} +impl, I: 'static> DataProviderExtended> for Pallet { + fn get_no_op(key: &T::OracleKey) -> Option> { + Self::get(key) + } + + #[allow(clippy::complexity)] + fn get_all_values() -> Vec<(T::OracleKey, Option>)> { + Self::get_all_values() + } +} + +impl, I: 'static> DataFeeder for Pallet { + fn feed_value(who: Option, key: T::OracleKey, value: T::OracleValue) -> DispatchResult { + Self::do_feed_values(Self::ensure_account(who)?, vec![(key, value)]) + } +} diff --git a/pallets/oracle/src/mock.rs b/pallets/oracle/src/mock.rs new file mode 100644 index 00000000..d289439f --- /dev/null +++ b/pallets/oracle/src/mock.rs @@ -0,0 +1,107 @@ +#![cfg(test)] + +use super::*; + +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{ConstU32, SortedMembers}, +}; +use sp_runtime::{traits::IdentityLookup, BuildStorage}; + +use std::cell::RefCell; + +mod oracle { + pub use super::super::*; +} + +pub type AccountId = u128; +type Key = u32; +type Value = u32; + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; +} + +thread_local! { + static TIME: RefCell = RefCell::new(0); + static MEMBERS: RefCell> = RefCell::new(vec![1, 2, 3]); +} + +pub struct Timestamp; +impl Time for Timestamp { + type Moment = u32; + + fn now() -> Self::Moment { + TIME.with(|v| *v.borrow()) + } +} + +impl Timestamp { + pub fn set_timestamp(val: u32) { + TIME.with(|v| *v.borrow_mut() = val); + } +} + +parameter_types! { + pub const RootOperatorAccountId: AccountId = 4; + pub const MaxFeedValues: u32 = 5; +} + +pub struct Members; + +impl SortedMembers for Members { + fn sorted_members() -> Vec { + MEMBERS.with(|v| v.borrow().clone()) + } + + #[cfg(feature = "runtime-benchmarks")] + fn add(who: &AccountId) { + MEMBERS.with(|v| v.borrow_mut().push(*who)); + } +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type OnNewData = (); + type CombineData = DefaultCombineData, ConstU32<600>>; + type Time = Timestamp; + type OracleKey = Key; + type OracleValue = Value; + type RootOperatorAccountId = RootOperatorAccountId; + type Members = Members; + type WeightInfo = (); + type MaxHasDispatchedSize = ConstU32<100>; + type MaxFeedValues = MaxFeedValues; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Test { + System: frame_system, + ModuleOracle: oracle, + } +); + +pub fn set_members(members: Vec) { + MEMBERS.with(|v| *v.borrow_mut() = members); +} + +// This function basically just builds a genesis storage key/value store +// according to our desired mockup. +pub fn new_test_ext() -> sp_io::TestExternalities { + let storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + let mut t: sp_io::TestExternalities = storage.into(); + + t.execute_with(|| { + Timestamp::set_timestamp(12345); + }); + + t +} diff --git a/pallets/oracle/src/tests.rs b/pallets/oracle/src/tests.rs new file mode 100644 index 00000000..2fa02f31 --- /dev/null +++ b/pallets/oracle/src/tests.rs @@ -0,0 +1,356 @@ +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::*; + +#[test] +fn should_feed_values_from_member() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let account_id: AccountId = 1; + + assert_noop!( + ModuleOracle::feed_values( + RuntimeOrigin::signed(5), + vec![(50, 1000), (51, 900), (52, 800)].try_into().unwrap() + ), + Error::::NoPermission, + ); + + assert_eq!( + ModuleOracle::feed_values( + RuntimeOrigin::signed(account_id), + vec![(50, 1000), (51, 900), (52, 800)].try_into().unwrap() + ) + .unwrap() + .pays_fee, + Pays::No + ); + System::assert_last_event(RuntimeEvent::ModuleOracle(crate::Event::NewFeedData { + sender: 1, + values: vec![(50, 1000), (51, 900), (52, 800)], + })); + + assert_eq!( + ModuleOracle::raw_values(&account_id, &50), + Some(TimestampedValue { + value: 1000, + timestamp: 12345, + }) + ); + + assert_eq!( + ModuleOracle::raw_values(&account_id, &51), + Some(TimestampedValue { + value: 900, + timestamp: 12345, + }) + ); + + assert_eq!( + ModuleOracle::raw_values(&account_id, &52), + Some(TimestampedValue { + value: 800, + timestamp: 12345, + }) + ); + }); +} + +#[test] +fn should_feed_values_from_root() { + new_test_ext().execute_with(|| { + let root_feeder: AccountId = RootOperatorAccountId::get(); + + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::root(), + vec![(50, 1000), (51, 900), (52, 800)].try_into().unwrap() + )); + + // Or feed from root using the DataFeeder trait with None + assert_ok!(ModuleOracle::feed_value(None, 53, 700)); + + assert_eq!( + ModuleOracle::raw_values(&root_feeder, &50), + Some(TimestampedValue { + value: 1000, + timestamp: 12345, + }) + ); + + assert_eq!( + ModuleOracle::raw_values(&root_feeder, &51), + Some(TimestampedValue { + value: 900, + timestamp: 12345, + }) + ); + + assert_eq!( + ModuleOracle::raw_values(&root_feeder, &52), + Some(TimestampedValue { + value: 800, + timestamp: 12345, + }) + ); + + assert_eq!( + ModuleOracle::raw_values(&root_feeder, &53), + Some(TimestampedValue { + value: 700, + timestamp: 12345, + }) + ); + }); +} + +#[test] +fn should_not_feed_values_from_root_directly() { + new_test_ext().execute_with(|| { + let root_feeder: AccountId = RootOperatorAccountId::get(); + + assert_noop!( + ModuleOracle::feed_values( + RuntimeOrigin::signed(root_feeder), + vec![(50, 1000), (51, 900), (52, 800)].try_into().unwrap() + ), + Error::::NoPermission, + ); + }); +} + +#[test] +fn should_read_raw_values() { + new_test_ext().execute_with(|| { + let key: u32 = 50; + + let raw_values = ModuleOracle::read_raw_values(&key); + assert_eq!(raw_values, vec![]); + + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(key, 1000)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(key, 1200)].try_into().unwrap() + )); + + let raw_values = ModuleOracle::read_raw_values(&key); + assert_eq!( + raw_values, + vec![ + TimestampedValue { + value: 1000, + timestamp: 12345, + }, + TimestampedValue { + value: 1200, + timestamp: 12345, + }, + ] + ); + }); +} + +#[test] +fn should_combined_data() { + new_test_ext().execute_with(|| { + let key: u32 = 50; + + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(key, 1300)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(key, 1000)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(3), + vec![(key, 1200)].try_into().unwrap() + )); + + let expected = Some(TimestampedValue { + value: 1200, + timestamp: 12345, + }); + + assert_eq!(ModuleOracle::get(&key), expected); + + Timestamp::set_timestamp(23456); + + assert_eq!(ModuleOracle::get(&key), expected); + }); +} + +#[test] +fn should_return_none_for_non_exist_key() { + new_test_ext().execute_with(|| { + assert_eq!(ModuleOracle::get(&50), None); + }); +} + +#[test] +fn multiple_calls_should_fail() { + new_test_ext().execute_with(|| { + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 1300)].try_into().unwrap() + )); + + // Fails feeding by the extrinsic + assert_noop!( + ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1300)].try_into().unwrap()), + Error::::AlreadyFeeded, + ); + + // But not if fed thought the trait internally + assert_ok!(ModuleOracle::feed_value(Some(1), 50, 1300)); + + ModuleOracle::on_finalize(1); + + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 1300)].try_into().unwrap() + )); + }); +} + +#[test] +fn get_all_values_should_work() { + new_test_ext().execute_with(|| { + let eur: u32 = 1; + let jpy: u32 = 2; + + assert_eq!(ModuleOracle::get_all_values(), vec![]); + + // feed eur & jpy + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(eur, 1300)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(eur, 1000)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(3), + vec![(jpy, 9000)].try_into().unwrap() + )); + + // not enough eur & jpy prices + assert_eq!(ModuleOracle::get(&eur), None); + assert_eq!(ModuleOracle::get(&jpy), None); + assert_eq!(ModuleOracle::get_all_values(), vec![]); + + // finalize block + ModuleOracle::on_finalize(1); + + // feed eur & jpy + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(3), + vec![(eur, 1200)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(jpy, 8000)].try_into().unwrap() + )); + + // enough eur prices + let eur_price = Some(TimestampedValue { + value: 1200, + timestamp: 12345, + }); + assert_eq!(ModuleOracle::get(&eur), eur_price); + + // not enough jpy prices + assert_eq!(ModuleOracle::get(&jpy), None); + + assert_eq!(ModuleOracle::get_all_values(), vec![(eur, eur_price)]); + + // feed jpy + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(jpy, 7000)].try_into().unwrap() + )); + + // enough jpy prices + let jpy_price = Some(TimestampedValue { + value: 8000, + timestamp: 12345, + }); + assert_eq!(ModuleOracle::get(&jpy), jpy_price); + + assert_eq!(ModuleOracle::get_all_values(), vec![(eur, eur_price), (jpy, jpy_price)]); + }); +} + +#[test] +fn change_member_should_work() { + new_test_ext().execute_with(|| { + set_members(vec![2, 3, 4]); + >::change_members_sorted(&[4], &[1], &[2, 3, 4]); + assert_noop!( + ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1000)].try_into().unwrap()), + Error::::NoPermission, + ); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(50, 1000)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(4), + vec![(50, 1000)].try_into().unwrap() + )); + }); +} + +#[test] +fn should_clear_data_for_removed_members() { + new_test_ext().execute_with(|| { + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 1000)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(50, 1000)].try_into().unwrap() + )); + + ModuleOracle::change_members_sorted(&[4], &[1], &[2, 3, 4]); + + assert_eq!(ModuleOracle::raw_values(&1, 50), None); + }); +} + +#[test] +fn values_are_updated_on_feed() { + new_test_ext().execute_with(|| { + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 900)].try_into().unwrap() + )); + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(2), + vec![(50, 1000)].try_into().unwrap() + )); + + assert_eq!(ModuleOracle::values(50), None); + + // Upon the third price feed, the value is updated immediately after `combine` + // can produce valid result. + assert_ok!(ModuleOracle::feed_values( + RuntimeOrigin::signed(3), + vec![(50, 1100)].try_into().unwrap() + )); + assert_eq!( + ModuleOracle::values(50), + Some(TimestampedValue { + value: 1000, + timestamp: 12345, + }) + ); + }); +} diff --git a/pallets/oracle/src/weights.rs b/pallets/oracle/src/weights.rs new file mode 100644 index 00000000..32bf2879 --- /dev/null +++ b/pallets/oracle/src/weights.rs @@ -0,0 +1,51 @@ +//! Autogenerated weights for orml_oracle +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-05-04, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// /Users/xiliangchen/projects/acala/target/release/acala +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=orml_oracle +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./oracle/src/weights.rs +// --template +// ../templates/orml-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for orml_oracle. +pub trait WeightInfo { + fn feed_values(c: u32, ) -> Weight; + fn on_finalize() -> Weight; +} + +/// Default weights. +impl WeightInfo for () { + fn feed_values(c: u32, ) -> Weight { + Weight::from_parts(16_800_000, 0) + // Standard Error: 84_000 + .saturating_add(Weight::from_parts(3_600_000, 0).saturating_mul(c as u64)) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + .saturating_add(RocksDbWeight::get().writes((2 as u64).saturating_mul(c as u64))) + } + fn on_finalize() -> Weight { + Weight::from_parts(3_000_000, 0) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } +} From ebe8b6a037465202b8d10a48427f93de4373e76b Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:24:55 +0530 Subject: [PATCH 31/63] update traits --- Cargo.lock | 1 + pallets/oracle/src/benchmarking.rs | 4 +- pallets/oracle/src/default_combine_data.rs | 12 +- pallets/oracle/src/lib.rs | 79 ++++++--- pallets/oracle/src/tests.rs | 75 +++------ primitives/Cargo.toml | 1 + primitives/src/traits/mod.rs | 2 + primitives/src/traits/oracle.rs | 162 ++++++++++++++++++ primitives/src/types.rs | 1 + primitives/src/types/ordered_set.rs | 185 +++++++++++++++++++++ 10 files changed, 441 insertions(+), 81 deletions(-) create mode 100644 primitives/src/traits/oracle.rs create mode 100644 primitives/src/types/ordered_set.rs diff --git a/Cargo.lock b/Cargo.lock index 993b3408..27f1a76a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14324,6 +14324,7 @@ dependencies = [ "frame-support", "frame-system", "hex", + "impl-trait-for-tuples", "log", "parity-scale-codec", "scale-info", diff --git a/pallets/oracle/src/benchmarking.rs b/pallets/oracle/src/benchmarking.rs index 7c8cc8f2..8403e1f2 100644 --- a/pallets/oracle/src/benchmarking.rs +++ b/pallets/oracle/src/benchmarking.rs @@ -11,7 +11,9 @@ mod benchmarks { use super::*; #[benchmark] - fn feed_values(x: Linear<0, { T::BenchmarkHelper::get_currency_id_value_pairs().len() as u32 }>) { + fn feed_values( + x: Linear<0, { T::BenchmarkHelper::get_currency_id_value_pairs().len() as u32 }>, + ) { // Register the caller let caller: T::AccountId = whitelisted_caller(); T::Members::add(&caller); diff --git a/pallets/oracle/src/default_combine_data.rs b/pallets/oracle/src/default_combine_data.rs index e294d2ce..f6e29c49 100644 --- a/pallets/oracle/src/default_combine_data.rs +++ b/pallets/oracle/src/default_combine_data.rs @@ -1,14 +1,17 @@ use crate::{Config, MomentOf, TimestampedValueOf}; use frame_support::traits::{Get, Time}; -use orml_traits::CombineData; use sp_runtime::traits::Saturating; use sp_std::{marker, prelude::*}; +use tangle_primitives::CombineData; /// Sort by value and returns median timestamped value. /// Returns prev_value if not enough valid values. -pub struct DefaultCombineData(marker::PhantomData<(T, I, MinimumCount, ExpiresIn)>); +pub struct DefaultCombineData( + marker::PhantomData<(T, I, MinimumCount, ExpiresIn)>, +); -impl CombineData<>::OracleKey, TimestampedValueOf> +impl + CombineData<>::OracleKey, TimestampedValueOf> for DefaultCombineData where T: Config, @@ -34,7 +37,8 @@ where let mid_index = count / 2; // Won't panic as `values` ensured not empty. - let (_, value, _) = values.select_nth_unstable_by(mid_index as usize, |a, b| a.value.cmp(&b.value)); + let (_, value, _) = + values.select_nth_unstable_by(mid_index as usize, |a, b| a.value.cmp(&b.value)); Some(value.clone()) } } diff --git a/pallets/oracle/src/lib.rs b/pallets/oracle/src/lib.rs index ce7ac307..daff0802 100644 --- a/pallets/oracle/src/lib.rs +++ b/pallets/oracle/src/lib.rs @@ -33,11 +33,13 @@ use frame_support::{ Parameter, }; use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; -pub use orml_traits::{CombineData, DataFeeder, DataProvider, DataProviderExtended, OnNewData}; -use orml_utilities::OrderedSet; use scale_info::TypeInfo; use sp_runtime::{traits::Member, DispatchResult, RuntimeDebug}; use sp_std::{prelude::*, vec}; +use tangle_primitives::ordered_set::OrderedSet; +pub use tangle_primitives::{ + CombineData, DataFeeder, DataProvider, DataProviderExtended, OnNewData, +}; pub use crate::default_combine_data::DefaultCombineData; @@ -75,9 +77,22 @@ pub mod module { use super::*; pub(crate) type MomentOf = <>::Time as Time>::Moment; - pub(crate) type TimestampedValueOf = TimestampedValue<>::OracleValue, MomentOf>; - - #[derive(Encode, Decode, RuntimeDebug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, TypeInfo, MaxEncodedLen)] + pub(crate) type TimestampedValueOf = + TimestampedValue<>::OracleValue, MomentOf>; + + #[derive( + Encode, + Decode, + RuntimeDebug, + Eq, + PartialEq, + Clone, + Copy, + Ord, + PartialOrd, + TypeInfo, + MaxEncodedLen, + )] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct TimestampedValue { pub value: Value, @@ -86,7 +101,8 @@ pub mod module { #[pallet::config] pub trait Config: frame_system::Config { - type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; /// Hook on new data received type OnNewData: OnNewData; @@ -123,7 +139,11 @@ pub mod module { type MaxFeedValues: Get; #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper: BenchmarkHelper; + type BenchmarkHelper: BenchmarkHelper< + Self::OracleKey, + Self::OracleValue, + Self::MaxFeedValues, + >; } #[pallet::error] @@ -138,17 +158,20 @@ pub mod module { #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event, I: 'static = ()> { /// New feed data is submitted. - NewFeedData { - sender: T::AccountId, - values: Vec<(T::OracleKey, T::OracleValue)>, - }, + NewFeedData { sender: T::AccountId, values: Vec<(T::OracleKey, T::OracleValue)> }, } /// Raw values for each oracle operators #[pallet::storage] #[pallet::getter(fn raw_values)] - pub type RawValues, I: 'static = ()> = - StorageDoubleMap<_, Twox64Concat, T::AccountId, Twox64Concat, T::OracleKey, TimestampedValueOf>; + pub type RawValues, I: 'static = ()> = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, + Twox64Concat, + T::OracleKey, + TimestampedValueOf, + >; /// Up to date combined value from Raw Values #[pallet::storage] @@ -240,13 +263,13 @@ impl, I: 'static> Pallet { } } - fn do_feed_values(who: T::AccountId, values: Vec<(T::OracleKey, T::OracleValue)>) -> DispatchResult { + fn do_feed_values( + who: T::AccountId, + values: Vec<(T::OracleKey, T::OracleValue)>, + ) -> DispatchResult { let now = T::Time::now(); for (key, value) in &values { - let timestamped = TimestampedValue { - value: value.clone(), - timestamp: now, - }; + let timestamped = TimestampedValue { value: value.clone(), timestamp: now }; RawValues::::insert(&who, key, timestamped); // Update `Values` storage if `combined` yielded result. @@ -262,7 +285,11 @@ impl, I: 'static> Pallet { } impl, I: 'static> ChangeMembers for Pallet { - fn change_members_sorted(_incoming: &[T::AccountId], outgoing: &[T::AccountId], _new: &[T::AccountId]) { + fn change_members_sorted( + _incoming: &[T::AccountId], + outgoing: &[T::AccountId], + _new: &[T::AccountId], + ) { // remove values for removed in outgoing { let _ = RawValues::::clear_prefix(removed, u32::MAX, None); @@ -279,7 +306,9 @@ impl, I: 'static> DataProvider for Pa Self::get(key).map(|timestamped_value| timestamped_value.value) } } -impl, I: 'static> DataProviderExtended> for Pallet { +impl, I: 'static> DataProviderExtended> + for Pallet +{ fn get_no_op(key: &T::OracleKey) -> Option> { Self::get(key) } @@ -290,8 +319,14 @@ impl, I: 'static> DataProviderExtended, I: 'static> DataFeeder for Pallet { - fn feed_value(who: Option, key: T::OracleKey, value: T::OracleValue) -> DispatchResult { +impl, I: 'static> DataFeeder + for Pallet +{ + fn feed_value( + who: Option, + key: T::OracleKey, + value: T::OracleValue, + ) -> DispatchResult { Self::do_feed_values(Self::ensure_account(who)?, vec![(key, value)]) } } diff --git a/pallets/oracle/src/tests.rs b/pallets/oracle/src/tests.rs index 2fa02f31..69b7f62f 100644 --- a/pallets/oracle/src/tests.rs +++ b/pallets/oracle/src/tests.rs @@ -34,26 +34,17 @@ fn should_feed_values_from_member() { assert_eq!( ModuleOracle::raw_values(&account_id, &50), - Some(TimestampedValue { - value: 1000, - timestamp: 12345, - }) + Some(TimestampedValue { value: 1000, timestamp: 12345 }) ); assert_eq!( ModuleOracle::raw_values(&account_id, &51), - Some(TimestampedValue { - value: 900, - timestamp: 12345, - }) + Some(TimestampedValue { value: 900, timestamp: 12345 }) ); assert_eq!( ModuleOracle::raw_values(&account_id, &52), - Some(TimestampedValue { - value: 800, - timestamp: 12345, - }) + Some(TimestampedValue { value: 800, timestamp: 12345 }) ); }); } @@ -73,34 +64,22 @@ fn should_feed_values_from_root() { assert_eq!( ModuleOracle::raw_values(&root_feeder, &50), - Some(TimestampedValue { - value: 1000, - timestamp: 12345, - }) + Some(TimestampedValue { value: 1000, timestamp: 12345 }) ); assert_eq!( ModuleOracle::raw_values(&root_feeder, &51), - Some(TimestampedValue { - value: 900, - timestamp: 12345, - }) + Some(TimestampedValue { value: 900, timestamp: 12345 }) ); assert_eq!( ModuleOracle::raw_values(&root_feeder, &52), - Some(TimestampedValue { - value: 800, - timestamp: 12345, - }) + Some(TimestampedValue { value: 800, timestamp: 12345 }) ); assert_eq!( ModuleOracle::raw_values(&root_feeder, &53), - Some(TimestampedValue { - value: 700, - timestamp: 12345, - }) + Some(TimestampedValue { value: 700, timestamp: 12345 }) ); }); } @@ -141,14 +120,8 @@ fn should_read_raw_values() { assert_eq!( raw_values, vec![ - TimestampedValue { - value: 1000, - timestamp: 12345, - }, - TimestampedValue { - value: 1200, - timestamp: 12345, - }, + TimestampedValue { value: 1000, timestamp: 12345 }, + TimestampedValue { value: 1200, timestamp: 12345 }, ] ); }); @@ -172,10 +145,7 @@ fn should_combined_data() { vec![(key, 1200)].try_into().unwrap() )); - let expected = Some(TimestampedValue { - value: 1200, - timestamp: 12345, - }); + let expected = Some(TimestampedValue { value: 1200, timestamp: 12345 }); assert_eq!(ModuleOracle::get(&key), expected); @@ -202,7 +172,10 @@ fn multiple_calls_should_fail() { // Fails feeding by the extrinsic assert_noop!( - ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1300)].try_into().unwrap()), + ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 1300)].try_into().unwrap() + ), Error::::AlreadyFeeded, ); @@ -259,10 +232,7 @@ fn get_all_values_should_work() { )); // enough eur prices - let eur_price = Some(TimestampedValue { - value: 1200, - timestamp: 12345, - }); + let eur_price = Some(TimestampedValue { value: 1200, timestamp: 12345 }); assert_eq!(ModuleOracle::get(&eur), eur_price); // not enough jpy prices @@ -277,10 +247,7 @@ fn get_all_values_should_work() { )); // enough jpy prices - let jpy_price = Some(TimestampedValue { - value: 8000, - timestamp: 12345, - }); + let jpy_price = Some(TimestampedValue { value: 8000, timestamp: 12345 }); assert_eq!(ModuleOracle::get(&jpy), jpy_price); assert_eq!(ModuleOracle::get_all_values(), vec![(eur, eur_price), (jpy, jpy_price)]); @@ -293,7 +260,10 @@ fn change_member_should_work() { set_members(vec![2, 3, 4]); >::change_members_sorted(&[4], &[1], &[2, 3, 4]); assert_noop!( - ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1000)].try_into().unwrap()), + ModuleOracle::feed_values( + RuntimeOrigin::signed(1), + vec![(50, 1000)].try_into().unwrap() + ), Error::::NoPermission, ); assert_ok!(ModuleOracle::feed_values( @@ -347,10 +317,7 @@ fn values_are_updated_on_feed() { )); assert_eq!( ModuleOracle::values(50), - Some(TimestampedValue { - value: 1000, - timestamp: 12345, - }) + Some(TimestampedValue { value: 1000, timestamp: 12345 }) ); }); } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 6dda244e..12d91d01 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -23,6 +23,7 @@ sp-staking = { workspace = true } ethabi = { workspace = true } fp-evm = { workspace = true } frame-system = { workspace = true } +impl-trait-for-tuples = "0.2.2" # Arkworks ark-bn254 = { workspace = true, optional = true } diff --git a/primitives/src/traits/mod.rs b/primitives/src/traits/mod.rs index 47b46b05..f2011b3a 100644 --- a/primitives/src/traits/mod.rs +++ b/primitives/src/traits/mod.rs @@ -1,7 +1,9 @@ pub mod assets; pub mod multi_asset_delegation; +pub mod oracle; pub mod services; pub use assets::*; pub use multi_asset_delegation::*; +pub use oracle::*; pub use services::*; diff --git a/primitives/src/traits/oracle.rs b/primitives/src/traits/oracle.rs new file mode 100644 index 00000000..2ae57dc9 --- /dev/null +++ b/primitives/src/traits/oracle.rs @@ -0,0 +1,162 @@ +/// New data handler +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait OnNewData { + /// New data is available + fn on_new_data(who: &AccountId, key: &Key, value: &Value); +} + +/// Combine data provided by operators +pub trait CombineData { + /// Combine data provided by operators + fn combine_data( + key: &Key, + values: Vec, + prev_value: Option, + ) -> Option; +} + +use sp_runtime::DispatchResult; +use sp_std::vec::Vec; + +/// Data provider with ability to provide data with no-op, and provide all data. +pub trait DataFeeder { + /// Provide a new value for a given key from an operator + fn feed_value(who: Option, key: Key, value: Value) -> DispatchResult; +} + +/// A simple trait to provide data +pub trait DataProvider { + /// Get data by key + fn get(key: &Key) -> Option; +} + +/// Extended data provider to provide timestamped data by key with no-op, and +/// all data. +pub trait DataProviderExtended { + /// Get timestamped value by key + fn get_no_op(key: &Key) -> Option; + /// Provide a list of tuples of key and timestamped value + fn get_all_values() -> Vec<(Key, Option)>; +} + +#[allow(dead_code)] // rust cannot detect usage in macro_rules +pub fn median(mut items: Vec) -> Option { + if items.is_empty() { + return None; + } + + let mid_index = items.len() / 2; + + // Won't panic as `items` ensured not empty. + let (_, item, _) = items.select_nth_unstable(mid_index); + Some(item.clone()) +} + +#[macro_export] +macro_rules! create_median_value_data_provider { + ($name:ident, $key:ty, $value:ty, $timestamped_value:ty, [$( $provider:ty ),*]) => { + pub struct $name; + impl $crate::DataProvider<$key, $value> for $name { + fn get(key: &$key) -> Option<$value> { + let mut values = vec![]; + $( + if let Some(v) = <$provider as $crate::DataProvider<$key, $value>>::get(&key) { + values.push(v); + } + )* + $crate::data_provider::median(values) + } + } + impl $crate::DataProviderExtended<$key, $timestamped_value> for $name { + fn get_no_op(key: &$key) -> Option<$timestamped_value> { + let mut values = vec![]; + $( + if let Some(v) = <$provider as $crate::DataProviderExtended<$key, $timestamped_value>>::get_no_op(&key) { + values.push(v); + } + )* + $crate::data_provider::median(values) + } + fn get_all_values() -> Vec<($key, Option<$timestamped_value>)> { + let mut keys = sp_std::collections::btree_set::BTreeSet::new(); + $( + <$provider as $crate::DataProviderExtended<$key, $timestamped_value>>::get_all_values() + .into_iter() + .for_each(|(k, _)| { keys.insert(k); }); + )* + keys.into_iter().map(|k| (k, Self::get_no_op(&k))).collect() + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_std::cell::RefCell; + + thread_local! { + static MOCK_PRICE_1: RefCell> = RefCell::new(None); + static MOCK_PRICE_2: RefCell> = RefCell::new(None); + static MOCK_PRICE_3: RefCell> = RefCell::new(None); + static MOCK_PRICE_4: RefCell> = RefCell::new(None); + } + + macro_rules! mock_data_provider { + ($provider:ident, $price:ident) => { + pub struct $provider; + impl $provider { + fn set_price(price: Option) { + $price.with(|v| *v.borrow_mut() = price) + } + } + impl DataProvider for $provider { + fn get(_: &u8) -> Option { + $price.with(|v| *v.borrow()) + } + } + impl DataProviderExtended for $provider { + fn get_no_op(_: &u8) -> Option { + $price.with(|v| *v.borrow()) + } + fn get_all_values() -> Vec<(u8, Option)> { + vec![(0, Self::get_no_op(&0))] + } + } + }; + } + + mock_data_provider!(Provider1, MOCK_PRICE_1); + mock_data_provider!(Provider2, MOCK_PRICE_2); + mock_data_provider!(Provider3, MOCK_PRICE_3); + mock_data_provider!(Provider4, MOCK_PRICE_4); + + create_median_value_data_provider!( + Providers, + u8, + u8, + u8, + [Provider1, Provider2, Provider3, Provider4] + ); + + #[test] + fn median_value_data_provider_works() { + assert_eq!(>::get(&0), None); + + let data = vec![ + (vec![None, None, None, Some(1)], Some(1)), + (vec![None, None, Some(2), Some(1)], Some(2)), + (vec![Some(5), Some(2), None, Some(7)], Some(5)), + (vec![Some(5), Some(13), Some(2), Some(7)], Some(7)), + ]; + + for (values, target) in data { + Provider1::set_price(values[0]); + Provider2::set_price(values[1]); + Provider3::set_price(values[2]); + Provider4::set_price(values[3]); + + assert_eq!(>::get(&0), target); + } + } +} diff --git a/primitives/src/types.rs b/primitives/src/types.rs index fd80dfab..50cf21ac 100644 --- a/primitives/src/types.rs +++ b/primitives/src/types.rs @@ -14,6 +14,7 @@ // limitations under the License. // use super::*; +pub mod ordered_set; use frame_support::pallet_prelude::*; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; diff --git a/primitives/src/types/ordered_set.rs b/primitives/src/types/ordered_set.rs new file mode 100644 index 00000000..308bd5c1 --- /dev/null +++ b/primitives/src/types/ordered_set.rs @@ -0,0 +1,185 @@ +use frame_support::{traits::Get, BoundedVec, CloneNoBound, DefaultNoBound, PartialEqNoBound}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use sp_std::{fmt, prelude::*}; + +/// An ordered set backed by `BoundedVec` +#[derive( + PartialEqNoBound, Eq, Encode, Decode, DefaultNoBound, CloneNoBound, TypeInfo, MaxEncodedLen, +)] +#[codec(mel_bound())] +#[scale_info(skip_type_params(S))] +pub struct OrderedSet< + T: Ord + Encode + Decode + MaxEncodedLen + Clone + Eq + PartialEq, + S: Get, +>(pub BoundedVec); + +impl> + OrderedSet +{ + /// Create a new empty set + pub fn new() -> Self { + Self(BoundedVec::default()) + } + + /// Create a set from a `Vec`. + /// `v` will be sorted and dedup first. + pub fn from(bv: BoundedVec) -> Self { + let mut v = bv.into_inner(); + v.sort(); + v.dedup(); + + Self::from_sorted_set(v.try_into().map_err(|_| ()).expect("Did not add any values")) + } + + /// Create a set from a `Vec`. + /// Assume `v` is sorted and contain unique elements. + pub fn from_sorted_set(bv: BoundedVec) -> Self { + Self(bv) + } + + /// Insert an element. + /// Return true if insertion happened. + pub fn insert(&mut self, value: T) -> bool { + match self.0.binary_search(&value) { + Ok(_) => false, + Err(loc) => self.0.try_insert(loc, value).is_ok(), + } + } + + /// Remove an element. + /// Return true if removal happened. + pub fn remove(&mut self, value: &T) -> bool { + match self.0.binary_search(value) { + Ok(loc) => { + self.0.remove(loc); + true + }, + Err(_) => false, + } + } + + /// Return if the set contains `value` + pub fn contains(&self, value: &T) -> bool { + self.0.binary_search(value).is_ok() + } + + /// Clear the set + pub fn clear(&mut self) { + self.0 = BoundedVec::default(); + } +} + +impl> + From> for OrderedSet +{ + fn from(v: BoundedVec) -> Self { + Self::from(v) + } +} + +#[cfg(feature = "std")] +impl fmt::Debug for OrderedSet +where + T: Ord + Encode + Decode + MaxEncodedLen + Clone + Eq + PartialEq + fmt::Debug, + S: Get, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("OrderedSet").field(&self.0).finish() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::parameter_types; + use sp_runtime::RuntimeDebug; + + parameter_types! { + #[derive(PartialEq, Eq, RuntimeDebug)] + pub const Eight: u32 = 8; + #[derive(PartialEq, Eq, RuntimeDebug)] + pub const Five: u32 = 5; + } + + #[test] + fn from() { + let v: BoundedVec = vec![4, 2, 3, 4, 3, 1].try_into().unwrap(); + let set: OrderedSet = v.into(); + assert_eq!(set, OrderedSet::::from(vec![1, 2, 3, 4].try_into().unwrap())); + } + + #[test] + fn insert() { + let mut set: OrderedSet = OrderedSet::new(); + assert_eq!(set, OrderedSet::::from(vec![].try_into().unwrap())); + + assert!(set.insert(1)); + assert_eq!(set, OrderedSet::::from(vec![1].try_into().unwrap())); + + assert!(set.insert(5)); + assert_eq!(set, OrderedSet::::from(vec![1, 5].try_into().unwrap())); + + assert!(set.insert(3)); + assert_eq!(set, OrderedSet::::from(vec![1, 3, 5].try_into().unwrap())); + + assert!(!set.insert(3)); + assert_eq!(set, OrderedSet::::from(vec![1, 3, 5].try_into().unwrap())); + } + + #[test] + fn remove() { + let mut set: OrderedSet = + OrderedSet::from(vec![1, 2, 3, 4].try_into().unwrap()); + + assert!(!set.remove(&5)); + assert_eq!(set, OrderedSet::::from(vec![1, 2, 3, 4].try_into().unwrap())); + + assert!(set.remove(&1)); + assert_eq!(set, OrderedSet::::from(vec![2, 3, 4].try_into().unwrap())); + + assert!(set.remove(&3)); + assert_eq!(set, OrderedSet::::from(vec![2, 4].try_into().unwrap())); + + assert!(!set.remove(&3)); + assert_eq!(set, OrderedSet::::from(vec![2, 4].try_into().unwrap())); + + assert!(set.remove(&4)); + assert_eq!(set, OrderedSet::::from(vec![2].try_into().unwrap())); + + assert!(set.remove(&2)); + assert_eq!(set, OrderedSet::::from(vec![].try_into().unwrap())); + + assert!(!set.remove(&2)); + assert_eq!(set, OrderedSet::::from(vec![].try_into().unwrap())); + } + + #[test] + fn contains() { + let set: OrderedSet = OrderedSet::from(vec![1, 2, 3, 4].try_into().unwrap()); + + assert!(!set.contains(&5)); + + assert!(set.contains(&1)); + + assert!(set.contains(&3)); + } + + #[test] + fn clear() { + let mut set: OrderedSet = + OrderedSet::from(vec![1, 2, 3, 4].try_into().unwrap()); + set.clear(); + assert_eq!(set, OrderedSet::new()); + } + + #[test] + fn exceeding_max_size_should_fail() { + let mut set: OrderedSet = + OrderedSet::from(vec![1, 2, 3, 4, 5].try_into().unwrap()); + let inserted = set.insert(6); + + assert!(!inserted) + } +} From 7adf9e6c03c4cc643ac4f033a99ae0712605a091 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:44:02 +0530 Subject: [PATCH 32/63] update precompile --- precompiles/oracle/Cargo.toml | 63 ++++++ precompiles/oracle/Oracle.sol | 19 ++ precompiles/oracle/src/lib.rs | 87 ++++++++ precompiles/oracle/src/mock.rs | 346 ++++++++++++++++++++++++++++++++ precompiles/oracle/src/tests.rs | 185 +++++++++++++++++ 5 files changed, 700 insertions(+) create mode 100644 precompiles/oracle/Cargo.toml create mode 100644 precompiles/oracle/Oracle.sol create mode 100644 precompiles/oracle/src/lib.rs create mode 100644 precompiles/oracle/src/mock.rs create mode 100644 precompiles/oracle/src/tests.rs diff --git a/precompiles/oracle/Cargo.toml b/precompiles/oracle/Cargo.toml new file mode 100644 index 00000000..043315ad --- /dev/null +++ b/precompiles/oracle/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "pallet-evm-precompile-oracle" +authors = { workspace = true } +description = "A Precompile to expose Oracle pallet." +edition = "2021" +version = "0.1.0" + +[dependencies] +paste = { workspace = true } + +# Moonbeam +precompile-utils = { workspace = true } + +# Substrate +frame-support = { workspace = true } +frame-system = { workspace = true } +pallet-assets = { workspace = true } +pallet-balances = { workspace = true } +pallet-timestamp = { workspace = true } +parity-scale-codec = { workspace = true, features = [ "max-encoded-len" ] } +scale-info = { workspace = true, features = [ "derive" ] } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } +tangle-primitives = { workspace = true } + +# Frontier +fp-evm = { workspace = true } +pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] } + +[dev-dependencies] +derive_more = { workspace = true, features = ["full"] } +hex-literal = { workspace = true } +libsecp256k1 = { workspace = true } +serde = { workspace = true } +sha3 = { workspace = true } + +precompile-utils = { workspace = true, features = [ "std", "testing" ] } + +pallet-timestamp = { workspace = true, features = [ "std" ] } +parity-scale-codec = { workspace = true, features = [ "max-encoded-len", "std" ] } +scale-info = { workspace = true, features = [ "derive" ] } +sp-runtime = { workspace = true, features = [ "std" ] } + +[features] +default = [ "std" ] +std = [ + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "pallet-assets/std", + "pallet-balances/std", + "pallet-evm/std", + "pallet-timestamp/std", + "parity-scale-codec/std", + "precompile-utils/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "tangle-primitives/std", +] diff --git a/precompiles/oracle/Oracle.sol b/precompiles/oracle/Oracle.sol new file mode 100644 index 00000000..3f701743 --- /dev/null +++ b/precompiles/oracle/Oracle.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title Oracle Precompile Interface +/// @notice Interface for interacting with the Oracle pallet through EVM +interface Oracle { + /// @notice Feed values into the oracle + /// @param keys Array of oracle keys + /// @param values Array of corresponding values for the keys + /// @dev The length of keys and values must match + /// @return success True if the operation was successful + function feed_values(uint256[] calldata keys, uint256[] calldata values) external returns (bool success); + + /// @notice Emitted when new values are fed into the oracle + /// @param operator The account that fed the values + /// @param keys Array of oracle keys that were updated + /// @param values Array of values that were fed + event ValuesFed(address indexed operator, uint256[] keys, uint256[] values); +} diff --git a/precompiles/oracle/src/lib.rs b/precompiles/oracle/src/lib.rs new file mode 100644 index 00000000..18fae6fa --- /dev/null +++ b/precompiles/oracle/src/lib.rs @@ -0,0 +1,87 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +use fp_evm::PrecompileHandle; +use frame_support::{ + dispatch::{GetDispatchInfo, PostDispatchInfo}, + pallet_prelude::BoundedVec, + traits::Currency, +}; +use pallet_evm::AddressMapping; +use parity_scale_codec::Codec; +use precompile_utils::prelude::*; +use sp_core::{H160, U256}; +use sp_std::{marker::PhantomData, vec::Vec}; + +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +pub struct OraclePrecompile(PhantomData); + +#[precompile_utils::precompile] +impl OraclePrecompile +where + Runtime: pallet_oracle::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, + Runtime::OracleKey: TryFrom + Into, + Runtime::OracleValue: TryFrom + Into, +{ + #[precompile::public("feedValues(uint256[],uint256[])")] + fn feed_values( + handle: &mut impl PrecompileHandle, + keys: Vec, + values: Vec, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Check that keys and values have the same length + ensure!(keys.len() == values.len(), revert("Keys and values must have the same length")); + + // Convert keys and values to the required types + let mut oracle_values = Vec::with_capacity(keys.len()); + for (key, value) in keys.into_iter().zip(values.into_iter()) { + let oracle_key = key + .try_into() + .map_err(|_| RevertReason::value_is_too_large("oracle key"))?; + let oracle_value = value + .try_into() + .map_err(|_| RevertReason::value_is_too_large("oracle value"))?; + oracle_values.push((oracle_key, oracle_value)); + } + + // Convert to BoundedVec + let bounded_values: BoundedVec<_, Runtime::MaxFeedValues> = oracle_values + .try_into() + .map_err(|_| revert("Too many values"))?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_oracle::Call::::feed_values { values: bounded_values }, + )?; + + Ok(()) + } +} diff --git a/precompiles/oracle/src/mock.rs b/precompiles/oracle/src/mock.rs new file mode 100644 index 00000000..799fdee7 --- /dev/null +++ b/precompiles/oracle/src/mock.rs @@ -0,0 +1,346 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// This file is part of pallet-evm-precompile-multi-asset-delegation package. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test utilities +use super::*; +use crate::{AssetsPrecompile, AssetsPrecompileCall}; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU64}, + weights::Weight, +}; +use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, SubstrateBlockHashMapping}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; +use serde::{Deserialize, Serialize}; +use sp_core::{ + self, + sr25519::{Public as sr25519Public, Signature}, + ConstU32, H160, U256, +}; +use sp_runtime::{ + traits::{IdentifyAccount, Verify}, + AccountId32, BuildStorage, +}; + +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; +pub type Balance = u64; + +type Block = frame_system::mocking::MockBlock; +type AssetId = u32; + +const PRECOMPILE_ADDRESS_BYTES: [u8; 32] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +]; + +#[derive( + Eq, + PartialEq, + Ord, + PartialOrd, + Clone, + Encode, + Decode, + Debug, + MaxEncodedLen, + Serialize, + Deserialize, + derive_more::Display, + scale_info::TypeInfo, +)] +pub enum TestAccount { + Empty, + Alex, + Bob, + Dave, + Charlie, + Eve, + PrecompileAddress, +} + +impl Default for TestAccount { + fn default() -> Self { + Self::Empty + } +} + +// needed for associated type in pallet_evm +impl AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> AccountId32 { + match h160_account { + a if a == H160::repeat_byte(0x01) => TestAccount::Alex.into(), + a if a == H160::repeat_byte(0x02) => TestAccount::Bob.into(), + a if a == H160::repeat_byte(0x03) => TestAccount::Charlie.into(), + a if a == H160::repeat_byte(0x04) => TestAccount::Dave.into(), + a if a == H160::repeat_byte(0x05) => TestAccount::Eve.into(), + a if a == H160::from_low_u64_be(6) => TestAccount::PrecompileAddress.into(), + _ => TestAccount::Empty.into(), + } + } +} + +impl AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> sp_core::sr25519::Public { + match h160_account { + a if a == H160::repeat_byte(0x01) => sr25519Public::from_raw([1u8; 32]), + a if a == H160::repeat_byte(0x02) => sr25519Public::from_raw([2u8; 32]), + a if a == H160::repeat_byte(0x03) => sr25519Public::from_raw([3u8; 32]), + a if a == H160::repeat_byte(0x04) => sr25519Public::from_raw([4u8; 32]), + a if a == H160::repeat_byte(0x05) => sr25519Public::from_raw([5u8; 32]), + a if a == H160::from_low_u64_be(6) => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), + _ => sr25519Public::from_raw([0u8; 32]), + } + } +} + +impl From for H160 { + fn from(x: TestAccount) -> H160 { + match x { + TestAccount::Alex => H160::repeat_byte(0x01), + TestAccount::Bob => H160::repeat_byte(0x02), + TestAccount::Charlie => H160::repeat_byte(0x03), + TestAccount::Dave => H160::repeat_byte(0x04), + TestAccount::Eve => H160::repeat_byte(0x05), + TestAccount::PrecompileAddress => H160::from_low_u64_be(6), + _ => Default::default(), + } + } +} + +impl From for AccountId32 { + fn from(x: TestAccount) -> Self { + match x { + TestAccount::Alex => AccountId32::from([1u8; 32]), + TestAccount::Bob => AccountId32::from([2u8; 32]), + TestAccount::Charlie => AccountId32::from([3u8; 32]), + TestAccount::Dave => AccountId32::from([4u8; 32]), + TestAccount::Eve => AccountId32::from([5u8; 32]), + TestAccount::PrecompileAddress => AccountId32::from(PRECOMPILE_ADDRESS_BYTES), + _ => AccountId32::from([0u8; 32]), + } + } +} + +impl From for sp_core::sr25519::Public { + fn from(x: TestAccount) -> Self { + match x { + TestAccount::Alex => sr25519Public::from_raw([1u8; 32]), + TestAccount::Bob => sr25519Public::from_raw([2u8; 32]), + TestAccount::Charlie => sr25519Public::from_raw([3u8; 32]), + TestAccount::Dave => sr25519Public::from_raw([4u8; 32]), + TestAccount::Eve => sr25519Public::from_raw([5u8; 32]), + TestAccount::PrecompileAddress => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), + _ => sr25519Public::from_raw([0u8; 32]), + } + } +} + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Balances: pallet_balances, + Evm: pallet_evm, + Timestamp: pallet_timestamp, + Assets: pallet_assets, + } +); + +parameter_types! { + pub const SS58Prefix: u8 = 42; + pub static ExistentialDeposit: Balance = 1; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type SS58Prefix = (); + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type RuntimeCall = RuntimeCall; + type Hash = sp_core::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = (); + type DbWeight = (); + type BlockLength = (); + type BlockWeights = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_balances::Config for Runtime { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = (); + type FreezeIdentifier = (); + type MaxFreezes = (); +} + +pub type Precompiles = + PrecompileSetBuilder, AssetsPrecompile>,)>; + +pub type PCall = AssetsPrecompileCall; + +pub struct EnsureAddressAlways; +impl EnsureAddressOrigin for EnsureAddressAlways { + type Success = (); + + fn try_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } + + fn ensure_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } +} + +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub BlockGasLimit: U256 = U256::from(u64::MAX); + pub PrecompilesValue: Precompiles = Precompiles::new(); + pub const WeightPerGas: Weight = Weight::from_parts(1, 0); + pub GasLimitPovSizeRatio: u64 = { + let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); + block_gas_limit.saturating_div(MAX_POV_SIZE) + }; + pub SuicideQuickClearLimit: u32 = 0; + +} +impl pallet_evm::Config for Runtime { + type FeeCalculator = (); + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type CallOrigin = EnsureAddressAlways; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = TestAccount; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type Runner = pallet_evm::runner::stack::Runner; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = (); + type OnChargeTransaction = (); + type BlockGasLimit = BlockGasLimit; + type BlockHashMapping = SubstrateBlockHashMapping; + type FindAuthor = (); + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = pallet_evm::weights::SubstrateWeight; +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl tangle_primitives::NextAssetId for Runtime { + fn next_asset_id() -> Option { + None + } +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = u64; + type AssetId = AssetId; + type AssetIdParameter = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; +} + +/// Build test externalities, prepopulated with data for testing democracy precompiles +#[derive(Default)] +pub(crate) struct ExtBuilder { + /// Endowed accounts with balances + balances: Vec<(AccountId, Balance)>, +} + +impl ExtBuilder { + /// Build the test externalities for use in tests + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self + .balances + .iter() + .chain( + [ + (TestAccount::Alex.into(), 1_000_000), + (TestAccount::Bob.into(), 1_000_000), + (TestAccount::Charlie.into(), 1_000_000), + ] + .iter(), + ) + .cloned() + .collect(), + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + System::set_block_number(1); + }); + ext + } +} diff --git a/precompiles/oracle/src/tests.rs b/precompiles/oracle/src/tests.rs new file mode 100644 index 00000000..a1269c0c --- /dev/null +++ b/precompiles/oracle/src/tests.rs @@ -0,0 +1,185 @@ +use crate::{mock::*, U256}; +use frame_support::traits::fungibles::Inspect; +use precompile_utils::testing::*; +use sp_core::H160; + +#[test] +fn test_selector_less_than_four_bytes_reverts() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test(Alice, Precompile1, vec![1u8, 2, 3]) + .execute_reverts(|output| output == b"Tried to read selector out of bounds"); + }); +} + +#[test] +fn test_unimplemented_selector_reverts() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test(Alice, Precompile1, vec![1u8, 2, 3, 4]) + .execute_reverts(|output| output == b"Unknown selector"); + }); +} + +#[test] +fn test_create_asset() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::create { + id: U256::from(1), + admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + min_balance: U256::from(1), + }, + ) + .execute_returns(()); + + // Verify asset was created + assert!(Assets::asset_exists(1)); + }); +} + +#[test] +fn test_mint_asset() { + ExtBuilder::default().build().execute_with(|| { + // First create the asset + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::create { + id: U256::from(1), + admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + min_balance: U256::from(1), + }, + ) + .execute_returns(()); + + // Then mint some tokens + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::mint { + id: U256::from(1), + beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + amount: U256::from(100), + }, + ) + .execute_returns(()); + }); +} + +#[test] +fn test_transfer_asset() { + ExtBuilder::default().build().execute_with(|| { + let admin = sp_core::sr25519::Public::from(TestAccount::Alex); + let to = sp_core::sr25519::Public::from(TestAccount::Bob); + + // Create asset + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::create { + id: U256::from(1), + admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + min_balance: U256::from(1), + }, + ) + .execute_returns(()); + + // Mint tokens to sender + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::mint { + id: U256::from(1), + beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + amount: U256::from(100), + }, + ) + .execute_returns(()); + + // Transfer tokens + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::transfer { + id: U256::from(1), + target: precompile_utils::prelude::Address(H160::repeat_byte(0x02)), + amount: U256::from(50), + }, + ) + .execute_returns(()); + + // Verify balances + assert_eq!(Assets::balance(1, admin), 50); + assert_eq!(Assets::balance(1, to), 50); + }); +} + +#[test] +fn test_start_destroy() { + ExtBuilder::default().build().execute_with(|| { + // Create asset + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::create { + id: U256::from(1), + admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + min_balance: U256::from(1), + }, + ) + .execute_returns(()); + + // Start destroy + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::start_destroy { id: U256::from(1) }, + ) + .execute_returns(()); + + // Verify asset is being destroyed + assert!(Assets::asset_exists(1)); // Still exists but in "destroying" state + }); +} + +#[test] +fn test_mint_insufficient_permissions() { + ExtBuilder::default().build().execute_with(|| { + // Create asset + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::create { + id: U256::from(1), + admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + min_balance: U256::from(1), + }, + ) + .execute_returns(()); + + // Try to mint without permission + PrecompilesValue::get() + .prepare_test( + TestAccount::Bob, + H160::from_low_u64_be(1), + PCall::mint { + id: U256::from(1), + beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), + amount: U256::from(100), + }, + ) + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 4, error: [2, 0, 0, 0], message: Some(\"NoPermission\") })"); + }); +} From c9754bbe6b282790cddf44832e48ec9bbe762b4a Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:06:32 +0530 Subject: [PATCH 33/63] cleanup mock --- Cargo.lock | 64 +++- Cargo.toml | 2 + pallets/oracle/Cargo.toml | 2 +- pallets/oracle/runtime-api/Cargo.toml | 4 +- pallets/oracle/src/weights.rs | 6 +- precompiles/oracle/Cargo.toml | 2 + precompiles/oracle/src/lib.rs | 146 +++++--- precompiles/oracle/src/mock.rs | 320 +++++++----------- precompiles/oracle/src/tests.rs | 204 ++--------- .../traits/{oracle.rs => data_provider.rs} | 0 primitives/src/traits/mod.rs | 4 +- 11 files changed, 302 insertions(+), 452 deletions(-) rename primitives/src/traits/{oracle.rs => data_provider.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 27f1a76a..573de8bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7230,24 +7230,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "orml-oracle" -version = "1.1.0" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "tangle-primitives", -] - [[package]] name = "overload" version = "0.1.1" @@ -7810,6 +7792,34 @@ dependencies = [ "tangle-primitives", ] +[[package]] +name = "pallet-evm-precompile-oracle" +version = "0.1.0" +dependencies = [ + "derive_more 1.0.0", + "fp-evm", + "frame-support", + "frame-system", + "hex-literal 0.4.1", + "libsecp256k1", + "pallet-assets", + "pallet-balances", + "pallet-evm", + "pallet-oracle", + "pallet-timestamp", + "parity-scale-codec", + "paste", + "precompile-utils", + "scale-info", + "serde", + "sha3", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "tangle-primitives", +] + [[package]] name = "pallet-evm-precompile-preimage" version = "0.1.0" @@ -8434,6 +8444,24 @@ dependencies = [ "sp-staking", ] +[[package]] +name = "pallet-oracle" +version = "1.1.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "tangle-primitives", +] + [[package]] name = "pallet-preimage" version = "37.0.0" diff --git a/Cargo.toml b/Cargo.toml index bfde2948..4442ad47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ members = [ "precompiles/pallet-democracy", "precompiles/batch", "precompiles/call-permit", + "precompiles/oracle", "precompiles/proxy", "precompiles/preimage", "precompiles/balances-erc20", @@ -123,6 +124,7 @@ pallet-services-rpc-runtime-api = { path = "pallets/services/rpc/runtime-api", d pallet-services-rpc = { path = "pallets/services/rpc" } pallet-multi-asset-delegation = { path = "pallets/multi-asset-delegation", default-features = false } pallet-tangle-lst-benchmarking = { path = "pallets/tangle-lst/benchmarking", default-features = false } +pallet-oracle = { path = "pallets/oracle", default-features = false } k256 = { version = "0.13.3", default-features = false } p256 = { version = "0.13.2", default-features = false } diff --git a/pallets/oracle/Cargo.toml b/pallets/oracle/Cargo.toml index e0047b86..90ef5145 100644 --- a/pallets/oracle/Cargo.toml +++ b/pallets/oracle/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "orml-oracle" +name = "pallet-oracle" description = "Oracle module that makes off-chain data available on-chain." repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/oracle" license = "Apache-2.0" diff --git a/pallets/oracle/runtime-api/Cargo.toml b/pallets/oracle/runtime-api/Cargo.toml index db12b5d4..bfe50420 100644 --- a/pallets/oracle/runtime-api/Cargo.toml +++ b/pallets/oracle/runtime-api/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "orml-oracle-runtime-api" +name = "pallet-oracle-runtime-api" version = "1.1.0" authors = ["Laminar Developers "] edition = "2021" license = "Apache-2.0" -description = "Runtime API module for orml-oracle." +description = "Runtime API module for pallet-oracle." repository = "https://github.com/open-web3-stack/open-runtime-module-library" [dependencies] diff --git a/pallets/oracle/src/weights.rs b/pallets/oracle/src/weights.rs index 32bf2879..9f6cfd39 100644 --- a/pallets/oracle/src/weights.rs +++ b/pallets/oracle/src/weights.rs @@ -1,4 +1,4 @@ -//! Autogenerated weights for orml_oracle +//! Autogenerated weights for pallet_oracle //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 //! DATE: 2021-05-04, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] @@ -10,7 +10,7 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=orml_oracle +// --pallet=pallet_oracle // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -28,7 +28,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for orml_oracle. +/// Weight functions needed for pallet_oracle. pub trait WeightInfo { fn feed_values(c: u32, ) -> Weight; fn on_finalize() -> Weight; diff --git a/precompiles/oracle/Cargo.toml b/precompiles/oracle/Cargo.toml index 043315ad..a681b2b5 100644 --- a/precompiles/oracle/Cargo.toml +++ b/precompiles/oracle/Cargo.toml @@ -16,6 +16,7 @@ frame-support = { workspace = true } frame-system = { workspace = true } pallet-assets = { workspace = true } pallet-balances = { workspace = true } +pallet-oracle = { workspace = true } pallet-timestamp = { workspace = true } parity-scale-codec = { workspace = true, features = [ "max-encoded-len" ] } scale-info = { workspace = true, features = [ "derive" ] } @@ -52,6 +53,7 @@ std = [ "pallet-assets/std", "pallet-balances/std", "pallet-evm/std", + "pallet-oracle/std", "pallet-timestamp/std", "parity-scale-codec/std", "precompile-utils/std", diff --git a/precompiles/oracle/src/lib.rs b/precompiles/oracle/src/lib.rs index 18fae6fa..246c9df7 100644 --- a/precompiles/oracle/src/lib.rs +++ b/precompiles/oracle/src/lib.rs @@ -16,72 +16,110 @@ #![cfg_attr(not(feature = "std"), no_std)] -use fp_evm::PrecompileHandle; +use core::str::FromStr; +use fp_evm::{PrecompileHandle, PrecompileOutput}; use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - pallet_prelude::BoundedVec, - traits::Currency, + dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, + traits::Get, }; use pallet_evm::AddressMapping; -use parity_scale_codec::Codec; -use precompile_utils::prelude::*; -use sp_core::{H160, U256}; -use sp_std::{marker::PhantomData, vec::Vec}; +use pallet_oracle::TimestampedValue; +use precompile_utils::{ + prelude::*, + solidity::{codec::Writer, modifier::FunctionModifier, revert::revert}, +}; +use sp_core::U256; +use sp_std::{marker::PhantomData, prelude::*}; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +#[precompile_utils::generate_function_selector] +#[derive(Debug, PartialEq)] +pub enum Action { + GetValue = "getValue(uint256)", + FeedValues = "feedValues(uint256[],uint256[])", +} + +/// A precompile to wrap the functionality from pallet_oracle. pub struct OraclePrecompile(PhantomData); -#[precompile_utils::precompile] impl OraclePrecompile where - Runtime: pallet_oracle::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, - Runtime::OracleKey: TryFrom + Into, - Runtime::OracleValue: TryFrom + Into, + Runtime: pallet_oracle::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, { - #[precompile::public("feedValues(uint256[],uint256[])")] - fn feed_values( - handle: &mut impl PrecompileHandle, - keys: Vec, - values: Vec, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - // Check that keys and values have the same length - ensure!(keys.len() == values.len(), revert("Keys and values must have the same length")); - - // Convert keys and values to the required types - let mut oracle_values = Vec::with_capacity(keys.len()); - for (key, value) in keys.into_iter().zip(values.into_iter()) { - let oracle_key = key - .try_into() - .map_err(|_| RevertReason::value_is_too_large("oracle key"))?; - let oracle_value = value - .try_into() - .map_err(|_| RevertReason::value_is_too_large("oracle value"))?; - oracle_values.push((oracle_key, oracle_value)); - } - - // Convert to BoundedVec - let bounded_values: BoundedVec<_, Runtime::MaxFeedValues> = oracle_values - .try_into() - .map_err(|_| revert("Too many values"))?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_oracle::Call::::feed_values { values: bounded_values }, - )?; - - Ok(()) - } + pub fn new() -> Self { + Self(PhantomData) + } + + fn get_value(handle: &mut impl PrecompileHandle, key: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let key: u32 = key.try_into().map_err(|_| revert("Invalid key"))?; + + let value = >::get(&key); + + let mut writer = Writer::new_with_selector(Action::GetValue); + + if let Some(TimestampedValue { value, timestamp }) = value { + writer.write(U256::from(value)); + writer.write(U256::from(timestamp)); + } else { + writer.write(U256::zero()); + writer.write(U256::zero()); + } + + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: writer.build() }) + } + + fn feed_values( + handle: &mut impl PrecompileHandle, + keys: Vec, + values: Vec, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + + let caller = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let mut feed_values = Vec::new(); + for (key, value) in keys.iter().zip(values.iter()) { + let key: u32 = key.try_into().map_err(|_| revert("Invalid key"))?; + let value: u64 = value.try_into().map_err(|_| revert("Invalid value"))?; + feed_values.push((key, value)); + } + + let bounded_feed_values = feed_values.try_into().map_err(|_| revert("Too many values"))?; + + let call = pallet_oracle::Call::::feed_values { feed_values: bounded_feed_values }; + + RuntimeHelper::::try_dispatch(handle, Some(caller).into(), call)?; + + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: vec![] }) + } +} + +impl Precompile for OraclePrecompile +where + Runtime: pallet_oracle::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, +{ + fn execute(handle: &mut impl PrecompileHandle) -> EvmResult { + let selector = handle.read_selector()?; + + match selector { + Action::GetValue => Self::get_value(handle, handle.read_u256()?), + Action::FeedValues => { + let keys = handle.read_u256_array()?; + let values = handle.read_u256_array()?; + Self::feed_values(handle, keys, values) + }, + } + } } diff --git a/precompiles/oracle/src/mock.rs b/precompiles/oracle/src/mock.rs index 799fdee7..7640e696 100644 --- a/precompiles/oracle/src/mock.rs +++ b/precompiles/oracle/src/mock.rs @@ -16,35 +16,49 @@ //! Test utilities use super::*; -use crate::{AssetsPrecompile, AssetsPrecompileCall}; use frame_support::{ construct_runtime, derive_impl, parameter_types, - traits::{AsEnsureOriginWithArg, ConstU64}, + traits::{ConstU32, ConstU64, SortedMembers}, weights::Weight, + BoundedVec, }; use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, SubstrateBlockHashMapping}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; +use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; -use sp_core::{ - self, - sr25519::{Public as sr25519Public, Signature}, - ConstU32, H160, U256, -}; +use sp_core::{H160, U256}; use sp_runtime::{ - traits::{IdentifyAccount, Verify}, + traits::{IdentifyAccount, IdentityLookup}, AccountId32, BuildStorage, }; +use std::fmt; -pub type AccountId = <::Signer as IdentifyAccount>::AccountId; -pub type Balance = u64; +pub const ALICE: H160 = H160::repeat_byte(0x01); +pub const BOB: H160 = H160::repeat_byte(0x02); -type Block = frame_system::mocking::MockBlock; -type AssetId = u32; +pub type AccountId = TestAccount; +pub type Balance = u64; +pub type AssetId = u32; +pub type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +pub type Block = frame_system::mocking::MockBlock; -const PRECOMPILE_ADDRESS_BYTES: [u8; 32] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -]; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; + pub const ExistentialDeposit: u64 = 1; + pub const MinimumPeriod: u64 = 5; + pub const MaxFeedValues: u32 = 1000; + pub const MaxHasDispatchedSize: u32 = 100; + pub const MaxFreezes: u32 = 50; + pub BlockGasLimit: U256 = U256::from(u64::MAX); + pub const WeightPerGas: Weight = Weight::from_parts(1, 0); + pub GasLimitPovSizeRatio: u64 = { + let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); + block_gas_limit.saturating_div(5 * 1024 * 1024) + }; + pub const SuicideQuickClearLimit: u32 = 0; + pub const RootOperatorAccountId: AccountId = TestAccount::Alice; +} #[derive( Eq, @@ -56,161 +70,103 @@ const PRECOMPILE_ADDRESS_BYTES: [u8; 32] = [ Decode, Debug, MaxEncodedLen, + TypeInfo, + Copy, Serialize, Deserialize, - derive_more::Display, - scale_info::TypeInfo, )] pub enum TestAccount { Empty, - Alex, + Alice, Bob, - Dave, Charlie, - Eve, - PrecompileAddress, -} - -impl Default for TestAccount { - fn default() -> Self { - Self::Empty - } + Dave, } -// needed for associated type in pallet_evm -impl AddressMapping for TestAccount { - fn into_account_id(h160_account: H160) -> AccountId32 { - match h160_account { - a if a == H160::repeat_byte(0x01) => TestAccount::Alex.into(), - a if a == H160::repeat_byte(0x02) => TestAccount::Bob.into(), - a if a == H160::repeat_byte(0x03) => TestAccount::Charlie.into(), - a if a == H160::repeat_byte(0x04) => TestAccount::Dave.into(), - a if a == H160::repeat_byte(0x05) => TestAccount::Eve.into(), - a if a == H160::from_low_u64_be(6) => TestAccount::PrecompileAddress.into(), - _ => TestAccount::Empty.into(), +impl fmt::Display for TestAccount { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TestAccount::Empty => write!(f, "Empty"), + TestAccount::Alice => write!(f, "Alice"), + TestAccount::Bob => write!(f, "Bob"), + TestAccount::Charlie => write!(f, "Charlie"), + TestAccount::Dave => write!(f, "Dave"), } } } -impl AddressMapping for TestAccount { - fn into_account_id(h160_account: H160) -> sp_core::sr25519::Public { - match h160_account { - a if a == H160::repeat_byte(0x01) => sr25519Public::from_raw([1u8; 32]), - a if a == H160::repeat_byte(0x02) => sr25519Public::from_raw([2u8; 32]), - a if a == H160::repeat_byte(0x03) => sr25519Public::from_raw([3u8; 32]), - a if a == H160::repeat_byte(0x04) => sr25519Public::from_raw([4u8; 32]), - a if a == H160::repeat_byte(0x05) => sr25519Public::from_raw([5u8; 32]), - a if a == H160::from_low_u64_be(6) => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), - _ => sr25519Public::from_raw([0u8; 32]), - } +impl Default for TestAccount { + fn default() -> Self { + Self::Empty } } -impl From for H160 { - fn from(x: TestAccount) -> H160 { - match x { - TestAccount::Alex => H160::repeat_byte(0x01), - TestAccount::Bob => H160::repeat_byte(0x02), - TestAccount::Charlie => H160::repeat_byte(0x03), - TestAccount::Dave => H160::repeat_byte(0x04), - TestAccount::Eve => H160::repeat_byte(0x05), - TestAccount::PrecompileAddress => H160::from_low_u64_be(6), - _ => Default::default(), - } +impl IdentifyAccount for TestAccount { + type AccountId = AccountId; + + fn into_account(self) -> Self::AccountId { + self } } -impl From for AccountId32 { - fn from(x: TestAccount) -> Self { - match x { - TestAccount::Alex => AccountId32::from([1u8; 32]), - TestAccount::Bob => AccountId32::from([2u8; 32]), - TestAccount::Charlie => AccountId32::from([3u8; 32]), - TestAccount::Dave => AccountId32::from([4u8; 32]), - TestAccount::Eve => AccountId32::from([5u8; 32]), - TestAccount::PrecompileAddress => AccountId32::from(PRECOMPILE_ADDRESS_BYTES), - _ => AccountId32::from([0u8; 32]), +impl AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> AccountId32 { + match h160_account { + a if a == ALICE => AccountId32::new([0u8; 32]), + a if a == BOB => AccountId32::new([1u8; 32]), + _ => AccountId32::new([0u8; 32]), } } } -impl From for sp_core::sr25519::Public { - fn from(x: TestAccount) -> Self { - match x { - TestAccount::Alex => sr25519Public::from_raw([1u8; 32]), - TestAccount::Bob => sr25519Public::from_raw([2u8; 32]), - TestAccount::Charlie => sr25519Public::from_raw([3u8; 32]), - TestAccount::Dave => sr25519Public::from_raw([4u8; 32]), - TestAccount::Eve => sr25519Public::from_raw([5u8; 32]), - TestAccount::PrecompileAddress => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), - _ => sr25519Public::from_raw([0u8; 32]), +impl pallet_evm::AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> TestAccount { + match h160_account { + a if a == ALICE => TestAccount::Alice, + a if a == BOB => TestAccount::Bob, + _ => TestAccount::Empty, } } } -construct_runtime!( - pub enum Runtime - { - System: frame_system, - Balances: pallet_balances, - Evm: pallet_evm, - Timestamp: pallet_timestamp, - Assets: pallet_assets, +#[derive(Debug, Clone, Copy)] +pub struct MockMembers; +impl SortedMembers for MockMembers { + fn sorted_members() -> Vec { + vec![TestAccount::Alice] } -); - -parameter_types! { - pub const SS58Prefix: u8 = 42; - pub static ExistentialDeposit: Balance = 1; } #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { - type SS58Prefix = (); - type BaseCallFilter = frame_support::traits::Everything; - type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; - type RuntimeCall = RuntimeCall; - type Hash = sp_core::H256; - type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; - type Lookup = sp_runtime::traits::IdentityLookup; + type Lookup = IdentityLookup; type Block = Block; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = (); - type DbWeight = (); - type BlockLength = (); - type BlockWeights = (); - type Version = (); - type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_balances::Config for Runtime { - type MaxReserves = (); - type ReserveIdentifier = [u8; 4]; - type MaxLocks = (); - type Balance = Balance; type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type Balance = Balance; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; - type WeightInfo = (); + type ReserveIdentifier = [u8; 8]; type RuntimeHoldReason = RuntimeHoldReason; - type RuntimeFreezeReason = (); type FreezeIdentifier = (); - type MaxFreezes = (); + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<50>; + type MaxFreezes = MaxFreezes; + type RuntimeFreezeReason = RuntimeFreezeReason; } -pub type Precompiles = - PrecompileSetBuilder, AssetsPrecompile>,)>; - -pub type PCall = AssetsPrecompileCall; +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = pallet_timestamp::weights::SubstrateWeight; +} pub struct EnsureAddressAlways; impl EnsureAddressOrigin for EnsureAddressAlways { @@ -231,19 +187,6 @@ impl EnsureAddressOrigin for EnsureAddressAlways { } } -const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; - -parameter_types! { - pub BlockGasLimit: U256 = U256::from(u64::MAX); - pub PrecompilesValue: Precompiles = Precompiles::new(); - pub const WeightPerGas: Weight = Weight::from_parts(1, 0); - pub GasLimitPovSizeRatio: u64 = { - let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); - block_gas_limit.saturating_div(MAX_POV_SIZE) - }; - pub SuicideQuickClearLimit: u32 = 0; - -} impl pallet_evm::Config for Runtime { type FeeCalculator = (); type GasWeightMapping = pallet_evm::FixedGasWeightMapping; @@ -253,94 +196,65 @@ impl pallet_evm::Config for Runtime { type AddressMapping = TestAccount; type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = Precompiles; - type PrecompilesValue = PrecompilesValue; + type PrecompilesType = (); + type PrecompilesValue = (); type ChainId = (); - type OnChargeTransaction = (); type BlockGasLimit = BlockGasLimit; type BlockHashMapping = SubstrateBlockHashMapping; - type FindAuthor = (); + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = (); type OnCreate = (); - type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = (); type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type SuicideQuickClearLimit = SuicideQuickClearLimit; type Timestamp = Timestamp; type WeightInfo = pallet_evm::weights::SubstrateWeight; } -parameter_types! { - pub const MinimumPeriod: u64 = 5; -} -impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; +impl pallet_oracle::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Time = Timestamp; + type Members = MockMembers; + type MaxFeedValues = MaxFeedValues; type WeightInfo = (); + type OnNewData = (); + type CombineData = pallet_oracle::DefaultCombineData, ConstU64<600>>; + type OracleKey = u32; + type OracleValue = u64; + type RootOperatorAccountId = RootOperatorAccountId; + type MaxHasDispatchedSize = MaxHasDispatchedSize; } -impl tangle_primitives::NextAssetId for Runtime { - fn next_asset_id() -> Option { - None +construct_runtime!( + pub enum Runtime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + EVM: pallet_evm, + Oracle: pallet_oracle, } -} - -impl pallet_assets::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = u64; - type AssetId = AssetId; - type AssetIdParameter = u32; - type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = ConstU64<1>; - type AssetAccountDeposit = ConstU64<10>; - type MetadataDepositBase = ConstU64<1>; - type MetadataDepositPerByte = ConstU64<1>; - type ApprovalDeposit = ConstU64<1>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type WeightInfo = (); - type CallbackHandle = (); - type Extra = (); - type RemoveItemsLimit = ConstU32<5>; -} +); -/// Build test externalities, prepopulated with data for testing democracy precompiles #[derive(Default)] -pub(crate) struct ExtBuilder { - /// Endowed accounts with balances - balances: Vec<(AccountId, Balance)>, -} +pub struct ExtBuilder; impl ExtBuilder { - /// Build the test externalities for use in tests - pub(crate) fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { - balances: self - .balances - .iter() - .chain( - [ - (TestAccount::Alex.into(), 1_000_000), - (TestAccount::Bob.into(), 1_000_000), - (TestAccount::Charlie.into(), 1_000_000), - ] - .iter(), - ) - .cloned() - .collect(), + balances: vec![(TestAccount::Alice, 1_000_000_000_000)], } .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); + .unwrap(); let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| { - System::set_block_number(1); - }); + ext.execute_with(|| System::set_block_number(1)); ext } } diff --git a/precompiles/oracle/src/tests.rs b/precompiles/oracle/src/tests.rs index a1269c0c..9795e8cd 100644 --- a/precompiles/oracle/src/tests.rs +++ b/precompiles/oracle/src/tests.rs @@ -1,185 +1,51 @@ -use crate::{mock::*, U256}; -use frame_support::traits::fungibles::Inspect; -use precompile_utils::testing::*; -use sp_core::H160; - -#[test] -fn test_selector_less_than_four_bytes_reverts() { - ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test(Alice, Precompile1, vec![1u8, 2, 3]) - .execute_reverts(|output| output == b"Tried to read selector out of bounds"); - }); +use super::*; +use crate::{mock::*, OraclePrecompile, OraclePrecompileCall}; +use frame_support::{assert_ok, BoundedVec}; +use precompile_utils::{ + precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}, + testing::PrecompileTesterExt, +}; +use sp_core::{H160, U256}; + +pub type PCall = OraclePrecompileCall; +pub type Precompiles = + PrecompileSetBuilder, OraclePrecompile>,)>; + +fn precompiles() -> Precompiles { + Precompiles::new() } #[test] -fn test_unimplemented_selector_reverts() { +fn feed_values_works() { ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test(Alice, Precompile1, vec![1u8, 2, 3, 4]) - .execute_reverts(|output| output == b"Unknown selector"); + // Create a bounded vector for feed values + let mut feed_values = Vec::new(); + feed_values.push((1u32, 100u64)); + feed_values.push((2u32, 200u64)); + let bounded_feed_values: BoundedVec<_, _> = feed_values.try_into().unwrap(); + + assert_ok!(Oracle::feed_values( + RuntimeOrigin::signed(TestAccount::Alice), + bounded_feed_values + )); }); } #[test] -fn test_create_asset() { +fn precompile_feed_values_works() { ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::create { - id: U256::from(1), - admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - min_balance: U256::from(1), - }, - ) - .execute_returns(()); - - // Verify asset was created - assert!(Assets::asset_exists(1)); - }); -} - -#[test] -fn test_mint_asset() { - ExtBuilder::default().build().execute_with(|| { - // First create the asset - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::create { - id: U256::from(1), - admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - min_balance: U256::from(1), - }, - ) - .execute_returns(()); + // Test data + let key1: U256 = U256::from(1u32); + let value1: U256 = U256::from(100u64); + let key2: U256 = U256::from(2u32); + let value2: U256 = U256::from(200u64); - // Then mint some tokens - PrecompilesValue::get() + precompiles() .prepare_test( - TestAccount::Alex, + TestAccount::Alice, H160::from_low_u64_be(1), - PCall::mint { - id: U256::from(1), - beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - amount: U256::from(100), - }, + PCall::feed_values { keys: vec![key1, key2], values: vec![value1, value2] }, ) .execute_returns(()); }); } - -#[test] -fn test_transfer_asset() { - ExtBuilder::default().build().execute_with(|| { - let admin = sp_core::sr25519::Public::from(TestAccount::Alex); - let to = sp_core::sr25519::Public::from(TestAccount::Bob); - - // Create asset - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::create { - id: U256::from(1), - admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - min_balance: U256::from(1), - }, - ) - .execute_returns(()); - - // Mint tokens to sender - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::mint { - id: U256::from(1), - beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - amount: U256::from(100), - }, - ) - .execute_returns(()); - - // Transfer tokens - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::transfer { - id: U256::from(1), - target: precompile_utils::prelude::Address(H160::repeat_byte(0x02)), - amount: U256::from(50), - }, - ) - .execute_returns(()); - - // Verify balances - assert_eq!(Assets::balance(1, admin), 50); - assert_eq!(Assets::balance(1, to), 50); - }); -} - -#[test] -fn test_start_destroy() { - ExtBuilder::default().build().execute_with(|| { - // Create asset - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::create { - id: U256::from(1), - admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - min_balance: U256::from(1), - }, - ) - .execute_returns(()); - - // Start destroy - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::start_destroy { id: U256::from(1) }, - ) - .execute_returns(()); - - // Verify asset is being destroyed - assert!(Assets::asset_exists(1)); // Still exists but in "destroying" state - }); -} - -#[test] -fn test_mint_insufficient_permissions() { - ExtBuilder::default().build().execute_with(|| { - // Create asset - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::create { - id: U256::from(1), - admin: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - min_balance: U256::from(1), - }, - ) - .execute_returns(()); - - // Try to mint without permission - PrecompilesValue::get() - .prepare_test( - TestAccount::Bob, - H160::from_low_u64_be(1), - PCall::mint { - id: U256::from(1), - beneficiary: precompile_utils::prelude::Address(H160::repeat_byte(0x01)), - amount: U256::from(100), - }, - ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 4, error: [2, 0, 0, 0], message: Some(\"NoPermission\") })"); - }); -} diff --git a/primitives/src/traits/oracle.rs b/primitives/src/traits/data_provider.rs similarity index 100% rename from primitives/src/traits/oracle.rs rename to primitives/src/traits/data_provider.rs diff --git a/primitives/src/traits/mod.rs b/primitives/src/traits/mod.rs index f2011b3a..fef97c98 100644 --- a/primitives/src/traits/mod.rs +++ b/primitives/src/traits/mod.rs @@ -1,9 +1,9 @@ pub mod assets; +pub mod data_provider; pub mod multi_asset_delegation; -pub mod oracle; pub mod services; pub use assets::*; +pub use data_provider::*; pub use multi_asset_delegation::*; -pub use oracle::*; pub use services::*; From fce94012eec7a46f9c4d5d91e0a62fbd357137b9 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:49:07 +0530 Subject: [PATCH 34/63] fix --- Cargo.lock | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 44e9c540..573de8bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7777,7 +7777,6 @@ dependencies = [ "pallet-staking", "pallet-timestamp", "parity-scale-codec", - "paste", "precompile-utils", "scale-info", "serde", @@ -7793,6 +7792,34 @@ dependencies = [ "tangle-primitives", ] +[[package]] +name = "pallet-evm-precompile-oracle" +version = "0.1.0" +dependencies = [ + "derive_more 1.0.0", + "fp-evm", + "frame-support", + "frame-system", + "hex-literal 0.4.1", + "libsecp256k1", + "pallet-assets", + "pallet-balances", + "pallet-evm", + "pallet-oracle", + "pallet-timestamp", + "parity-scale-codec", + "paste", + "precompile-utils", + "scale-info", + "serde", + "sha3", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "tangle-primitives", +] + [[package]] name = "pallet-evm-precompile-preimage" version = "0.1.0" From eca9612068da19c42611a44e20769e54ee5201af Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:27:47 +0530 Subject: [PATCH 35/63] updates to tests --- Cargo.lock | 28 --- Cargo.toml | 1 - client/evm-tracing/Cargo.toml | 2 - client/rpc/debug/Cargo.toml | 2 +- client/rpc/trace/Cargo.toml | 2 +- client/rpc/txpool/Cargo.toml | 2 +- evm-tracer/Cargo.toml | 2 +- pallets/claims/src/lib.rs | 3 +- pallets/oracle/src/mock.rs | 2 +- pallets/oracle/src/tests.rs | 2 +- pallets/tangle-lst/src/types/sub_pools.rs | 2 +- precompiles/assets-erc20/Cargo.toml | 2 +- precompiles/assets/Cargo.toml | 2 +- precompiles/balances-erc20/Cargo.toml | 4 +- precompiles/batch/Cargo.toml | 2 +- precompiles/call-permit/Cargo.toml | 2 +- precompiles/multi-asset-delegation/Cargo.toml | 4 +- precompiles/oracle/Cargo.toml | 2 +- precompiles/oracle/src/lib.rs | 185 ++++++++++-------- precompiles/oracle/src/tests.rs | 96 +++++---- precompiles/pallet-democracy/Cargo.toml | 4 +- precompiles/precompile-registry/Cargo.toml | 4 +- precompiles/preimage/Cargo.toml | 4 +- precompiles/proxy/Cargo.toml | 4 +- precompiles/services/Cargo.toml | 4 +- precompiles/services/src/lib.rs | 14 -- precompiles/staking/Cargo.toml | 4 +- precompiles/staking/StakingInterface.sol | 5 - precompiles/staking/src/lib.rs | 1 - precompiles/tangle-lst/Cargo.toml | 4 +- precompiles/tangle-lst/TangleLst.sol | 2 +- precompiles/tangle-lst/src/lib.rs | 2 +- precompiles/vesting/Cargo.toml | 4 +- precompiles/vesting/src/lib.rs | 2 +- primitives/ext/Cargo.toml | 2 +- primitives/src/traits/data_provider.rs | 8 +- 36 files changed, 204 insertions(+), 211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 573de8bf..6f04abbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7792,34 +7792,6 @@ dependencies = [ "tangle-primitives", ] -[[package]] -name = "pallet-evm-precompile-oracle" -version = "0.1.0" -dependencies = [ - "derive_more 1.0.0", - "fp-evm", - "frame-support", - "frame-system", - "hex-literal 0.4.1", - "libsecp256k1", - "pallet-assets", - "pallet-balances", - "pallet-evm", - "pallet-oracle", - "pallet-timestamp", - "parity-scale-codec", - "paste", - "precompile-utils", - "scale-info", - "serde", - "sha3", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "tangle-primitives", -] - [[package]] name = "pallet-evm-precompile-preimage" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 4442ad47..78abf51d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ members = [ "precompiles/pallet-democracy", "precompiles/batch", "precompiles/call-permit", - "precompiles/oracle", "precompiles/proxy", "precompiles/preimage", "precompiles/balances-erc20", diff --git a/client/evm-tracing/Cargo.toml b/client/evm-tracing/Cargo.toml index 7bcd7efd..1adc5307 100644 --- a/client/evm-tracing/Cargo.toml +++ b/client/evm-tracing/Cargo.toml @@ -11,8 +11,6 @@ ethereum-types = { workspace = true, features = [ "std" ] } hex = { workspace = true, features = [ "serde" ] } serde = { workspace = true, features = [ "derive", "std" ] } serde_json = { workspace = true } - -# Moonbeam evm-tracing-events = { workspace = true, features = [ "std" ] } rpc-primitives-debug = { workspace = true, features = [ "std" ] } diff --git a/client/rpc/debug/Cargo.toml b/client/rpc/debug/Cargo.toml index 613638bc..b2c7d643 100644 --- a/client/rpc/debug/Cargo.toml +++ b/client/rpc/debug/Cargo.toml @@ -12,7 +12,7 @@ hex-literal = { workspace = true } jsonrpsee = { workspace = true, features = ["macros", "server"] } tokio = { workspace = true, features = ["sync", "time"] } -# Moonbeam + client-evm-tracing = { workspace = true } rpc-core-debug = { workspace = true } rpc-core-types = { workspace = true } diff --git a/client/rpc/trace/Cargo.toml b/client/rpc/trace/Cargo.toml index 336ce667..3e1adb2c 100644 --- a/client/rpc/trace/Cargo.toml +++ b/client/rpc/trace/Cargo.toml @@ -15,7 +15,7 @@ substrate-prometheus-endpoint = { workspace = true } tokio = { workspace = true, features = ["sync", "time"] } tracing = { workspace = true } -# Moonbeam + client-evm-tracing = { workspace = true } rpc-core-trace = { workspace = true } rpc-core-types = { workspace = true } diff --git a/client/rpc/txpool/Cargo.toml b/client/rpc/txpool/Cargo.toml index 7e7fd2f7..57cbbda6 100644 --- a/client/rpc/txpool/Cargo.toml +++ b/client/rpc/txpool/Cargo.toml @@ -11,7 +11,7 @@ jsonrpsee = { workspace = true, features = ["macros", "server"] } serde = { workspace = true, features = ["derive"] } sha3 = { workspace = true } -# Moonbeam + rpc-core-txpool = { workspace = true } rpc-primitives-txpool = { workspace = true, features = ["std"] } diff --git a/evm-tracer/Cargo.toml b/evm-tracer/Cargo.toml index 76e815f0..e70430ad 100644 --- a/evm-tracer/Cargo.toml +++ b/evm-tracer/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" repository = { workspace = true } [dependencies] -# Moonbeam + evm-tracing-events = { workspace = true, features = ["evm-tracing"] } primitives-ext = { workspace = true } diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 161de15d..b94ac8e0 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -48,6 +48,7 @@ use sp_io::{ crypto::{secp256k1_ecdsa_recover, sr25519_verify}, hashing::keccak_256, }; +use sp_runtime::Saturating; use sp_runtime::{ traits::{CheckedSub, Zero}, transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, @@ -334,7 +335,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - >::mutate(|t| *t += value); + >::mutate(|t| *t = t.saturating_add(value)); >::insert(who.clone(), value); if let Some(vs) = vesting_schedule { >::insert(who.clone(), vs); diff --git a/pallets/oracle/src/mock.rs b/pallets/oracle/src/mock.rs index d289439f..6c62b54d 100644 --- a/pallets/oracle/src/mock.rs +++ b/pallets/oracle/src/mock.rs @@ -26,7 +26,7 @@ impl frame_system::Config for Test { } thread_local! { - static TIME: RefCell = RefCell::new(0); + static TIME: RefCell = const { RefCell::new(0) }; static MEMBERS: RefCell> = RefCell::new(vec![1, 2, 3]); } diff --git a/pallets/oracle/src/tests.rs b/pallets/oracle/src/tests.rs index 69b7f62f..5934bc6c 100644 --- a/pallets/oracle/src/tests.rs +++ b/pallets/oracle/src/tests.rs @@ -291,7 +291,7 @@ fn should_clear_data_for_removed_members() { ModuleOracle::change_members_sorted(&[4], &[1], &[2, 3, 4]); - assert_eq!(ModuleOracle::raw_values(&1, 50), None); + assert_eq!(ModuleOracle::raw_values(1, 50), None); }); } diff --git a/pallets/tangle-lst/src/types/sub_pools.rs b/pallets/tangle-lst/src/types/sub_pools.rs index c0f5852b..855fe0e7 100644 --- a/pallets/tangle-lst/src/types/sub_pools.rs +++ b/pallets/tangle-lst/src/types/sub_pools.rs @@ -107,7 +107,7 @@ impl RewardPool { // Split the `current_payout_balance` into claimable rewards and claimable commission // according to the current commission rate. - let new_pending_commission = commission * current_payout_balance; + let new_pending_commission = commission.mul_floor(current_payout_balance); let new_pending_rewards = current_payout_balance.saturating_sub(new_pending_commission); // * accuracy notes regarding the multiplication in `checked_from_rational`: diff --git a/precompiles/assets-erc20/Cargo.toml b/precompiles/assets-erc20/Cargo.toml index 94421e61..2982da01 100644 --- a/precompiles/assets-erc20/Cargo.toml +++ b/precompiles/assets-erc20/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" [dependencies] paste = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate diff --git a/precompiles/assets/Cargo.toml b/precompiles/assets/Cargo.toml index 1ebb54be..aba24fef 100644 --- a/precompiles/assets/Cargo.toml +++ b/precompiles/assets/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" [dependencies] paste = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate diff --git a/precompiles/balances-erc20/Cargo.toml b/precompiles/balances-erc20/Cargo.toml index b6cd1bb1..489bcac3 100644 --- a/precompiles/balances-erc20/Cargo.toml +++ b/precompiles/balances-erc20/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" [dependencies] paste = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -34,7 +34,7 @@ libsecp256k1 = { workspace = true } serde = { workspace = true } sha3 = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = [ "std", "testing" ] } pallet-timestamp = { workspace = true, features = [ "std" ] } diff --git a/precompiles/batch/Cargo.toml b/precompiles/batch/Cargo.toml index 52904ef5..ec811c43 100644 --- a/precompiles/batch/Cargo.toml +++ b/precompiles/batch/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to batch multiple calls." [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate diff --git a/precompiles/call-permit/Cargo.toml b/precompiles/call-permit/Cargo.toml index f1c37b71..19bde6c0 100644 --- a/precompiles/call-permit/Cargo.toml +++ b/precompiles/call-permit/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to dispatch a call with a ERC712 permit." [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate diff --git a/precompiles/multi-asset-delegation/Cargo.toml b/precompiles/multi-asset-delegation/Cargo.toml index b6b38178..5ad05c85 100644 --- a/precompiles/multi-asset-delegation/Cargo.toml +++ b/precompiles/multi-asset-delegation/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to make pallet-multi-asset-delegation calls encoding [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -40,7 +40,7 @@ serde_json = { workspace = true } smallvec = { workspace = true } sp-keystore = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/oracle/Cargo.toml b/precompiles/oracle/Cargo.toml index a681b2b5..51409686 100644 --- a/precompiles/oracle/Cargo.toml +++ b/precompiles/oracle/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" [dependencies] paste = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate diff --git a/precompiles/oracle/src/lib.rs b/precompiles/oracle/src/lib.rs index 246c9df7..aeafcc81 100644 --- a/precompiles/oracle/src/lib.rs +++ b/precompiles/oracle/src/lib.rs @@ -16,19 +16,19 @@ #![cfg_attr(not(feature = "std"), no_std)] -use core::str::FromStr; -use fp_evm::{PrecompileHandle, PrecompileOutput}; -use frame_support::{ - dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, - traits::Get, +use fp_evm::{ + ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure, PrecompileHandle, + PrecompileOutput, }; +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use pallet_evm::AddressMapping; use pallet_oracle::TimestampedValue; use precompile_utils::{ - prelude::*, - solidity::{codec::Writer, modifier::FunctionModifier, revert::revert}, + prelude::*, + solidity::{codec::Writer, revert::revert}, }; use sp_core::U256; +use sp_runtime::traits::{Dispatchable, UniqueSaturatedInto}; use sp_std::{marker::PhantomData, prelude::*}; #[cfg(test)] @@ -36,11 +36,13 @@ mod mock; #[cfg(test)] mod tests; -#[precompile_utils::generate_function_selector] -#[derive(Debug, PartialEq)] -pub enum Action { - GetValue = "getValue(uint256)", - FeedValues = "feedValues(uint256[],uint256[])", +/// The selector values for each function in the precompile. +/// These are calculated using the first 4 bytes of the Keccak hash of the function signature. +pub mod selectors { + /// Selector for the getValue(uint256) function + pub const GET_VALUE: u32 = 0x20965255; + /// Selector for the feedValues(uint256[],uint256[]) function + pub const FEED_VALUES: u32 = 0x983b2d56; } /// A precompile to wrap the functionality from pallet_oracle. @@ -48,78 +50,99 @@ pub struct OraclePrecompile(PhantomData); impl OraclePrecompile where - Runtime: pallet_oracle::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, + Runtime: pallet_oracle::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, { - pub fn new() -> Self { - Self(PhantomData) - } - - fn get_value(handle: &mut impl PrecompileHandle, key: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let key: u32 = key.try_into().map_err(|_| revert("Invalid key"))?; - - let value = >::get(&key); - - let mut writer = Writer::new_with_selector(Action::GetValue); - - if let Some(TimestampedValue { value, timestamp }) = value { - writer.write(U256::from(value)); - writer.write(U256::from(timestamp)); - } else { - writer.write(U256::zero()); - writer.write(U256::zero()); - } - - Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: writer.build() }) - } - - fn feed_values( - handle: &mut impl PrecompileHandle, - keys: Vec, - values: Vec, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - - let caller = Runtime::AddressMapping::into_account_id(handle.context().caller); - - let mut feed_values = Vec::new(); - for (key, value) in keys.iter().zip(values.iter()) { - let key: u32 = key.try_into().map_err(|_| revert("Invalid key"))?; - let value: u64 = value.try_into().map_err(|_| revert("Invalid value"))?; - feed_values.push((key, value)); - } - - let bounded_feed_values = feed_values.try_into().map_err(|_| revert("Too many values"))?; - - let call = pallet_oracle::Call::::feed_values { feed_values: bounded_feed_values }; - - RuntimeHelper::::try_dispatch(handle, Some(caller).into(), call)?; - - Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: vec![] }) - } + pub fn new() -> Self { + Self(PhantomData) + } + + fn get_value_impl(input: &[u8]) -> Result<(ExitSucceed, Vec), PrecompileFailure> { + let key = U256::from_big_endian(&input[4..]); + let key: u32 = key.low_u32(); + let value = >::get(&key); + + let mut writer = Writer::default(); + + if let Some(TimestampedValue { value, timestamp }) = value { + let mut writer = writer.write(U256::from(value)); + let timestamp_u64: u64 = UniqueSaturatedInto::::unique_saturated_into(timestamp); + writer = writer.write(U256::from(timestamp_u64)); + Ok((ExitSucceed::Returned, writer.build())) + } else { + let mut writer = writer.write(U256::zero()); + writer = writer.write(U256::zero()); + Ok((ExitSucceed::Returned, writer.build())) + } + } + + fn feed_values_impl(input: &[u8]) -> Result<(ExitSucceed, Vec), PrecompileFailure> { + let mut keys = Vec::new(); + let mut values = Vec::new(); + + // Read the length of the arrays + let keys_len = U256::from_big_endian(&input[4..36]).as_usize(); + let mut pos = 36; + + // Read keys + for _ in 0..keys_len { + keys.push(U256::from_big_endian(&input[pos..pos + 32])); + pos += 32; + } + + // Read values + let values_len = U256::from_big_endian(&input[pos..pos + 32]).as_usize(); + pos += 32; + + for _ in 0..values_len { + values.push(U256::from_big_endian(&input[pos..pos + 32])); + pos += 32; + } + + let mut feed_values = Vec::new(); + for (key, value) in keys.iter().zip(values.iter()) { + let key: u32 = key.low_u32(); + let value: u64 = value.low_u64(); + feed_values.push((key, value)); + } + + let bounded_feed_values = feed_values.try_into().map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("Too many values".into()), + })?; + + let call = pallet_oracle::Call::::feed_values { values: bounded_feed_values }; + + Ok((ExitSucceed::Returned, vec![])) + } } -impl Precompile for OraclePrecompile +impl LinearCostPrecompile for OraclePrecompile where - Runtime: pallet_oracle::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, + Runtime: pallet_oracle::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, { - fn execute(handle: &mut impl PrecompileHandle) -> EvmResult { - let selector = handle.read_selector()?; - - match selector { - Action::GetValue => Self::get_value(handle, handle.read_u256()?), - Action::FeedValues => { - let keys = handle.read_u256_array()?; - let values = handle.read_u256_array()?; - Self::feed_values(handle, keys, values) - }, - } - } + const BASE: u64 = 20; + const WORD: u64 = 10; + + fn execute( + input: &[u8], + _target_gas: u64, + ) -> Result<(ExitSucceed, Vec), PrecompileFailure> { + let selector = input.get(0..4).ok_or_else(|| { + PrecompileFailure::Error { exit_status: ExitError::Other("Invalid selector".into()) } + })?; + let selector = u32::from_be_bytes(selector.try_into().unwrap()); + + match selector { + selectors::GET_VALUE => Self::get_value_impl(input), + selectors::FEED_VALUES => Self::feed_values_impl(input), + _ => Err(PrecompileFailure::Error { + exit_status: ExitError::Other("Unknown selector".into()), + }), + } + } } diff --git a/precompiles/oracle/src/tests.rs b/precompiles/oracle/src/tests.rs index 9795e8cd..1f257168 100644 --- a/precompiles/oracle/src/tests.rs +++ b/precompiles/oracle/src/tests.rs @@ -1,51 +1,71 @@ use super::*; -use crate::{mock::*, OraclePrecompile, OraclePrecompileCall}; +use crate::{mock::*, selectors, OraclePrecompile}; use frame_support::{assert_ok, BoundedVec}; -use precompile_utils::{ - precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}, - testing::PrecompileTesterExt, -}; use sp_core::{H160, U256}; -pub type PCall = OraclePrecompileCall; -pub type Precompiles = - PrecompileSetBuilder, OraclePrecompile>,)>; - -fn precompiles() -> Precompiles { - Precompiles::new() +fn evm_test_context() -> Context { + Context { + address: Default::default(), + caller: H160::from_low_u64_be(1), + apparent_value: Default::default(), + } } #[test] fn feed_values_works() { - ExtBuilder::default().build().execute_with(|| { - // Create a bounded vector for feed values - let mut feed_values = Vec::new(); - feed_values.push((1u32, 100u64)); - feed_values.push((2u32, 200u64)); - let bounded_feed_values: BoundedVec<_, _> = feed_values.try_into().unwrap(); - - assert_ok!(Oracle::feed_values( - RuntimeOrigin::signed(TestAccount::Alice), - bounded_feed_values - )); - }); + ExtBuilder::default().build().execute_with(|| { + // Create a bounded vector for feed values + let mut feed_values = Vec::new(); + feed_values.push((1u32, 100u64)); + feed_values.push((2u32, 200u64)); + let bounded_feed_values: BoundedVec<_, _> = feed_values.try_into().unwrap(); + + assert_ok!(Oracle::feed_values( + RuntimeOrigin::signed(TestAccount::Alice), + bounded_feed_values + )); + }); } #[test] fn precompile_feed_values_works() { - ExtBuilder::default().build().execute_with(|| { - // Test data - let key1: U256 = U256::from(1u32); - let value1: U256 = U256::from(100u64); - let key2: U256 = U256::from(2u32); - let value2: U256 = U256::from(200u64); - - precompiles() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PCall::feed_values { keys: vec![key1, key2], values: vec![value1, value2] }, - ) - .execute_returns(()); - }); + ExtBuilder::default().build().execute_with(|| { + // Test data + let key1: U256 = U256::from(1u32); + let value1: U256 = U256::from(100u64); + let key2: U256 = U256::from(2u32); + let value2: U256 = U256::from(200u64); + + // Build input data + let mut input = Vec::new(); + input.extend_from_slice(&selectors::FEED_VALUES.to_be_bytes()); + + // Write array lengths and data + let mut key_data = vec![0u8; 32]; + U256::from(2u32).to_big_endian(&mut key_data); + input.extend_from_slice(&key_data); + + let mut key1_data = vec![0u8; 32]; + key1.to_big_endian(&mut key1_data); + input.extend_from_slice(&key1_data); + + let mut key2_data = vec![0u8; 32]; + key2.to_big_endian(&mut key2_data); + input.extend_from_slice(&key2_data); + + let mut value_data = vec![0u8; 32]; + U256::from(2u32).to_big_endian(&mut value_data); + input.extend_from_slice(&value_data); + + let mut value1_data = vec![0u8; 32]; + value1.to_big_endian(&mut value1_data); + input.extend_from_slice(&value1_data); + + let mut value2_data = vec![0u8; 32]; + value2.to_big_endian(&mut value2_data); + input.extend_from_slice(&value2_data); + + let result = OraclePrecompile::::execute(&input, u64::MAX); + assert!(result.is_ok()); + }); } diff --git a/precompiles/pallet-democracy/Cargo.toml b/precompiles/pallet-democracy/Cargo.toml index 5e5b419c..50694ed6 100644 --- a/precompiles/pallet-democracy/Cargo.toml +++ b/precompiles/pallet-democracy/Cargo.toml @@ -8,7 +8,7 @@ description = "A Precompile to make Substrate's pallet-democracy accessible to p [dependencies] log = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -31,7 +31,7 @@ derive_more = { workspace = true, features = ["full"] } hex-literal = { workspace = true } serde = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/precompile-registry/Cargo.toml b/precompiles/precompile-registry/Cargo.toml index 6306faab..dbf5f591 100644 --- a/precompiles/precompile-registry/Cargo.toml +++ b/precompiles/precompile-registry/Cargo.toml @@ -8,7 +8,7 @@ description = "Registry of active precompiles" [dependencies] log = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -28,7 +28,7 @@ derive_more = { workspace = true, features = ["full"] } hex-literal = { workspace = true } serde = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/preimage/Cargo.toml b/precompiles/preimage/Cargo.toml index 2a829b31..d6d5e93a 100644 --- a/precompiles/preimage/Cargo.toml +++ b/precompiles/preimage/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" description = "A Precompile to make pallet-preimage calls encoding accessible to pallet-evm" [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -28,7 +28,7 @@ hex-literal = { workspace = true } serde = { workspace = true } sha3 = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/proxy/Cargo.toml b/precompiles/proxy/Cargo.toml index 738080ac..838d8440 100644 --- a/precompiles/proxy/Cargo.toml +++ b/precompiles/proxy/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to make proxy calls encoding accessible to pallet-ev [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -30,7 +30,7 @@ hex-literal = { workspace = true } serde = { workspace = true } sha3 = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/services/Cargo.toml b/precompiles/services/Cargo.toml index b878f90a..0d4b94b2 100644 --- a/precompiles/services/Cargo.toml +++ b/precompiles/services/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to make pallet-services calls encoding accessible to [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -40,7 +40,7 @@ serde_json = { workspace = true } smallvec = { workspace = true } sp-keystore = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/services/src/lib.rs b/precompiles/services/src/lib.rs index 91d2bc2d..b7a3bc9f 100644 --- a/precompiles/services/src/lib.rs +++ b/precompiles/services/src/lib.rs @@ -286,20 +286,6 @@ where Ok(()) } - /// Terminate a service by the owner of the service. - #[precompile::public("terminate(uint256)")] - fn terminate(handle: &mut impl PrecompileHandle, service_id: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let service_id: u64 = service_id.as_u64(); - - let call = pallet_services::Call::::terminate { service_id }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - /// Call a job in the service. #[precompile::public("callJob(uint256,uint8,bytes)")] fn call_job( diff --git a/precompiles/staking/Cargo.toml b/precompiles/staking/Cargo.toml index 15586d3c..25c82c0e 100644 --- a/precompiles/staking/Cargo.toml +++ b/precompiles/staking/Cargo.toml @@ -8,7 +8,7 @@ description = "A Precompile to make staking accessible to pallet-evm" [dependencies] tangle-primitives = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -30,7 +30,7 @@ derive_more = { workspace = true, features = ["full"] } serde = { workspace = true } sha3 = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/staking/StakingInterface.sol b/precompiles/staking/StakingInterface.sol index 48878869..e0ff826c 100644 --- a/precompiles/staking/StakingInterface.sol +++ b/precompiles/staking/StakingInterface.sol @@ -37,11 +37,6 @@ interface Staking { /// @return Max validator count function maxValidatorCount() external view returns (uint32); - /// @dev Check whether the specified address is a validator - /// @param stash the address that we want to confirm is a validator - /// @return A boolean confirming whether the address is a validator - function isValidator(address stash) external view returns (bool); - /// @dev Check whether the specified address is a nominator /// @param stash the address that we want to confirm is a nominator /// @return A boolean confirming whether the address is a nominator diff --git a/precompiles/staking/src/lib.rs b/precompiles/staking/src/lib.rs index aa08dbe3..a4f09258 100644 --- a/precompiles/staking/src/lib.rs +++ b/precompiles/staking/src/lib.rs @@ -218,7 +218,6 @@ where Ok(total_stake) } - #[precompile::public("erasTotalRewardPoints(uint32)")] #[precompile::public("eras_total_reward_points(uint32)")] #[precompile::view] fn eras_total_reward_points( diff --git a/precompiles/tangle-lst/Cargo.toml b/precompiles/tangle-lst/Cargo.toml index 2e0a26bd..b55ab1e4 100644 --- a/precompiles/tangle-lst/Cargo.toml +++ b/precompiles/tangle-lst/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to make pallet-multi-asset-delegation calls encoding [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -33,7 +33,7 @@ serde = { workspace = true } sha3 = { workspace = true } sp-staking = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/tangle-lst/TangleLst.sol b/precompiles/tangle-lst/TangleLst.sol index 0509880d..a9568b14 100644 --- a/precompiles/tangle-lst/TangleLst.sol +++ b/precompiles/tangle-lst/TangleLst.sol @@ -7,7 +7,7 @@ interface TangleLst { /// @dev Join a pool with a specified amount. /// @param amount The amount to join with. /// @param poolId The ID of the pool to join. - function join(uint256 amount, uint256 poolId) external returns (uint8); + function join(uint256 amount, uint256 poolId) external; /// @dev Bond extra to a pool. /// @param poolId The ID of the pool. diff --git a/precompiles/tangle-lst/src/lib.rs b/precompiles/tangle-lst/src/lib.rs index b49fdc01..3d66f29f 100644 --- a/precompiles/tangle-lst/src/lib.rs +++ b/precompiles/tangle-lst/src/lib.rs @@ -351,7 +351,7 @@ where Ok(addr) } - /// Helper for converting from u8 to RewardDestination + /// Helper for converting from H256 to AccountId fn convert_to_account_id(payee: H256) -> EvmResult { let payee = match payee { H256( diff --git a/precompiles/vesting/Cargo.toml b/precompiles/vesting/Cargo.toml index 6e4f1459..a2b521ff 100644 --- a/precompiles/vesting/Cargo.toml +++ b/precompiles/vesting/Cargo.toml @@ -7,7 +7,7 @@ description = "A Precompile to make pallet-vesting calls encoding accessible to [dependencies] -# Moonbeam + precompile-utils = { workspace = true } # Substrate @@ -32,7 +32,7 @@ hex-literal = { workspace = true } serde = { workspace = true } sha3 = { workspace = true } -# Moonbeam + precompile-utils = { workspace = true, features = ["std", "testing"] } # Substrate diff --git a/precompiles/vesting/src/lib.rs b/precompiles/vesting/src/lib.rs index d4c48406..9c613349 100644 --- a/precompiles/vesting/src/lib.rs +++ b/precompiles/vesting/src/lib.rs @@ -86,7 +86,7 @@ where Ok(addr) } - /// Helper for converting from u8 to RewardDestination + /// Helper for converting from H256 to AccountId fn convert_to_account_id(payee: H256) -> EvmResult { let payee = match payee { H256( diff --git a/primitives/ext/Cargo.toml b/primitives/ext/Cargo.toml index 9af40914..9cebec85 100644 --- a/primitives/ext/Cargo.toml +++ b/primitives/ext/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0-only" repository = { workspace = true } [dependencies] -# Moonbeam + evm-tracing-events = { workspace = true } # Substrate diff --git a/primitives/src/traits/data_provider.rs b/primitives/src/traits/data_provider.rs index 2ae57dc9..485bc4fa 100644 --- a/primitives/src/traits/data_provider.rs +++ b/primitives/src/traits/data_provider.rs @@ -96,10 +96,10 @@ mod tests { use sp_std::cell::RefCell; thread_local! { - static MOCK_PRICE_1: RefCell> = RefCell::new(None); - static MOCK_PRICE_2: RefCell> = RefCell::new(None); - static MOCK_PRICE_3: RefCell> = RefCell::new(None); - static MOCK_PRICE_4: RefCell> = RefCell::new(None); + static MOCK_PRICE_1: RefCell> = const { RefCell::new(None) }; + static MOCK_PRICE_2: RefCell> = const { RefCell::new(None) }; + static MOCK_PRICE_3: RefCell> = const { RefCell::new(None) }; + static MOCK_PRICE_4: RefCell> = const { RefCell::new(None) }; } macro_rules! mock_data_provider { From 4e7529955d2613f27eb935fb9c96114f9f81297e Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:38:49 +0530 Subject: [PATCH 36/63] base pallet --- pallets/rewards/Cargo.toml | 123 +++ pallets/rewards/src/benchmarking.rs | 292 +++++++ pallets/rewards/src/functions.rs | 23 + pallets/rewards/src/functions/delegate.rs | 429 +++++++++ pallets/rewards/src/functions/deposit.rs | 272 ++++++ pallets/rewards/src/functions/evm.rs | 143 +++ pallets/rewards/src/functions/operator.rs | 342 ++++++++ pallets/rewards/src/functions/rewards.rs | 144 ++++ .../rewards/src/functions/session_manager.rs | 41 + pallets/rewards/src/lib.rs | 816 ++++++++++++++++++ pallets/rewards/src/mock.rs | 617 +++++++++++++ pallets/rewards/src/mock_evm.rs | 342 ++++++++ pallets/rewards/src/tests.rs | 24 + pallets/rewards/src/tests/delegate.rs | 539 ++++++++++++ pallets/rewards/src/tests/deposit.rs | 509 +++++++++++ pallets/rewards/src/tests/operator.rs | 761 ++++++++++++++++ pallets/rewards/src/tests/session_manager.rs | 156 ++++ pallets/rewards/src/traits.rs | 72 ++ pallets/rewards/src/types.rs | 59 ++ pallets/rewards/src/types/delegator.rs | 219 +++++ pallets/rewards/src/types/operator.rs | 139 +++ pallets/rewards/src/types/rewards.rs | 43 + pallets/rewards/src/weights.rs | 55 ++ 23 files changed, 6160 insertions(+) create mode 100644 pallets/rewards/Cargo.toml create mode 100644 pallets/rewards/src/benchmarking.rs create mode 100644 pallets/rewards/src/functions.rs create mode 100644 pallets/rewards/src/functions/delegate.rs create mode 100644 pallets/rewards/src/functions/deposit.rs create mode 100644 pallets/rewards/src/functions/evm.rs create mode 100644 pallets/rewards/src/functions/operator.rs create mode 100644 pallets/rewards/src/functions/rewards.rs create mode 100644 pallets/rewards/src/functions/session_manager.rs create mode 100644 pallets/rewards/src/lib.rs create mode 100644 pallets/rewards/src/mock.rs create mode 100644 pallets/rewards/src/mock_evm.rs create mode 100644 pallets/rewards/src/tests.rs create mode 100644 pallets/rewards/src/tests/delegate.rs create mode 100644 pallets/rewards/src/tests/deposit.rs create mode 100644 pallets/rewards/src/tests/operator.rs create mode 100644 pallets/rewards/src/tests/session_manager.rs create mode 100644 pallets/rewards/src/traits.rs create mode 100644 pallets/rewards/src/types.rs create mode 100644 pallets/rewards/src/types/delegator.rs create mode 100644 pallets/rewards/src/types/operator.rs create mode 100644 pallets/rewards/src/types/rewards.rs create mode 100644 pallets/rewards/src/weights.rs diff --git a/pallets/rewards/Cargo.toml b/pallets/rewards/Cargo.toml new file mode 100644 index 00000000..9acdd01a --- /dev/null +++ b/pallets/rewards/Cargo.toml @@ -0,0 +1,123 @@ +[package] +name = "pallet-rewards" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +repository = { workspace = true } + +[dependencies] +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +log = { workspace = true } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } +ethabi = { workspace = true } +pallet-balances = { workspace = true } +tangle-primitives = { workspace = true } +pallet-assets = { workspace = true, default-features = false } +fp-evm = { workspace = true } +itertools = { workspace = true, features = ["use_alloc"] } +serde = { workspace = true, features = ["derive"], optional = true } +hex = { workspace = true, features = ["alloc"] } + +[dev-dependencies] +ethereum = { workspace = true, features = ["with-codec"] } +ethers = "2.0" +num_enum = { workspace = true } +hex-literal = { workspace = true } +libsecp256k1 = { workspace = true } +pallet-assets = { workspace = true } +pallet-balances = { workspace = true } +pallet-timestamp = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +smallvec = { workspace = true } +sp-io = { workspace = true } +sp-keystore = { workspace = true } + +# Frontier Primitive +fp-account = { workspace = true } +fp-consensus = { workspace = true } +fp-dynamic-fee = { workspace = true } +fp-ethereum = { workspace = true } +fp-rpc = { workspace = true } +fp-self-contained = { workspace = true } +fp-storage = { workspace = true } + +# Frontier FRAME +pallet-base-fee = { workspace = true } +pallet-dynamic-fee = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } + +pallet-evm-precompile-blake2 = { workspace = true } +pallet-evm-precompile-bn128 = { workspace = true } +pallet-evm-precompile-curve25519 = { workspace = true } +pallet-evm-precompile-ed25519 = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-sha3fips = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } + +precompile-utils = { workspace = true } +sp-keyring ={ workspace = true} +pallet-session = { workspace = true } +pallet-staking = { workspace = true } +sp-staking = { workspace = true } +frame-election-provider-support = { workspace = true } + +[features] +default = ["std"] +std = [ + "scale-info/std", + "sp-runtime/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "sp-core/std", + "sp-std/std", + "pallet-balances/std", + "pallet-assets/std", + "tangle-primitives/std", + "ethabi/std", + "log/std", + "fp-evm/std", + "serde/std", + "hex/std", + + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-precompile-blake2/std", + "pallet-evm-precompile-bn128/std", + "pallet-evm-precompile-curve25519/std", + "pallet-evm-precompile-ed25519/std", + "precompile-utils/std", + "pallet-staking/std", + "fp-account/std", + "fp-consensus/std", + "fp-dynamic-fee/std", + "fp-ethereum/std", + "fp-evm/std", + "fp-rpc/std", + "fp-self-contained/std", + "fp-storage/std", + "ethabi/std", + "sp-keyring/std", + "pallet-ethereum/std" +] +try-runtime = ["frame-support/try-runtime"] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", +] diff --git a/pallets/rewards/src/benchmarking.rs b/pallets/rewards/src/benchmarking.rs new file mode 100644 index 00000000..b231ce4e --- /dev/null +++ b/pallets/rewards/src/benchmarking.rs @@ -0,0 +1,292 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::*, Pallet as MultiAssetDelegation}; +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{Currency, Get, ReservableCurrency}, +}; +use frame_system::RawOrigin; +use sp_runtime::{traits::Zero, DispatchError}; + +const SEED: u32 = 0; + +benchmarks! { + join_operators { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + }: _(RawOrigin::Signed(caller.clone()), bond_amount) + verify { + assert!(Operators::::contains_key(&caller)); + } + + schedule_leave_operators { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + match operator.status { + OperatorStatus::Leaving(_) => {}, + _ => panic!("Operator should be in Leaving status"), + } + } + + cancel_leave_operators { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + MultiAssetDelegation::::schedule_leave_operators(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert_eq!(operator.status, OperatorStatus::Active); + } + + execute_leave_operators { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + MultiAssetDelegation::::schedule_leave_operators(RawOrigin::Signed(caller.clone()).into())?; + let current_round = Pallet::::current_round(); + CurrentRound::::put(current_round + T::LeaveOperatorsDelay::get()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(!Operators::::contains_key(&caller)); + } + + operator_bond_more { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + let additional_bond: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); + }: _(RawOrigin::Signed(caller.clone()), additional_bond) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert_eq!(operator.stake, bond_amount + additional_bond); + } + + schedule_operator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); + }: _(RawOrigin::Signed(caller.clone()), unstake_amount) + verify { + let operator = Operators::::get(&caller).unwrap(); + let request = operator.request.unwrap(); + assert_eq!(request.amount, unstake_amount); + } + + execute_operator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); + MultiAssetDelegation::::schedule_operator_unstake(RawOrigin::Signed(caller.clone()).into(), unstake_amount)?; + let current_round = Pallet::::current_round(); + CurrentRound::::put(current_round + T::OperatorBondLessDelay::get()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert_eq!(operator.stake, bond_amount - unstake_amount); + } + + cancel_operator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); + MultiAssetDelegation::::schedule_operator_unstake(RawOrigin::Signed(caller.clone()).into(), unstake_amount)?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert!(operator.request.is_none()); + } + + go_offline { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert_eq!(operator.status, OperatorStatus::Inactive); + } + + go_online { + + let caller: T::AccountId = whitelisted_caller(); + let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; + MultiAssetDelegation::::go_offline(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let operator = Operators::::get(&caller).unwrap(); + assert_eq!(operator.status, OperatorStatus::Active); + } + + deposit { + + let caller: T::AccountId = whitelisted_caller(); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + }: _(RawOrigin::Signed(caller.clone()), Some(asset_id), amount) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); + } + + schedule_withdraw { + + let caller: T::AccountId = whitelisted_caller(); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + }: _(RawOrigin::Signed(caller.clone()), Some(asset_id), amount) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.withdraw_requests.is_some()); + } + + execute_withdraw { + + let caller: T::AccountId = whitelisted_caller(); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + MultiAssetDelegation::::schedule_withdraw(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + let current_round = Pallet::::current_round(); + CurrentRound::::put(current_round + T::LeaveDelegatorsDelay::get()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.withdraw_requests.is_none()); + } + + cancel_withdraw { + + let caller: T::AccountId = whitelisted_caller(); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + MultiAssetDelegation::::schedule_withdraw(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.withdraw_requests.is_none()); + } + + delegate { + + let caller: T::AccountId = whitelisted_caller(); + let operator: T::AccountId = account("operator", 1, SEED); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + }: _(RawOrigin::Signed(caller.clone()), operator.clone(), asset_id, amount) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + let delegation = metadata.delegations.iter().find(|d| d.operator == operator && d.asset_id == asset_id).unwrap(); + assert_eq!(delegation.amount, amount); + } + + schedule_delegator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let operator: T::AccountId = account("operator", 1, SEED); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; + }: _(RawOrigin::Signed(caller.clone()), operator.clone(), asset_id, amount) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.delegator_unstake_requests.is_some()); + } + + execute_delegator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let operator: T::AccountId = account("operator", 1, SEED); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; + MultiAssetDelegation::::schedule_delegator_unstake(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; + let current_round = Pallet::::current_round(); + CurrentRound::::put(current_round + T::DelegationBondLessDelay::get()); + }: _(RawOrigin::Signed(caller.clone())) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.delegator_unstake_requests.is_none()); + } + + cancel_delegator_unstake { + + let caller: T::AccountId = whitelisted_caller(); + let operator: T::AccountId = account("operator", 1, SEED); + let asset_id: T::AssetId = 1_u32.into(); + let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; + MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; + MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; + MultiAssetDelegation::::schedule_delegator_unstake(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + let metadata = Delegators::::get(&caller).unwrap(); + assert!(metadata.delegator_unstake_requests.is_none()); + } + + set_incentive_apy_and_cap { + + let caller: T::AccountId = whitelisted_caller(); + let asset_id: T::AssetId = 1_u32.into(); + let apy: u128 = 1000; + let cap: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); + }: _(RawOrigin::Root, asset_id, apy, cap) + verify { + let config = RewardConfigStorage::::get().unwrap(); + let asset_config = config.configs.get(&asset_id).unwrap(); + assert_eq!(asset_config.apy, apy); + assert_eq!(asset_config.cap, cap); + } + + whitelist_blueprint_for_rewards { + + let caller: T::AccountId = whitelisted_caller(); + let blueprint_id: u32 = 1; + }: _(RawOrigin::Root, blueprint_id) + verify { + let config = RewardConfigStorage::::get().unwrap(); + assert!(config.whitelisted_blueprint_ids.contains(&blueprint_id)); + } +} diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs new file mode 100644 index 00000000..9ee9c028 --- /dev/null +++ b/pallets/rewards/src/functions.rs @@ -0,0 +1,23 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; + +pub mod delegate; +pub mod deposit; +pub mod evm; +pub mod operator; +pub mod rewards; +pub mod session_manager; diff --git a/pallets/rewards/src/functions/delegate.rs b/pallets/rewards/src/functions/delegate.rs new file mode 100644 index 00000000..eac6ad6d --- /dev/null +++ b/pallets/rewards/src/functions/delegate.rs @@ -0,0 +1,429 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::*, Pallet}; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{fungibles::Mutate, tokens::Preservation, Get}, +}; +use sp_runtime::{ + traits::{CheckedSub, Zero}, + DispatchError, Percent, +}; +use sp_std::vec::Vec; +use tangle_primitives::services::EvmAddressMapping; +use tangle_primitives::{services::Asset, BlueprintId}; + +impl Pallet { + /// Processes the delegation of an amount of an asset to an operator. + /// Creates a new delegation for the delegator and updates their status to active, the deposit + /// of the delegator is moved to delegation. + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `operator` - The account ID of the operator. + /// * `asset_id` - The ID of the asset to be delegated. + /// * `amount` - The amount to be delegated. + /// + /// # Errors + /// + /// Returns an error if the delegator does not have enough deposited balance, + /// or if the operator is not found. + pub fn process_delegate( + who: T::AccountId, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + blueprint_selection: DelegatorBlueprintSelection, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Ensure enough deposited balance + let balance = + metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; + ensure!(*balance >= amount, Error::::InsufficientBalance); + + // Reduce the balance in deposits + *balance = balance.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; + if *balance == Zero::zero() { + metadata.deposits.remove(&asset_id); + } + + // Check if the delegation exists and update it, otherwise create a new delegation + if let Some(delegation) = metadata + .delegations + .iter_mut() + .find(|d| d.operator == operator && d.asset_id == asset_id) + { + delegation.amount += amount; + } else { + // Create the new delegation + let new_delegation = BondInfoDelegator { + operator: operator.clone(), + amount, + asset_id, + blueprint_selection, + }; + + // Create a mutable copy of delegations + let mut delegations = metadata.delegations.clone(); + delegations + .try_push(new_delegation) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + metadata.delegations = delegations; + + // Update the status + metadata.status = DelegatorStatus::Active; + } + + // Update the operator's metadata + if let Some(mut operator_metadata) = Operators::::get(&operator) { + // Check if the operator has capacity for more delegations + ensure!( + operator_metadata.delegation_count < T::MaxDelegations::get(), + Error::::MaxDelegationsExceeded + ); + + // Create and push the new delegation bond + let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; + + let mut delegations = operator_metadata.delegations.clone(); + + // Check if delegation already exists + if let Some(existing_delegation) = + delegations.iter_mut().find(|d| d.delegator == who && d.asset_id == asset_id) + { + existing_delegation.amount += amount; + } else { + delegations + .try_push(delegation) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + operator_metadata.delegation_count = + operator_metadata.delegation_count.saturating_add(1); + } + + operator_metadata.delegations = delegations; + + // Update storage + Operators::::insert(&operator, operator_metadata); + } else { + return Err(Error::::NotAnOperator.into()); + } + + Ok(()) + }) + } + + /// Schedules a stake reduction for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `operator` - The account ID of the operator. + /// * `asset_id` - The ID of the asset to be reduced. + /// * `amount` - The amount to be reduced. + /// + /// # Errors + /// + /// Returns an error if the delegator has no active delegation, + /// or if the unstake amount is greater than the current delegation amount. + pub fn process_schedule_delegator_unstake( + who: T::AccountId, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Ensure the delegator has an active delegation with the operator for the given asset + let delegation_index = metadata + .delegations + .iter() + .position(|d| d.operator == operator && d.asset_id == asset_id) + .ok_or(Error::::NoActiveDelegation)?; + + // Get the delegation and clone necessary data + let blueprint_selection = + metadata.delegations[delegation_index].blueprint_selection.clone(); + let delegation = &mut metadata.delegations[delegation_index]; + ensure!(delegation.amount >= amount, Error::::InsufficientBalance); + + delegation.amount -= amount; + + // Create the unstake request + let current_round = Self::current_round(); + let mut unstake_requests = metadata.delegator_unstake_requests.clone(); + unstake_requests + .try_push(BondLessRequest { + operator: operator.clone(), + asset_id, + amount, + requested_round: current_round, + blueprint_selection, + }) + .map_err(|_| Error::::MaxUnstakeRequestsExceeded)?; + metadata.delegator_unstake_requests = unstake_requests; + + // Remove the delegation if the remaining amount is zero + if delegation.amount.is_zero() { + metadata.delegations.remove(delegation_index); + } + + // Update the operator's metadata + Operators::::try_mutate(&operator, |maybe_operator_metadata| -> DispatchResult { + let operator_metadata = + maybe_operator_metadata.as_mut().ok_or(Error::::NotAnOperator)?; + + // Ensure the operator has a matching delegation + let operator_delegation_index = operator_metadata + .delegations + .iter() + .position(|d| d.delegator == who && d.asset_id == asset_id) + .ok_or(Error::::NoActiveDelegation)?; + + let operator_delegation = + &mut operator_metadata.delegations[operator_delegation_index]; + + // Reduce the amount in the operator's delegation + ensure!(operator_delegation.amount >= amount, Error::::InsufficientBalance); + operator_delegation.amount -= amount; + + // Remove the delegation if the remaining amount is zero + if operator_delegation.amount.is_zero() { + operator_metadata.delegations.remove(operator_delegation_index); + operator_metadata.delegation_count -= 1; + } + + Ok(()) + })?; + + Ok(()) + }) + } + + /// Executes scheduled stake reductions for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// + /// # Errors + /// + /// Returns an error if the delegator has no unstake requests or if none of the unstake requests + /// are ready. + pub fn process_execute_delegator_unstake(who: T::AccountId) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Ensure there are outstanding unstake requests + ensure!(!metadata.delegator_unstake_requests.is_empty(), Error::::NoBondLessRequest); + + let current_round = Self::current_round(); + + // Process all ready unstake requests + let mut executed_requests = Vec::new(); + metadata.delegator_unstake_requests.retain(|request| { + let delay = T::DelegationBondLessDelay::get(); + if current_round >= delay + request.requested_round { + // Add the amount back to the delegator's deposits + metadata + .deposits + .entry(request.asset_id) + .and_modify(|e| *e += request.amount) + .or_insert(request.amount); + executed_requests.push(request.clone()); + false // Remove this request + } else { + true // Keep this request + } + }); + + // If no requests were executed, return an error + ensure!(!executed_requests.is_empty(), Error::::BondLessNotReady); + + Ok(()) + }) + } + + /// Cancels a scheduled stake reduction for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `asset_id` - The ID of the asset for which to cancel the unstake request. + /// * `amount` - The amount of the unstake request to cancel. + /// + /// # Errors + /// + /// Returns an error if the delegator has no matching unstake request or if there is no active + /// delegation. + pub fn process_cancel_delegator_unstake( + who: T::AccountId, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Find and remove the matching unstake request + let request_index = metadata + .delegator_unstake_requests + .iter() + .position(|r| { + r.asset_id == asset_id && r.amount == amount && r.operator == operator + }) + .ok_or(Error::::NoBondLessRequest)?; + + let unstake_request = metadata.delegator_unstake_requests.remove(request_index); + + // Update the operator's metadata + Operators::::try_mutate( + &unstake_request.operator, + |maybe_operator_metadata| -> DispatchResult { + let operator_metadata = + maybe_operator_metadata.as_mut().ok_or(Error::::NotAnOperator)?; + + // Find the matching delegation and increase its amount, or insert a new + // delegation if not found + let mut delegations = operator_metadata.delegations.clone(); + if let Some(delegation) = delegations + .iter_mut() + .find(|d| d.asset_id == asset_id && d.delegator == who.clone()) + { + delegation.amount += amount; + } else { + delegations + .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + + // Increase the delegation count only when a new delegation is added + operator_metadata.delegation_count += 1; + } + operator_metadata.delegations = delegations; + + Ok(()) + }, + )?; + + // Update the delegator's metadata + let mut delegations = metadata.delegations.clone(); + + // If a similar delegation exists, increase the amount + if let Some(delegation) = delegations.iter_mut().find(|d| { + d.operator == unstake_request.operator && d.asset_id == unstake_request.asset_id + }) { + delegation.amount += unstake_request.amount; + } else { + // Create a new delegation + delegations + .try_push(BondInfoDelegator { + operator: unstake_request.operator.clone(), + amount: unstake_request.amount, + asset_id: unstake_request.asset_id, + blueprint_selection: unstake_request.blueprint_selection, + }) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + } + metadata.delegations = delegations; + + Ok(()) + }) + } + + /// Slashes a delegator's stake. + /// + /// # Arguments + /// + /// * `delegator` - The account ID of the delegator. + /// * `operator` - The account ID of the operator. + /// * `blueprint_id` - The ID of the blueprint. + /// * `percentage` - The percentage of the stake to slash. + /// + /// # Errors + /// + /// Returns an error if the delegator is not found, or if the delegation is not active. + pub fn slash_delegator( + delegator: &T::AccountId, + operator: &T::AccountId, + blueprint_id: BlueprintId, + percentage: Percent, + ) -> Result<(), DispatchError> { + Delegators::::try_mutate(delegator, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + let delegation = metadata + .delegations + .iter_mut() + .find(|d| &d.operator == operator) + .ok_or(Error::::NoActiveDelegation)?; + + // Check delegation type and blueprint_id + match &delegation.blueprint_selection { + DelegatorBlueprintSelection::Fixed(blueprints) => { + // For fixed delegation, ensure the blueprint_id is in the list + ensure!(blueprints.contains(&blueprint_id), Error::::BlueprintNotSelected); + }, + DelegatorBlueprintSelection::All => { + // For "All" type, no need to check blueprint_id + }, + } + + // Calculate and apply slash + let slash_amount = percentage.mul_floor(delegation.amount); + delegation.amount = delegation + .amount + .checked_sub(&slash_amount) + .ok_or(Error::::InsufficientStakeRemaining)?; + + match delegation.asset_id { + Asset::Custom(asset_id) => { + // Transfer slashed amount to the treasury + let _ = T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &T::SlashedAmountRecipient::get(), + slash_amount, + Preservation::Expendable, + ); + }, + Asset::Erc20(address) => { + let slashed_amount_recipient_evm = + T::EvmAddressMapping::into_address(T::SlashedAmountRecipient::get()); + let (success, _weight) = Self::erc20_transfer( + address, + &Self::pallet_evm_account(), + slashed_amount_recipient_evm, + slash_amount, + ) + .map_err(|_| Error::::ERC20TransferFailed)?; + ensure!(success, Error::::ERC20TransferFailed); + }, + } + + // emit event + Self::deposit_event(Event::DelegatorSlashed { + who: delegator.clone(), + amount: slash_amount, + }); + + Ok(()) + }) + } +} diff --git a/pallets/rewards/src/functions/deposit.rs b/pallets/rewards/src/functions/deposit.rs new file mode 100644 index 00000000..5f7a17fa --- /dev/null +++ b/pallets/rewards/src/functions/deposit.rs @@ -0,0 +1,272 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::*, Pallet}; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, + traits::{fungibles::Mutate, tokens::Preservation, Get}, +}; +use sp_core::H160; +use tangle_primitives::services::{Asset, EvmAddressMapping}; + +impl Pallet { + /// Returns the account ID of the pallet. + pub fn pallet_account() -> T::AccountId { + T::PalletId::get().into_account_truncating() + } + + /// Returns the EVM account id of the pallet. + /// + /// This function retrieves the account id associated with the pallet by converting + /// the pallet evm address to an account id. + /// + /// # Returns + /// * `T::AccountId` - The account id of the pallet. + pub fn pallet_evm_account() -> H160 { + T::EvmAddressMapping::into_address(Self::pallet_account()) + } + + pub fn handle_transfer_to_pallet( + sender: &T::AccountId, + asset_id: Asset, + amount: BalanceOf, + evm_sender: Option, + ) -> DispatchResult { + match asset_id { + Asset::Custom(asset_id) => { + T::Fungibles::transfer( + asset_id, + sender, + &Self::pallet_account(), + amount, + Preservation::Expendable, + )?; + }, + Asset::Erc20(asset_address) => { + let sender = evm_sender.ok_or(Error::::ERC20TransferFailed)?; + let (success, _weight) = Self::erc20_transfer( + asset_address, + &sender, + Self::pallet_evm_account(), + amount, + ) + .map_err(|_| Error::::ERC20TransferFailed)?; + ensure!(success, Error::::ERC20TransferFailed); + }, + } + Ok(()) + } + + /// Processes the deposit of assets into the pallet. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `asset_id` - The optional asset ID of the assets to be deposited. + /// * `amount` - The amount of assets to be deposited. + /// + /// # Errors + /// + /// Returns an error if the user is already a delegator, if the stake amount is too low, or if + /// the transfer fails. + pub fn process_deposit( + who: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + evm_address: Option, + ) -> DispatchResult { + ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); + + // Transfer the amount to the pallet account + Self::handle_transfer_to_pallet(&who, asset_id, amount, evm_address)?; + + // Update storage + Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { + let metadata = maybe_metadata.get_or_insert_with(Default::default); + // Handle checked addition first to avoid ? operator in closure + if let Some(existing) = metadata.deposits.get(&asset_id) { + let new_amount = + existing.checked_add(&amount).ok_or(Error::::DepositOverflow)?; + metadata.deposits.insert(asset_id, new_amount); + } else { + metadata.deposits.insert(asset_id, amount); + } + Ok(()) + })?; + + Ok(()) + } + + /// Schedules an withdraw request for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `asset_id` - The optional asset ID of the assets to be withdrawd. + /// * `amount` - The amount of assets to be withdrawd. + /// + /// # Errors + /// + /// Returns an error if the user is not a delegator, if there is insufficient balance, or if the + /// asset is not supported. + pub fn process_schedule_withdraw( + who: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Ensure there is enough deposited balance + let balance = + metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; + ensure!(*balance >= amount, Error::::InsufficientBalance); + + // Reduce the balance in deposits + *balance -= amount; + if *balance == Zero::zero() { + metadata.deposits.remove(&asset_id); + } + + // Create the unstake request + let current_round = Self::current_round(); + let mut withdraw_requests = metadata.withdraw_requests.clone(); + withdraw_requests + .try_push(WithdrawRequest { asset_id, amount, requested_round: current_round }) + .map_err(|_| Error::::MaxWithdrawRequestsExceeded)?; + metadata.withdraw_requests = withdraw_requests; + + Ok(()) + }) + } + + /// Executes an withdraw request for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// + /// # Errors + /// + /// Returns an error if the user is not a delegator, if there are no withdraw requests, or if + /// the withdraw request is not ready. + pub fn process_execute_withdraw( + who: T::AccountId, + evm_address: Option, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Ensure there are outstanding withdraw requests + ensure!(!metadata.withdraw_requests.is_empty(), Error::::NowithdrawRequests); + + let current_round = Self::current_round(); + let delay = T::LeaveDelegatorsDelay::get(); + + // Process all ready withdraw requests + let mut i = 0; + while i < metadata.withdraw_requests.len() { + let request = &metadata.withdraw_requests[i]; + if current_round >= delay + request.requested_round { + let transfer_success = match request.asset_id { + Asset::Custom(asset_id) => T::Fungibles::transfer( + asset_id, + &Self::pallet_account(), + &who, + request.amount, + Preservation::Expendable, + ) + .is_ok(), + Asset::Erc20(asset_address) => { + if let Some(evm_addr) = evm_address { + if let Ok((success, _weight)) = Self::erc20_transfer( + asset_address, + &Self::pallet_evm_account(), + evm_addr, + request.amount, + ) { + success + } else { + false + } + } else { + false + } + }, + }; + + if transfer_success { + // Remove the completed request + metadata.withdraw_requests.remove(i); + } else { + // Only increment if we didn't remove the request + i += 1; + } + } else { + i += 1; + } + } + + Ok(()) + }) + } + + /// Cancels an withdraw request for a delegator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the delegator. + /// * `asset_id` - The asset ID of the withdraw request to cancel. + /// * `amount` - The amount of the withdraw request to cancel. + /// + /// # Errors + /// + /// Returns an error if the user is not a delegator or if there is no matching withdraw request. + pub fn process_cancel_withdraw( + who: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + Delegators::::try_mutate(&who, |maybe_metadata| { + let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + + // Find and remove the matching withdraw request + let request_index = metadata + .withdraw_requests + .iter() + .position(|r| r.asset_id == asset_id && r.amount == amount) + .ok_or(Error::::NoMatchingwithdrawRequest)?; + + let withdraw_request = metadata.withdraw_requests.remove(request_index); + + // Add the amount back to the delegator's deposits + metadata + .deposits + .entry(asset_id) + .and_modify(|e| *e += withdraw_request.amount) + .or_insert(withdraw_request.amount); + + // Update the status if no more delegations exist + if metadata.delegations.is_empty() { + metadata.status = DelegatorStatus::Active; + } + + Ok(()) + }) + } +} diff --git a/pallets/rewards/src/functions/evm.rs b/pallets/rewards/src/functions/evm.rs new file mode 100644 index 00000000..e2cb6140 --- /dev/null +++ b/pallets/rewards/src/functions/evm.rs @@ -0,0 +1,143 @@ +use super::*; +use crate::types::BalanceOf; +use ethabi::{Function, StateMutability, Token}; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + pallet_prelude::{Pays, Weight}, +}; +use parity_scale_codec::Encode; +use scale_info::prelude::string::String; +use sp_core::{H160, U256}; +use sp_runtime::traits::UniqueSaturatedInto; +use sp_std::{vec, vec::Vec}; +use tangle_primitives::services::{EvmGasWeightMapping, EvmRunner}; + +impl Pallet { + /// Moves a `value` amount of tokens from the caller's account to `to`. + pub fn erc20_transfer( + erc20: H160, + from: &H160, + to: H160, + value: BalanceOf, + ) -> Result<(bool, Weight), DispatchErrorWithPostInfo> { + #[allow(deprecated)] + let transfer_fn = Function { + name: String::from("transfer"), + inputs: vec![ + ethabi::Param { + name: String::from("to"), + kind: ethabi::ParamType::Address, + internal_type: None, + }, + ethabi::Param { + name: String::from("value"), + kind: ethabi::ParamType::Uint(256), + internal_type: None, + }, + ], + outputs: vec![ethabi::Param { + name: String::from("success"), + kind: ethabi::ParamType::Bool, + internal_type: None, + }], + constant: None, + state_mutability: StateMutability::NonPayable, + }; + + let args = [ + Token::Address(to), + Token::Uint(ethabi::Uint::from(value.using_encoded(U256::from_little_endian))), + ]; + + log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(transfer_fn.short_signature()), transfer_fn.signature()); + let data = transfer_fn.encode_input(&args).map_err(|_| Error::::EVMAbiEncode)?; + let gas_limit = 300_000; + let info = Self::evm_call(*from, erc20, U256::zero(), data, gas_limit)?; + let weight = Self::weight_from_call_info(&info); + + // decode the result and return it + let maybe_value = info.exit_reason.is_succeed().then_some(&info.value); + let success = if let Some(data) = maybe_value { + let result = transfer_fn.decode_output(data).map_err(|_| Error::::EVMAbiDecode)?; + let success = result.first().ok_or(Error::::EVMAbiDecode)?; + if let ethabi::Token::Bool(val) = success { + *val + } else { + false + } + } else { + false + }; + + Ok((success, weight)) + } + + /// Dispatches a call to the EVM and returns the result. + fn evm_call( + from: H160, + to: H160, + value: U256, + data: Vec, + gas_limit: u64, + ) -> Result { + let transactional = true; + let validate = false; + let result = + T::EvmRunner::call(from, to, data.clone(), value, gas_limit, transactional, validate); + match result { + Ok(info) => { + log::debug!( + target: "evm", + "Call from: {:?}, to: {:?}, data: 0x{}, gas_limit: {:?}, result: {:?}", + from, + to, + hex::encode(&data), + gas_limit, + info, + ); + // if we have a revert reason, emit an event + if info.exit_reason.is_revert() { + log::debug!( + target: "evm", + "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", + to, + hex::encode(&data), + hex::encode(&info.value), + ); + #[cfg(test)] + eprintln!( + "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", + to, + hex::encode(&data), + hex::encode(&info.value), + ); + Self::deposit_event(Event::::EvmReverted { + from, + to, + data, + reason: info.value.clone(), + }); + } + Ok(info) + }, + Err(e) => Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: Some(e.weight), pays_fee: Pays::Yes }, + error: e.error.into(), + }), + } + } + + /// Convert the gas used in the call info to weight. + pub fn weight_from_call_info(info: &fp_evm::CallInfo) -> Weight { + let mut gas_to_weight = T::EvmGasWeightMapping::gas_to_weight( + info.used_gas.standard.unique_saturated_into(), + true, + ); + if let Some(weight_info) = info.weight_info { + if let Some(proof_size_usage) = weight_info.proof_size_usage { + *gas_to_weight.proof_size_mut() = proof_size_usage; + } + } + gas_to_weight + } +} diff --git a/pallets/rewards/src/functions/operator.rs b/pallets/rewards/src/functions/operator.rs new file mode 100644 index 00000000..9e6e2b39 --- /dev/null +++ b/pallets/rewards/src/functions/operator.rs @@ -0,0 +1,342 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +/// Functions for the pallet. +use super::*; +use crate::{types::*, Pallet}; +use frame_support::{ + ensure, + pallet_prelude::DispatchResult, + traits::{Currency, ExistenceRequirement, Get, ReservableCurrency}, + BoundedVec, +}; +use sp_runtime::{ + traits::{CheckedAdd, CheckedSub}, + DispatchError, Percent, +}; +use tangle_primitives::{BlueprintId, ServiceManager}; + +impl Pallet { + /// Handles the deposit of stake amount and creation of an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// * `bond_amount` - The amount to be bonded by the operator. + /// + /// # Errors + /// + /// Returns an error if the user is already an operator or if the stake amount is too low. + pub fn handle_deposit_and_create_operator( + who: T::AccountId, + bond_amount: BalanceOf, + ) -> DispatchResult { + ensure!(!Operators::::contains_key(&who), Error::::AlreadyOperator); + ensure!(bond_amount >= T::MinOperatorBondAmount::get(), Error::::BondTooLow); + T::Currency::reserve(&who, bond_amount)?; + + let operator_metadata = OperatorMetadata { + delegations: BoundedVec::default(), + delegation_count: 0, + blueprint_ids: BoundedVec::default(), + stake: bond_amount, + request: None, + status: OperatorStatus::Active, + }; + + Operators::::insert(&who, operator_metadata); + + Ok(()) + } + + /// Processes the leave operation for an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found, already leaving, or cannot exit. + #[allow(clippy::single_match)] + pub fn process_leave_operator(who: &T::AccountId) -> DispatchResult { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + + match operator.status { + OperatorStatus::Leaving(_) => return Err(Error::::AlreadyLeaving.into()), + _ => {}, + }; + + ensure!(T::ServiceManager::can_exit(who), Error::::CannotExit); + + let current_round = Self::current_round(); + let leaving_time = current_round + T::LeaveOperatorsDelay::get(); + + operator.status = OperatorStatus::Leaving(leaving_time); + Operators::::insert(who, operator); + + Ok(()) + } + + /// Cancels the leave operation for an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found or not in leaving state. + pub fn process_cancel_leave_operator(who: &T::AccountId) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + + match operator.status { + OperatorStatus::Leaving(_) => {}, + _ => return Err(Error::::NotLeavingOperator.into()), + }; + + operator.status = OperatorStatus::Active; + Operators::::insert(who, operator); + + Ok(()) + } + + /// Executes the leave operation for an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found, not in leaving state, or the leaving round + /// has not been reached. + pub fn process_execute_leave_operators(who: &T::AccountId) -> Result<(), DispatchError> { + let operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + let current_round = Self::current_round(); + + match operator.status { + OperatorStatus::Leaving(leaving_round) => { + ensure!(current_round >= leaving_round, Error::::LeavingRoundNotReached); + }, + _ => return Err(Error::::NotLeavingOperator.into()), + }; + + T::Currency::unreserve(who, operator.stake); + Operators::::remove(who); + + Ok(()) + } + + /// Processes an additional TNT stake for an operator, called + /// by themselves. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// * `additional_bond` - The additional amount to be bonded by the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found or if the reserve fails. + pub fn process_operator_bond_more( + who: &T::AccountId, + additional_bond: BalanceOf, + ) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + + // Check for potential overflow before reserving funds + operator.stake = + operator.stake.checked_add(&additional_bond).ok_or(Error::::StakeOverflow)?; + + // Only reserve funds if the addition would be safe + T::Currency::reserve(who, additional_bond)?; + + Operators::::insert(who, operator); + + Ok(()) + } + + /// Schedules a native TNT stake reduction for an operator, called + /// by themselves. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// * `unstake_amount` - The amount to be reduced from the operator's stake. + /// + /// # Errors + /// + /// Returns an error if the operator is not found, has active services, or cannot exit. + pub fn process_schedule_operator_unstake( + who: &T::AccountId, + unstake_amount: BalanceOf, + ) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + ensure!(T::ServiceManager::can_exit(who), Error::::CannotExit); + + // Ensure there's no existing unstake request + ensure!(operator.request.is_none(), Error::::PendingUnstakeRequestExists); + + // Ensure the unstake amount doesn't exceed current stake + ensure!(unstake_amount <= operator.stake, Error::::UnstakeAmountTooLarge); + + // Ensure operator maintains minimum required stake after unstaking + let remaining_stake = operator + .stake + .checked_sub(&unstake_amount) + .ok_or(Error::::UnstakeAmountTooLarge)?; + ensure!( + remaining_stake >= T::MinOperatorBondAmount::get(), + Error::::InsufficientStakeRemaining + ); + + operator.request = Some(OperatorBondLessRequest { + amount: unstake_amount, + request_time: Self::current_round(), + }); + Operators::::insert(who, operator); + + Ok(()) + } + + /// Executes a scheduled stake reduction for an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found, has no scheduled stake reduction, or the + /// request is not satisfied. + pub fn process_execute_operator_unstake(who: &T::AccountId) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + let request = operator.request.as_ref().ok_or(Error::::NoScheduledBondLess)?; + let current_round = Self::current_round(); + + ensure!( + current_round >= T::OperatorBondLessDelay::get() + request.request_time, + Error::::BondLessRequestNotSatisfied + ); + + operator.stake = operator + .stake + .checked_sub(&request.amount) + .ok_or(Error::::UnstakeAmountTooLarge)?; + + operator.request = None; + Operators::::insert(who, operator); + + Ok(()) + } + + /// Cancels a scheduled stake reduction for an operator. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found or has no scheduled stake reduction. + pub fn process_cancel_operator_unstake(who: &T::AccountId) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + ensure!(operator.request.is_some(), Error::::NoScheduledBondLess); + + operator.request = None; + Operators::::insert(who, operator); + + Ok(()) + } + + /// Sets the operator status to offline. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found or not currently active. + pub fn process_go_offline(who: &T::AccountId) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + ensure!(operator.status == OperatorStatus::Active, Error::::NotActiveOperator); + + operator.status = OperatorStatus::Inactive; + Operators::::insert(who, operator); + + Ok(()) + } + + /// Sets the operator status to online. + /// + /// # Arguments + /// + /// * `who` - The account ID of the operator. + /// + /// # Errors + /// + /// Returns an error if the operator is not found or not currently inactive. + pub fn process_go_online(who: &T::AccountId) -> Result<(), DispatchError> { + let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; + ensure!(operator.status == OperatorStatus::Inactive, Error::::NotOfflineOperator); + + operator.status = OperatorStatus::Active; + Operators::::insert(who, operator); + + Ok(()) + } + + pub fn slash_operator( + operator: &T::AccountId, + blueprint_id: BlueprintId, + percentage: Percent, + ) -> Result<(), DispatchError> { + Operators::::try_mutate(operator, |maybe_operator| { + let operator_data = maybe_operator.as_mut().ok_or(Error::::NotAnOperator)?; + ensure!(operator_data.status == OperatorStatus::Active, Error::::NotActiveOperator); + + // Slash operator stake + let amount = percentage.mul_floor(operator_data.stake); + operator_data.stake = operator_data + .stake + .checked_sub(&amount) + .ok_or(Error::::InsufficientStakeRemaining)?; + + // Slash each delegator + for delegator in operator_data.delegations.iter() { + // Ignore errors from individual delegator slashing + let _ = + Self::slash_delegator(&delegator.delegator, operator, blueprint_id, percentage); + } + + // transfer the slashed amount to the treasury + T::Currency::unreserve(operator, amount); + let _ = T::Currency::transfer( + operator, + &T::SlashedAmountRecipient::get(), + amount, + ExistenceRequirement::AllowDeath, + ); + + // emit event + Self::deposit_event(Event::OperatorSlashed { who: operator.clone(), amount }); + + Ok(()) + }) + } +} diff --git a/pallets/rewards/src/functions/rewards.rs b/pallets/rewards/src/functions/rewards.rs new file mode 100644 index 00000000..23288fce --- /dev/null +++ b/pallets/rewards/src/functions/rewards.rs @@ -0,0 +1,144 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::*, Pallet}; +use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; +use tangle_primitives::{services::Asset, RoundIndex}; + +impl Pallet { + #[allow(clippy::type_complexity)] + pub fn distribute_rewards(_round: RoundIndex) -> DispatchResult { + // let mut delegation_info: BTreeMap< + // T::AssetId, + // Vec, T::AssetId>>, + // > = BTreeMap::new(); + + // // Iterate through all operator snapshots for the given round + // // TODO: Could be dangerous with many operators + // for (_, operator_snapshot) in AtStake::::iter_prefix(round) { + // for delegation in &operator_snapshot.delegations { + // delegation_info.entry(delegation.asset_id).or_default().push(delegation.clone()); + // } + // } + + // // Get the reward configuration + // if let Some(reward_config) = RewardConfigStorage::::get() { + // // Distribute rewards for each asset + // for (asset_id, delegations) in delegation_info.iter() { + // // We only reward asset in a reward vault + // if let Some(vault_id) = AssetLookupRewardVaults::::get(asset_id) { + // if let Some(config) = reward_config.configs.get(&vault_id) { + // // Calculate total amount and distribute rewards + // let total_amount: BalanceOf = + // delegations.iter().fold(Zero::zero(), |acc, d| acc + d.amount); + // let cap: BalanceOf = config.cap; + + // if total_amount >= cap { + // // Calculate the total reward based on the APY + // let total_reward = + // Self::calculate_total_reward(config.apy, total_amount)?; + + // for delegation in delegations { + // // Calculate the percentage of the cap that the user is staking + // let staking_percentage = + // delegation.amount.saturating_mul(100u32.into()) / cap; + // // Calculate the reward based on the staking percentage + // let reward = + // total_reward.saturating_mul(staking_percentage) / 100u32.into(); + // // Distribute the reward to the delegator + // Self::distribute_reward_to_delegator( + // &delegation.delegator, + // reward, + // )?; + // } + // } + // } + // } + // } + // } + + Ok(()) + } + + fn _calculate_total_reward( + apy: sp_runtime::Percent, + total_amount: BalanceOf, + ) -> Result, DispatchError> { + let total_reward = apy.mul_floor(total_amount); + Ok(total_reward) + } + + fn _distribute_reward_to_delegator( + delegator: &T::AccountId, + reward: BalanceOf, + ) -> DispatchResult { + // mint rewards to delegator + let _ = T::Currency::deposit_creating(delegator, reward); + Ok(()) + } + + pub fn add_asset_to_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { + // Ensure the asset is not already associated with any vault + ensure!( + !AssetLookupRewardVaults::::contains_key(asset_id), + Error::::AssetAlreadyInVault + ); + + // Update RewardVaults storage + RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { + let assets = maybe_assets.get_or_insert_with(Vec::new); + + // Ensure the asset is not already in the vault + ensure!(!assets.contains(asset_id), Error::::AssetAlreadyInVault); + + assets.push(*asset_id); + + Ok(()) + })?; + + // Update AssetLookupRewardVaults storage + AssetLookupRewardVaults::::insert(asset_id, vault_id); + + Ok(()) + } + + pub fn remove_asset_from_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { + // Update RewardVaults storage + RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { + let assets = maybe_assets.as_mut().ok_or(Error::::VaultNotFound)?; + + // Ensure the asset is in the vault + ensure!(assets.contains(asset_id), Error::::AssetNotInVault); + + assets.retain(|id| id != asset_id); + + Ok(()) + })?; + + // Update AssetLookupRewardVaults storage + AssetLookupRewardVaults::::remove(asset_id); + + Ok(()) + } +} diff --git a/pallets/rewards/src/functions/session_manager.rs b/pallets/rewards/src/functions/session_manager.rs new file mode 100644 index 00000000..050f3b70 --- /dev/null +++ b/pallets/rewards/src/functions/session_manager.rs @@ -0,0 +1,41 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::*, Pallet}; + +use frame_support::pallet_prelude::DispatchResult; + +impl Pallet { + pub fn handle_round_change() -> DispatchResult { + // Increment the current round + CurrentRound::::mutate(|round| *round += 1); + let current_round = Self::current_round(); + + // Iterate through all operators and build their snapshots + for (operator, metadata) in Operators::::iter() { + // Create the operator snapshot + let snapshot = OperatorSnapshot { + stake: metadata.stake, + delegations: metadata.delegations.clone(), + }; + + // Store the snapshot in AtStake storage + AtStake::::insert(current_round, operator.clone(), snapshot); + } + + Ok(()) + } +} diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs new file mode 100644 index 00000000..6f6d33dc --- /dev/null +++ b/pallets/rewards/src/lib.rs @@ -0,0 +1,816 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +//! # Tangle Multi Asset Delegation Pallet +//! +//! This crate provides the delegation framework for the Tangle network, enabling the delegation of +//! assets to operators for earning rewards. +//! +//! ## Key Components +//! +//! - **Operators**: Operators are entities within the Tangle network that can receive delegated +//! assets from delegators. They manage these assets, perform jobs and generate rewards for +//! delegators. +//! - **Deposits**: Depositors must first reserve (deposit) their assets before they can delegate +//! them to operators. This ensures that the assets are locked and available for delegation. +//! - **Delegation**: Delegation is the process where delegators assign their deposited assets to +//! operators to earn rewards. +//! +//! ## Workflow for Delegators +//! +//! 1. **Deposit**: Before a delegator can delegate assets to an operator, they must first deposit +//! the desired amount of assets. This reserves the assets in the delegator's account. +//! 2. **Delegate**: After depositing assets, the delegator can delegate these assets to an +//! operator. The operator then manages these assets, and the delegator can earn rewards from the +//! operator's activities. +//! 3. **Unstake**: If a delegator wants to reduce their delegation, they can schedule a unstake +//! request. This request will be executed after a specified delay, ensuring network stability. +//! 4. **withdraw Request**: To completely remove assets from delegation, a delegator must submit an +//! withdraw request. Similar to unstake requests, withdraw requests also have a delay before +//! they can be executed. +//! +//! ## Workflow for Operators +//! +//! - **Join Operators**: An account can join as an operator by depositing a minimum stake amount. +//! This stake is reserved and ensures that the operator has a stake in the network. +//! - **Leave Operators**: Operators can leave the network by scheduling a leave request. This +//! request is subject to a delay, during which the operator's status changes to 'Leaving'. +//! - **Stake More**: Operators can increase their stake to strengthen their stake in the network. +//! - **Stake Less**: Operators can schedule a stake reduction request, which is executed after a +//! delay. +//! - **Go Offline/Online**: Operators can change their status to offline if they need to +//! temporarily stop participating in the network, and can come back online when ready. +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod mock_evm; + +#[cfg(test)] +mod tests; + +pub mod weights; + +// #[cfg(feature = "runtime-benchmarks")] +// TODO(@1xstj): Fix benchmarking and re-enable +// mod benchmarking; + +pub mod functions; +pub mod traits; +pub mod types; +pub use functions::*; + +#[frame_support::pallet] +pub mod pallet { + use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; + use frame_support::{ + pallet_prelude::*, + traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, + PalletId, + }; + use frame_system::pallet_prelude::*; + use scale_info::TypeInfo; + use sp_core::H160; + use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; + use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; + use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex}; + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The currency type used for managing balances. + type Currency: Currency + + ReservableCurrency + + LockableCurrency; + + /// Type representing the unique ID of an asset. + type AssetId: Parameter + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + Default + + MaxEncodedLen + + Encode + + Decode + + TypeInfo; + + /// Type representing the unique ID of a vault. + type VaultId: Parameter + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + Default + + MaxEncodedLen + + TypeInfo; + + /// The maximum number of blueprints a delegator can have in Fixed mode. + #[pallet::constant] + type MaxDelegatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + + /// The maximum number of blueprints an operator can support. + #[pallet::constant] + type MaxOperatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + + /// The maximum number of withdraw requests a delegator can have. + #[pallet::constant] + type MaxWithdrawRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + + /// The maximum number of delegations a delegator can have. + #[pallet::constant] + type MaxDelegations: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + + /// The maximum number of unstake requests a delegator can have. + #[pallet::constant] + type MaxUnstakeRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; + + /// The minimum amount of stake required for an operator. + #[pallet::constant] + type MinOperatorBondAmount: Get>; + + /// The minimum amount of stake required for a delegate. + #[pallet::constant] + type MinDelegateAmount: Get>; + + /// The duration for which the stake is locked. + #[pallet::constant] + type BondDuration: Get; + + /// The service manager that manages active services. + type ServiceManager: ServiceManager>; + + /// Number of rounds that operators remain bonded before the exit request is executable. + #[pallet::constant] + type LeaveOperatorsDelay: Get; + + /// Number of rounds operator requests to decrease self-stake must wait to be executable. + #[pallet::constant] + type OperatorBondLessDelay: Get; + + /// Number of rounds that delegators remain bonded before the exit request is executable. + #[pallet::constant] + type LeaveDelegatorsDelay: Get; + + /// Number of rounds that delegation unstake requests must wait before being executable. + #[pallet::constant] + type DelegationBondLessDelay: Get; + + /// The fungibles trait used for managing fungible assets. + type Fungibles: fungibles::Inspect> + + fungibles::Mutate; + + /// The pallet's account ID. + type PalletId: Get; + + /// The origin with privileged access + type ForceOrigin: EnsureOrigin; + + /// The address that receives slashed funds + type SlashedAmountRecipient: Get; + + /// A type that implements the `EvmRunner` trait for the execution of EVM + /// transactions. + type EvmRunner: tangle_primitives::services::EvmRunner; + + /// A type that implements the `EvmGasWeightMapping` trait for the conversion of EVM gas to + /// Substrate weight and vice versa. + type EvmGasWeightMapping: tangle_primitives::services::EvmGasWeightMapping; + + /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address + type EvmAddressMapping: tangle_primitives::services::EvmAddressMapping; + + /// A type representing the weights required by the dispatchables of this pallet. + type WeightInfo: crate::weights::WeightInfo; + } + + /// The pallet struct. + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + /// Storage for operator information. + #[pallet::storage] + #[pallet::getter(fn operator_info)] + pub type Operators = + StorageMap<_, Blake2_128Concat, T::AccountId, OperatorMetadataOf>; + + /// Storage for the current round. + #[pallet::storage] + #[pallet::getter(fn current_round)] + pub type CurrentRound = StorageValue<_, RoundIndex, ValueQuery>; + + /// Snapshot of collator delegation stake at the start of the round. + #[pallet::storage] + #[pallet::getter(fn at_stake)] + pub type AtStake = StorageDoubleMap< + _, + Blake2_128Concat, + RoundIndex, + Blake2_128Concat, + T::AccountId, + OperatorSnapshotOf, + OptionQuery, + >; + + /// Storage for delegator information. + #[pallet::storage] + #[pallet::getter(fn delegators)] + pub type Delegators = + StorageMap<_, Blake2_128Concat, T::AccountId, DelegatorMetadataOf>; + + #[pallet::storage] + #[pallet::getter(fn reward_vaults)] + /// Storage for the reward vaults + pub type RewardVaults = + StorageMap<_, Blake2_128Concat, T::VaultId, Vec>, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn asset_reward_vault_lookup)] + /// Storage for the reward vaults + pub type AssetLookupRewardVaults = + StorageMap<_, Blake2_128Concat, Asset, T::VaultId, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn reward_config)] + /// Storage for the reward configuration, which includes APY, cap for assets, and whitelisted + /// blueprints. + pub type RewardConfigStorage = + StorageValue<_, RewardConfig>, OptionQuery>; + + /// Events emitted by the pallet. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An operator has joined. + OperatorJoined { who: T::AccountId }, + /// An operator has scheduled to leave. + OperatorLeavingScheduled { who: T::AccountId }, + /// An operator has cancelled their leave request. + OperatorLeaveCancelled { who: T::AccountId }, + /// An operator has executed their leave request. + OperatorLeaveExecuted { who: T::AccountId }, + /// An operator has increased their stake. + OperatorBondMore { who: T::AccountId, additional_bond: BalanceOf }, + /// An operator has scheduled to decrease their stake. + OperatorBondLessScheduled { who: T::AccountId, unstake_amount: BalanceOf }, + /// An operator has executed their stake decrease. + OperatorBondLessExecuted { who: T::AccountId }, + /// An operator has cancelled their stake decrease request. + OperatorBondLessCancelled { who: T::AccountId }, + /// An operator has gone offline. + OperatorWentOffline { who: T::AccountId }, + /// An operator has gone online. + OperatorWentOnline { who: T::AccountId }, + /// A deposit has been made. + Deposited { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, + /// An withdraw has been scheduled. + Scheduledwithdraw { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, + /// An withdraw has been executed. + Executedwithdraw { who: T::AccountId }, + /// An withdraw has been cancelled. + Cancelledwithdraw { who: T::AccountId }, + /// A delegation has been made. + Delegated { + who: T::AccountId, + operator: T::AccountId, + amount: BalanceOf, + asset_id: Asset, + }, + /// A delegator unstake request has been scheduled. + ScheduledDelegatorBondLess { + who: T::AccountId, + operator: T::AccountId, + amount: BalanceOf, + asset_id: Asset, + }, + /// A delegator unstake request has been executed. + ExecutedDelegatorBondLess { who: T::AccountId }, + /// A delegator unstake request has been cancelled. + CancelledDelegatorBondLess { who: T::AccountId }, + /// Event emitted when an incentive APY and cap are set for a reward vault + IncentiveAPYAndCapSet { vault_id: T::VaultId, apy: sp_runtime::Percent, cap: BalanceOf }, + /// Event emitted when a blueprint is whitelisted for rewards + BlueprintWhitelisted { blueprint_id: u32 }, + /// Asset has been updated to reward vault + AssetUpdatedInVault { + who: T::AccountId, + vault_id: T::VaultId, + asset_id: Asset, + action: AssetAction, + }, + /// Operator has been slashed + OperatorSlashed { who: T::AccountId, amount: BalanceOf }, + /// Delegator has been slashed + DelegatorSlashed { who: T::AccountId, amount: BalanceOf }, + /// EVM execution reverted with a reason. + EvmReverted { from: H160, to: H160, data: Vec, reason: Vec }, + } + + /// Errors emitted by the pallet. + #[pallet::error] + pub enum Error { + /// The account is already an operator. + AlreadyOperator, + /// The stake amount is too low. + BondTooLow, + /// The account is not an operator. + NotAnOperator, + /// The account cannot exit. + CannotExit, + /// The operator is already leaving. + AlreadyLeaving, + /// The account is not leaving as an operator. + NotLeavingOperator, + /// The round does not match the scheduled leave round. + NotLeavingRound, + /// Leaving round not reached + LeavingRoundNotReached, + /// There is no scheduled unstake request. + NoScheduledBondLess, + /// The unstake request is not satisfied. + BondLessRequestNotSatisfied, + /// The operator is not active. + NotActiveOperator, + /// The operator is not offline. + NotOfflineOperator, + /// The account is already a delegator. + AlreadyDelegator, + /// The account is not a delegator. + NotDelegator, + /// A withdraw request already exists. + WithdrawRequestAlreadyExists, + /// The account has insufficient balance. + InsufficientBalance, + /// There is no withdraw request. + NoWithdrawRequest, + /// There is no unstake request. + NoBondLessRequest, + /// The unstake request is not ready. + BondLessNotReady, + /// A unstake request already exists. + BondLessRequestAlreadyExists, + /// There are active services using the asset. + ActiveServicesUsingAsset, + /// There is not active delegation + NoActiveDelegation, + /// The asset is not whitelisted + AssetNotWhitelisted, + /// The origin is not authorized to perform this action + NotAuthorized, + /// Maximum number of blueprints exceeded + MaxBlueprintsExceeded, + /// The asset ID is not found + AssetNotFound, + /// The blueprint ID is already whitelisted + BlueprintAlreadyWhitelisted, + /// No withdraw requests found + NowithdrawRequests, + /// No matching withdraw reqests found + NoMatchingwithdrawRequest, + /// Asset already exists in a reward vault + AssetAlreadyInVault, + /// Asset not found in reward vault + AssetNotInVault, + /// The reward vault does not exist + VaultNotFound, + /// Error returned when trying to add a blueprint ID that already exists. + DuplicateBlueprintId, + /// Error returned when trying to remove a blueprint ID that doesn't exist. + BlueprintIdNotFound, + /// Error returned when trying to add/remove blueprint IDs while not in Fixed mode. + NotInFixedMode, + /// Error returned when the maximum number of delegations is exceeded. + MaxDelegationsExceeded, + /// Error returned when the maximum number of unstake requests is exceeded. + MaxUnstakeRequestsExceeded, + /// Error returned when the maximum number of withdraw requests is exceeded. + MaxWithdrawRequestsExceeded, + /// Deposit amount overflow + DepositOverflow, + /// Unstake underflow + UnstakeAmountTooLarge, + /// Overflow while adding stake + StakeOverflow, + /// Underflow while reducing stake + InsufficientStakeRemaining, + /// APY exceeds maximum allowed by the extrinsic + APYExceedsMaximum, + /// Cap cannot be zero + CapCannotBeZero, + /// Cap exceeds total supply of asset + CapExceedsTotalSupply, + /// An unstake request is already pending + PendingUnstakeRequestExists, + /// The blueprint is not selected + BlueprintNotSelected, + /// Erc20 transfer failed + ERC20TransferFailed, + /// EVM encode error + EVMAbiEncode, + /// EVM decode error + EVMAbiDecode, + } + + /// Hooks for the pallet. + #[pallet::hooks] + impl Hooks> for Pallet {} + + /// The callable functions (extrinsics) of the pallet. + #[pallet::call] + impl Pallet { + /// Allows an account to join as an operator by providing a stake. + #[pallet::call_index(0)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn join_operators(origin: OriginFor, bond_amount: BalanceOf) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::handle_deposit_and_create_operator(who.clone(), bond_amount)?; + Self::deposit_event(Event::OperatorJoined { who }); + Ok(()) + } + + /// Schedules an operator to leave. + #[pallet::call_index(1)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn schedule_leave_operators(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_leave_operator(&who)?; + Self::deposit_event(Event::OperatorLeavingScheduled { who }); + Ok(()) + } + + /// Cancels a scheduled leave for an operator. + #[pallet::call_index(2)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn cancel_leave_operators(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_cancel_leave_operator(&who)?; + Self::deposit_event(Event::OperatorLeaveCancelled { who }); + Ok(()) + } + + /// Executes a scheduled leave for an operator. + #[pallet::call_index(3)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn execute_leave_operators(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_execute_leave_operators(&who)?; + Self::deposit_event(Event::OperatorLeaveExecuted { who }); + Ok(()) + } + + /// Allows an operator to increase their stake. + #[pallet::call_index(4)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn operator_bond_more( + origin: OriginFor, + additional_bond: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_operator_bond_more(&who, additional_bond)?; + Self::deposit_event(Event::OperatorBondMore { who, additional_bond }); + Ok(()) + } + + /// Schedules an operator to decrease their stake. + #[pallet::call_index(5)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn schedule_operator_unstake( + origin: OriginFor, + unstake_amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_schedule_operator_unstake(&who, unstake_amount)?; + Self::deposit_event(Event::OperatorBondLessScheduled { who, unstake_amount }); + Ok(()) + } + + /// Executes a scheduled stake decrease for an operator. + #[pallet::call_index(6)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn execute_operator_unstake(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_execute_operator_unstake(&who)?; + Self::deposit_event(Event::OperatorBondLessExecuted { who }); + Ok(()) + } + + /// Cancels a scheduled stake decrease for an operator. + #[pallet::call_index(7)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn cancel_operator_unstake(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_cancel_operator_unstake(&who)?; + Self::deposit_event(Event::OperatorBondLessCancelled { who }); + Ok(()) + } + + /// Allows an operator to go offline. + #[pallet::call_index(8)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn go_offline(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_go_offline(&who)?; + Self::deposit_event(Event::OperatorWentOffline { who }); + Ok(()) + } + + /// Allows an operator to go online. + #[pallet::call_index(9)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn go_online(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_go_online(&who)?; + Self::deposit_event(Event::OperatorWentOnline { who }); + Ok(()) + } + + /// Allows a user to deposit an asset. + #[pallet::call_index(10)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn deposit( + origin: OriginFor, + asset_id: Asset, + amount: BalanceOf, + evm_address: Option, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_deposit(who.clone(), asset_id, amount, evm_address)?; + Self::deposit_event(Event::Deposited { who, amount, asset_id }); + Ok(()) + } + + /// Schedules an withdraw request. + #[pallet::call_index(11)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn schedule_withdraw( + origin: OriginFor, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_schedule_withdraw(who.clone(), asset_id, amount)?; + Self::deposit_event(Event::Scheduledwithdraw { who, amount, asset_id }); + Ok(()) + } + + /// Executes a scheduled withdraw request. + #[pallet::call_index(12)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn execute_withdraw(origin: OriginFor, evm_address: Option) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_execute_withdraw(who.clone(), evm_address)?; + Self::deposit_event(Event::Executedwithdraw { who }); + Ok(()) + } + + /// Cancels a scheduled withdraw request. + #[pallet::call_index(13)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn cancel_withdraw( + origin: OriginFor, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_cancel_withdraw(who.clone(), asset_id, amount)?; + Self::deposit_event(Event::Cancelledwithdraw { who }); + Ok(()) + } + + /// Allows a user to delegate an amount of an asset to an operator. + #[pallet::call_index(14)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn delegate( + origin: OriginFor, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + blueprint_selection: DelegatorBlueprintSelection, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_delegate( + who.clone(), + operator.clone(), + asset_id, + amount, + blueprint_selection, + )?; + Self::deposit_event(Event::Delegated { who, operator, asset_id, amount }); + Ok(()) + } + + /// Schedules a request to reduce a delegator's stake. + #[pallet::call_index(15)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn schedule_delegator_unstake( + origin: OriginFor, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_schedule_delegator_unstake( + who.clone(), + operator.clone(), + asset_id, + amount, + )?; + Self::deposit_event(Event::ScheduledDelegatorBondLess { + who, + asset_id, + operator, + amount, + }); + Ok(()) + } + + /// Executes a scheduled request to reduce a delegator's stake. + #[pallet::call_index(16)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn execute_delegator_unstake(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_execute_delegator_unstake(who.clone())?; + Self::deposit_event(Event::ExecutedDelegatorBondLess { who }); + Ok(()) + } + + /// Cancels a scheduled request to reduce a delegator's stake. + #[pallet::call_index(17)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn cancel_delegator_unstake( + origin: OriginFor, + operator: T::AccountId, + asset_id: Asset, + amount: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::process_cancel_delegator_unstake(who.clone(), operator, asset_id, amount)?; + Self::deposit_event(Event::CancelledDelegatorBondLess { who }); + Ok(()) + } + + /// Sets the APY and cap for a specific asset. + /// The APY is the annual percentage yield that the asset will earn. + /// The cap is the amount of assets required to be deposited to distribute the entire APY. + /// The APY is capped at 10% and will require runtime upgrade to change. + /// + /// While the cap is not met, the APY distributed will be `amount_deposited / cap * APY`. + #[pallet::call_index(18)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn set_incentive_apy_and_cap( + origin: OriginFor, + vault_id: T::VaultId, + apy: sp_runtime::Percent, + cap: BalanceOf, + ) -> DispatchResult { + // Ensure that the origin is authorized + T::ForceOrigin::ensure_origin(origin)?; + + // Validate APY is not greater than 10% + ensure!(apy <= sp_runtime::Percent::from_percent(10), Error::::APYExceedsMaximum); + + // Validate cap is not zero + ensure!(!cap.is_zero(), Error::::CapCannotBeZero); + + // Initialize the reward config if not already initialized + RewardConfigStorage::::mutate(|maybe_config| { + let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { + configs: BTreeMap::new(), + whitelisted_blueprint_ids: Vec::new(), + }); + + config.configs.insert(vault_id, RewardConfigForAssetVault { apy, cap }); + + *maybe_config = Some(config); + }); + + // Emit an event + Self::deposit_event(Event::IncentiveAPYAndCapSet { vault_id, apy, cap }); + + Ok(()) + } + + /// Whitelists a blueprint for rewards. + #[pallet::call_index(19)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn whitelist_blueprint_for_rewards( + origin: OriginFor, + blueprint_id: u32, + ) -> DispatchResult { + // Ensure that the origin is authorized + T::ForceOrigin::ensure_origin(origin)?; + + // Initialize the reward config if not already initialized + RewardConfigStorage::::mutate(|maybe_config| { + let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { + configs: BTreeMap::new(), + whitelisted_blueprint_ids: Vec::new(), + }); + + if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { + config.whitelisted_blueprint_ids.push(blueprint_id); + } + + *maybe_config = Some(config); + }); + + // Emit an event + Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); + + Ok(()) + } + + /// Manage asset id to vault rewards + #[pallet::call_index(20)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn manage_asset_in_vault( + origin: OriginFor, + vault_id: T::VaultId, + asset_id: Asset, + action: AssetAction, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + match action { + AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, + AssetAction::Remove => Self::remove_asset_from_vault(&vault_id, &asset_id)?, + } + + Self::deposit_event(Event::AssetUpdatedInVault { who, vault_id, asset_id, action }); + + Ok(()) + } + + /// Adds a blueprint ID to a delegator's selection. + #[pallet::call_index(22)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn add_blueprint_id(origin: OriginFor, blueprint_id: BlueprintId) -> DispatchResult { + let who = ensure_signed(origin)?; + let mut metadata = Self::delegators(&who).ok_or(Error::::NotDelegator)?; + + // Update blueprint selection for all delegations + for delegation in metadata.delegations.iter_mut() { + match delegation.blueprint_selection { + DelegatorBlueprintSelection::Fixed(ref mut ids) => { + ensure!(!ids.contains(&blueprint_id), Error::::DuplicateBlueprintId); + ids.try_push(blueprint_id) + .map_err(|_| Error::::MaxBlueprintsExceeded)?; + }, + _ => return Err(Error::::NotInFixedMode.into()), + } + } + + Delegators::::insert(&who, metadata); + Ok(()) + } + + /// Removes a blueprint ID from a delegator's selection. + #[pallet::call_index(23)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn remove_blueprint_id( + origin: OriginFor, + blueprint_id: BlueprintId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let mut metadata = Self::delegators(&who).ok_or(Error::::NotDelegator)?; + + // Update blueprint selection for all delegations + for delegation in metadata.delegations.iter_mut() { + match delegation.blueprint_selection { + DelegatorBlueprintSelection::Fixed(ref mut ids) => { + let pos = ids + .iter() + .position(|&id| id == blueprint_id) + .ok_or(Error::::BlueprintIdNotFound)?; + ids.remove(pos); + }, + _ => return Err(Error::::NotInFixedMode.into()), + } + } + + Delegators::::insert(&who, metadata); + Ok(()) + } + } +} diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs new file mode 100644 index 00000000..1314749b --- /dev/null +++ b/pallets/rewards/src/mock.rs @@ -0,0 +1,617 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use super::*; +use crate::{self as pallet_multi_asset_delegation}; +use ethabi::Uint; +use frame_election_provider_support::{ + bounds::{ElectionBounds, ElectionBoundsBuilder}, + onchain, SequentialPhragmen, +}; +use frame_support::{ + construct_runtime, derive_impl, + pallet_prelude::{Hooks, Weight}, + parameter_types, + traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, + PalletId, +}; +use mock_evm::MockedEvmRunner; +use pallet_evm::GasWeightMapping; +use pallet_session::historical as pallet_session_historical; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde_json::json; +use sp_core::{sr25519, H160}; +use sp_keyring::AccountKeyring; +use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; +use sp_runtime::{ + testing::UintAuthorityId, + traits::{ConvertInto, IdentityLookup}, + AccountId32, BuildStorage, Perbill, +}; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; + +use core::ops::Mul; +use std::{collections::BTreeMap, sync::Arc}; + +pub type AccountId = AccountId32; +pub type Balance = u128; +type Nonce = u32; +pub type AssetId = u128; + +#[frame_support::derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Nonce = Nonce; + type RuntimeCall = RuntimeCall; + type Hash = sp_core::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = (); + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = (); + type FreezeIdentifier = (); + type MaxFreezes = (); +} + +parameter_types! { + pub ElectionBoundsOnChain: ElectionBounds = ElectionBoundsBuilder::default() + .voters_count(5_000.into()).targets_count(1_250.into()).build(); + pub ElectionBoundsMultiPhase: ElectionBounds = ElectionBoundsBuilder::default() + .voters_count(10_000.into()).targets_count(1_500.into()).build(); +} + +impl pallet_session::historical::Config for Runtime { + type FullIdentification = AccountId; + type FullIdentificationOf = ConvertInto; +} + +sp_runtime::impl_opaque_keys! { + pub struct MockSessionKeys { + pub other: MockSessionHandler, + } +} + +pub struct MockSessionHandler; +impl OneSessionHandler for MockSessionHandler { + type Key = UintAuthorityId; + + fn on_genesis_session<'a, I: 'a>(_: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_: bool, _: I, _: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_disabled(_validator_index: u32) {} +} + +impl sp_runtime::BoundToRuntimeAppPublic for MockSessionHandler { + type Public = UintAuthorityId; +} + +pub struct MockSessionManager; + +impl pallet_session::SessionManager for MockSessionManager { + fn end_session(_: sp_staking::SessionIndex) {} + fn start_session(_: sp_staking::SessionIndex) {} + fn new_session(idx: sp_staking::SessionIndex) -> Option> { + if idx == 0 || idx == 1 || idx == 2 { + Some(vec![mock_pub_key(1), mock_pub_key(2), mock_pub_key(3), mock_pub_key(4)]) + } else { + None + } + } +} + +parameter_types! { + pub const Period: u64 = 1; + pub const Offset: u64 = 0; +} + +impl pallet_session::Config for Runtime { + type SessionManager = MockSessionManager; + type Keys = MockSessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionHandler = (MockSessionHandler,); + type RuntimeEvent = RuntimeEvent; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type WeightInfo = (); +} + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); + type MaxWinners = ConstU32<100>; + type Bounds = ElectionBoundsOnChain; +} + +/// Upper limit on the number of NPOS nominations. +const MAX_QUOTA_NOMINATIONS: u32 = 16; + +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type CurrencyBalance = ::Balance; + type UnixTime = pallet_timestamp::Pallet; + type CurrencyToVote = (); + type RewardRemainder = (); + type RuntimeEvent = RuntimeEvent; + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type AdminOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = (); + type EraPayout = (); + type NextNewSession = Session; + type MaxExposurePageSize = ConstU32<64>; + type MaxControllersInDeprecationBatch = ConstU32<100>; + type ElectionProvider = onchain::OnChainExecution; + type GenesisElectionProvider = Self::ElectionProvider; + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type TargetList = pallet_staking::UseValidatorsMap; + type MaxUnlockingChunks = ConstU32<32>; + type HistoryDepth = ConstU32<84>; + type EventListeners = (); + type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; + type NominationsQuota = pallet_staking::FixedNominationsQuota; + type WeightInfo = (); + type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; +} + +parameter_types! { + pub const ServicesEVMAddress: H160 = H160([0x11; 20]); +} + +pub struct PalletEVMGasWeightMapping; + +impl EvmGasWeightMapping for PalletEVMGasWeightMapping { + fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { + pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) + } + + fn weight_to_gas(weight: Weight) -> u64 { + pallet_evm::FixedGasWeightMapping::::weight_to_gas(weight) + } +} + +pub struct PalletEVMAddressMapping; + +impl EvmAddressMapping for PalletEVMAddressMapping { + fn into_account_id(address: H160) -> AccountId { + use pallet_evm::AddressMapping; + ::AddressMapping::into_account_id(address) + } + + fn into_address(account_id: AccountId) -> H160 { + H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) + } +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = u128; + type AssetId = AssetId; + type AssetIdParameter = AssetId; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU128<1>; + type AssetAccountDeposit = ConstU128<10>; + type MetadataDepositBase = ConstU128<1>; + type MetadataDepositPerByte = ConstU128<1>; + type ApprovalDeposit = ConstU128<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; +} + +pub struct MockServiceManager; + +impl tangle_primitives::ServiceManager for MockServiceManager { + fn get_active_blueprints_count(_account: &AccountId) -> usize { + // we dont care + Default::default() + } + + fn get_active_services_count(_account: &AccountId) -> usize { + // we dont care + Default::default() + } + + fn can_exit(_account: &AccountId) -> bool { + // Mock logic to determine if the given account can exit + true + } + + fn get_blueprints_by_operator(_account: &AccountId) -> Vec { + todo!(); // we dont care + } +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaxLocks: u32 = 50; + pub const MinOperatorBondAmount: u64 = 10_000; + pub const BondDuration: u32 = 10; + pub PID: PalletId = PalletId(*b"PotStake"); + pub SlashedAmountRecipient : AccountId = AccountKeyring::Alice.into(); + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxOperatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxWithdrawRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxUnstakeRequests: u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegations: u32 = 50; +} + +impl pallet_multi_asset_delegation::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type MinOperatorBondAmount = MinOperatorBondAmount; + type BondDuration = BondDuration; + type ServiceManager = MockServiceManager; + type LeaveOperatorsDelay = ConstU32<10>; + type OperatorBondLessDelay = ConstU32<1>; + type LeaveDelegatorsDelay = ConstU32<1>; + type DelegationBondLessDelay = ConstU32<5>; + type MinDelegateAmount = ConstU128<100>; + type Fungibles = Assets; + type AssetId = AssetId; + type VaultId = AssetId; + type ForceOrigin = frame_system::EnsureRoot; + type PalletId = PID; + type MaxDelegatorBlueprints = MaxDelegatorBlueprints; + type MaxOperatorBlueprints = MaxOperatorBlueprints; + type MaxWithdrawRequests = MaxWithdrawRequests; + type MaxUnstakeRequests = MaxUnstakeRequests; + type MaxDelegations = MaxDelegations; + type SlashedAmountRecipient = SlashedAmountRecipient; + type EvmRunner = MockedEvmRunner; + type EvmGasWeightMapping = PalletEVMGasWeightMapping; + type EvmAddressMapping = PalletEVMAddressMapping; + type WeightInfo = (); +} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Assets: pallet_assets, + MultiAssetDelegation: pallet_multi_asset_delegation, + EVM: pallet_evm, + Ethereum: pallet_ethereum, + Session: pallet_session, + Staking: pallet_staking, + Historical: pallet_session_historical, + } +); + +pub struct ExtBuilder; + +impl Default for ExtBuilder { + fn default() -> Self { + ExtBuilder + } +} + +pub fn mock_pub_key(id: u8) -> AccountId { + sr25519::Public::from_raw([id; 32]).into() +} + +pub fn mock_address(id: u8) -> H160 { + H160::from_slice(&[id; 20]) +} + +pub fn account_id_to_address(account_id: AccountId) -> H160 { + H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) +} + +// pub fn address_to_account_id(address: H160) -> AccountId { +// use pallet_evm::AddressMapping; +// ::AddressMapping::into_account_id(address) +// } + +pub fn new_test_ext() -> sp_io::TestExternalities { + new_test_ext_raw_authorities() +} + +pub const USDC_ERC20: H160 = H160([0x23; 20]); +// pub const USDC: AssetId = 1; +// pub const WETH: AssetId = 2; +// pub const WBTC: AssetId = 3; +pub const VDOT: AssetId = 4; + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + let authorities: Vec = vec![ + AccountKeyring::Alice.into(), + AccountKeyring::Bob.into(), + AccountKeyring::Charlie.into(), + ]; + let mut balances: Vec<_> = authorities.iter().map(|i| (i.clone(), 200_000_u128)).collect(); + + // Add test accounts with enough balance + let test_accounts = vec![ + AccountKeyring::Dave.into(), + AccountKeyring::Eve.into(), + MultiAssetDelegation::pallet_account(), + ]; + balances.extend(test_accounts.iter().map(|i: &AccountId| (i.clone(), 1_000_000_u128))); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + let mut evm_accounts = BTreeMap::new(); + + for i in 1..=authorities.len() { + evm_accounts.insert( + mock_address(i as u8), + fp_evm::GenesisAccount { + code: vec![], + storage: Default::default(), + nonce: Default::default(), + balance: Uint::from(1_000).mul(Uint::from(10).pow(Uint::from(18))), + }, + ); + } + + for a in &authorities { + evm_accounts.insert( + account_id_to_address(a.clone()), + fp_evm::GenesisAccount { + code: vec![], + storage: Default::default(), + nonce: Default::default(), + balance: Uint::from(1_000).mul(Uint::from(10).pow(Uint::from(18))), + }, + ); + } + + let evm_config = + pallet_evm::GenesisConfig:: { accounts: evm_accounts, ..Default::default() }; + + evm_config.assimilate_storage(&mut t).unwrap(); + + // let assets_config = pallet_assets::GenesisConfig:: { + // assets: vec![ + // (USDC, authorities[0].clone(), true, 100_000), // 1 cent. + // (WETH, authorities[1].clone(), true, 100), // 100 wei. + // (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. + // (VDOT, authorities[0].clone(), true, 100), + // ], + // metadata: vec![ + // (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), + // (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), + // (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), + // (VDOT, Vec::from(b"VeChain"), Vec::from(b"VDOT"), 18), + // ], + // accounts: vec![ + // (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), + // // + // (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), + // // + // (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), + // (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), + // (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), + + // // + // (VDOT, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), + // (VDOT, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), + // (VDOT, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), + // ], + // next_asset_id: Some(4), + // }; + + // assets_config.assimilate_storage(&mut t).unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); + ext.execute_with(|| System::set_block_number(1)); + ext.execute_with(|| { + System::set_block_number(1); + Session::on_initialize(1); + >::on_initialize(1); + + let call = ::EvmRunner::call( + MultiAssetDelegation::pallet_evm_account(), + USDC_ERC20, + serde_json::from_value::(json!({ + "name": "initialize", + "inputs": [ + { + "name": "name_", + "type": "string", + "internalType": "string" + }, + { + "name": "symbol_", + "type": "string", + "internalType": "string" + }, + { + "name": "decimals_", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + })) + .unwrap() + .encode_input(&[ + ethabi::Token::String("USD Coin".to_string()), + ethabi::Token::String("USDC".to_string()), + ethabi::Token::Uint(6.into()), + ]) + .unwrap(), + Default::default(), + 300_000, + true, + false, + ); + + assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); + // Mint + for i in 1..=authorities.len() { + let call = ::EvmRunner::call( + MultiAssetDelegation::pallet_evm_account(), + USDC_ERC20, + serde_json::from_value::(json!({ + "name": "mint", + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + })) + .unwrap() + .encode_input(&[ + ethabi::Token::Address(mock_address(i as u8).into()), + ethabi::Token::Uint(Uint::from(100_000).mul(Uint::from(10).pow(Uint::from(6)))), + ]) + .unwrap(), + Default::default(), + 300_000, + true, + false, + ); + + assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); + } + }); + + ext +} + +#[macro_export] +macro_rules! evm_log { + () => { + fp_evm::Log { address: H160::zero(), topics: vec![], data: vec![] } + }; + + ($contract:expr) => { + fp_evm::Log { address: $contract, topics: vec![], data: vec![] } + }; + + ($contract:expr, $topic:expr) => { + fp_evm::Log { + address: $contract, + topics: vec![sp_core::keccak_256($topic).into()], + data: vec![], + } + }; +} + +// /// Asserts that the EVM logs are as expected. +// #[track_caller] +// pub fn assert_evm_logs(expected: &[fp_evm::Log]) { +// assert_evm_events_contains(expected.iter().cloned().collect()) +// } + +// /// Asserts that the EVM events are as expected. +// #[track_caller] +// fn assert_evm_events_contains(expected: Vec) { +// let actual: Vec = System::events() +// .iter() +// .filter_map(|e| match e.event { +// RuntimeEvent::EVM(pallet_evm::Event::Log { ref log }) => Some(log.clone()), +// _ => None, +// }) +// .collect(); + +// // Check if `expected` is a subset of `actual` +// let mut any_matcher = false; +// for evt in expected { +// if !actual.contains(&evt) { +// panic!("Events don't match\nactual: {actual:?}\nexpected: {evt:?}"); +// } else { +// any_matcher = true; +// } +// } + +// // At least one event should be present +// if !any_matcher { +// panic!("No events found"); +// } +// } diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs new file mode 100644 index 00000000..f9d9646a --- /dev/null +++ b/pallets/rewards/src/mock_evm.rs @@ -0,0 +1,342 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use crate as pallet_multi_asset_delegation; +use crate::mock::{ + AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, +}; +use fp_evm::FeeCalculator; +use frame_support::{ + parameter_types, + traits::{Currency, FindAuthor, OnUnbalanced}, + weights::Weight, + PalletId, +}; +use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; +use pallet_evm::{ + EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, OnChargeEVMTransaction, +}; +use sp_core::{keccak_256, ConstU32, H160, H256, U256}; +use sp_runtime::{ + traits::{BlakeTwo256, DispatchInfoOf, Dispatchable}, + transaction_validity::{TransactionValidity, TransactionValidityError}, + ConsensusEngineId, +}; + +use pallet_evm_precompile_blake2::Blake2F; +use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +use precompile_utils::precompile_set::{ + AcceptDelegateCall, AddressU64, CallableByContract, CallableByPrecompile, PrecompileAt, + PrecompileSetBuilder, PrecompilesInRangeInclusive, +}; + +type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile); + +#[precompile_utils::precompile_name_from_address] +pub type DefaultPrecompiles = ( + // Ethereum precompiles: + PrecompileAt, ECRecover, EthereumPrecompilesChecks>, + PrecompileAt, Sha256, EthereumPrecompilesChecks>, + PrecompileAt, Ripemd160, EthereumPrecompilesChecks>, + PrecompileAt, Identity, EthereumPrecompilesChecks>, + PrecompileAt, Modexp, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Add, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Mul, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Pairing, EthereumPrecompilesChecks>, + PrecompileAt, Blake2F, EthereumPrecompilesChecks>, + PrecompileAt, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>, + PrecompileAt, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>, +); + +pub type TanglePrecompiles = PrecompileSetBuilder< + R, + (PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<2095>), DefaultPrecompiles>,), +>; + +parameter_types! { + pub const MinimumPeriod: u64 = 6000 / 2; + + pub PrecompilesValue: TanglePrecompiles = TanglePrecompiles::<_>::new(); +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + (1.into(), Weight::zero()) + } +} + +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(address_build(0).address) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub const TransactionByteFee: u64 = 1; + pub const ChainId: u64 = 42; + pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); +} + +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(_fees_then_tips: impl Iterator) { + // whatever + } +} +pub struct FreeEVMExecution; + +impl OnChargeEVMTransaction for FreeEVMExecution { + type LiquidityInfo = (); + + fn withdraw_fee( + _who: &H160, + _fee: U256, + ) -> Result> { + Ok(()) + } + + fn correct_and_deposit_fee( + _who: &H160, + _corrected_fee: U256, + _base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + already_withdrawn + } + + fn pay_priority_fee(_tip: Self::LiquidityInfo) {} +} + +/// Type alias for negative imbalance during fees +type RuntimeNegativeImbalance = + ::AccountId>>::NegativeImbalance; + +/// See: [`pallet_evm::EVMCurrencyAdapter`] +pub struct CustomEVMCurrencyAdapter; + +impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { + type LiquidityInfo = Option; + + fn withdraw_fee( + who: &H160, + fee: U256, + ) -> Result> { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet multi_asset_delegation account free to use + if who == &pallet_multi_asset_delegation_address { + return Ok(None); + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::withdraw_fee(who, fee) + } + + fn correct_and_deposit_fee( + who: &H160, + corrected_fee: U256, + base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet multi_asset_delegation account free to use + if who == &pallet_multi_asset_delegation_address { + return already_withdrawn; + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) + } + + fn pay_priority_fee(tip: Self::LiquidityInfo) { + as OnChargeEVMTransaction< + Runtime, + >>::pay_priority_fee(tip) + } +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = EthereumBlockHashMapping; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = HashedAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = TanglePrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = ChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = CustomEVMCurrencyAdapter; + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, + _ => None, + } + } +} + +pub struct MockedEvmRunner; + +impl tangle_primitives::services::EvmRunner for MockedEvmRunner { + type Error = pallet_evm::Error; + + fn call( + source: sp_core::H160, + target: sp_core::H160, + input: Vec, + value: sp_core::U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result> { + let max_fee_per_gas = FixedGasPrice::min_gas_price().0; + let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); + let nonce = None; + let access_list = Default::default(); + let weight_limit = None; + let proof_size_base_cost = None; + <::Runner as pallet_evm::Runner>::call( + source, + target, + input, + value, + gas_limit, + Some(max_fee_per_gas), + Some(max_priority_fee_per_gas), + nonce, + access_list, + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + ::config(), + ) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) + } +} + +pub struct AccountInfo { + pub address: H160, +} + +pub fn address_build(seed: u8) -> AccountInfo { + let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); + let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); + let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; + let address = H160::from(H256::from(keccak_256(public_key))); + + AccountInfo { address } +} diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs new file mode 100644 index 00000000..376a1b43 --- /dev/null +++ b/pallets/rewards/src/tests.rs @@ -0,0 +1,24 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{mock::*, tests::RuntimeEvent}; + +pub mod delegate; +pub mod deposit; +pub mod operator; +pub mod session_manager; + +use crate::tests::deposit::{create_and_mint_tokens, mint_tokens}; diff --git a/pallets/rewards/src/tests/delegate.rs b/pallets/rewards/src/tests/delegate.rs new file mode 100644 index 00000000..92a7316d --- /dev/null +++ b/pallets/rewards/src/tests/delegate.rs @@ -0,0 +1,539 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use super::*; +use crate::{CurrentRound, Error}; +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::{Alice, Bob}; +use tangle_primitives::services::Asset; + +#[test] +fn delegate_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + create_and_mint_tokens(VDOT, who.clone(), amount); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.deposits.get(&asset_id).is_none()); + assert_eq!(metadata.delegations.len(), 1); + let delegation = &metadata.delegations[0]; + assert_eq!(delegation.operator, operator.clone()); + assert_eq!(delegation.amount, amount); + assert_eq!(delegation.asset_id, asset_id); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount); + assert_eq!(operator_delegation.asset_id, asset_id); + }); +} + +#[test] +fn schedule_delegator_unstake_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit and delegate first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + )); + + // Assert + // Check the delegator metadata + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(!metadata.delegator_unstake_requests.is_empty()); + let request = &metadata.delegator_unstake_requests[0]; + assert_eq!(request.asset_id, asset_id); + assert_eq!(request.amount, amount); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 0); + assert_eq!(operator_metadata.delegations.len(), 0); + }); +} + +#[test] +fn execute_delegator_unstake_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit, delegate and schedule unstake first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + )); + + // Simulate round passing + CurrentRound::::put(10); + + assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed( + who.clone() + ),)); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.delegator_unstake_requests.is_empty()); + assert!(metadata.deposits.get(&asset_id).is_some()); + assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); + }); +} + +#[test] +fn cancel_delegator_unstake_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit, delegate and schedule unstake first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + )); + + // Assert + // Check the delegator metadata + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(!metadata.delegator_unstake_requests.is_empty()); + let request = &metadata.delegator_unstake_requests[0]; + assert_eq!(request.asset_id, asset_id); + assert_eq!(request.amount, amount); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 0); + assert_eq!(operator_metadata.delegations.len(), 0); + + assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount + )); + + // Assert + // Check the delegator metadata + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.delegator_unstake_requests.is_empty()); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount); // Amount added back + assert_eq!(operator_delegation.asset_id, asset_id); + }); +} + +#[test] +fn cancel_delegator_unstake_should_update_already_existing() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit, delegate and schedule unstake first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + 10, + )); + + // Assert + // Check the delegator metadata + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(!metadata.delegator_unstake_requests.is_empty()); + let request = &metadata.delegator_unstake_requests[0]; + assert_eq!(request.asset_id, asset_id); + assert_eq!(request.amount, 10); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount - 10); + assert_eq!(operator_delegation.asset_id, asset_id); + + assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + 10 + )); + + // Assert + // Check the delegator metadata + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.delegator_unstake_requests.is_empty()); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount); // Amount added back + assert_eq!(operator_delegation.asset_id, asset_id); + }); +} + +#[test] +fn delegate_should_fail_if_not_enough_balance() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 10_000; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount - 20, + None + )); + + assert_noop!( + MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + ), + Error::::InsufficientBalance + ); + }); +} + +#[test] +fn schedule_delegator_unstake_should_fail_if_no_delegation() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + + assert_noop!( + MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + ), + Error::::NoActiveDelegation + ); + }); +} + +#[test] +fn execute_delegator_unstake_should_fail_if_not_ready() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit, delegate and schedule unstake first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + assert_noop!( + MultiAssetDelegation::cancel_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount + ), + Error::::NoBondLessRequest + ); + + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + )); + + assert_noop!( + MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who.clone()),), + Error::::BondLessNotReady + ); + }); +} + +#[test] +fn delegate_should_not_create_multiple_on_repeat_delegation() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + let additional_amount = 50; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + create_and_mint_tokens(VDOT, who.clone(), amount + additional_amount); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount + additional_amount, + None + )); + + // Delegate first time + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default() + )); + + // Assert first delegation + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.deposits.get(&asset_id).is_some()); + assert_eq!(metadata.delegations.len(), 1); + let delegation = &metadata.delegations[0]; + assert_eq!(delegation.operator, operator.clone()); + assert_eq!(delegation.amount, amount); + assert_eq!(delegation.asset_id, asset_id); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount); + assert_eq!(operator_delegation.asset_id, asset_id); + + // Delegate additional amount + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + additional_amount, + Default::default() + )); + + // Assert updated delegation + let updated_metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(updated_metadata.deposits.get(&asset_id).is_none()); + assert_eq!(updated_metadata.delegations.len(), 1); + let updated_delegation = &updated_metadata.delegations[0]; + assert_eq!(updated_delegation.operator, operator.clone()); + assert_eq!(updated_delegation.amount, amount + additional_amount); + assert_eq!(updated_delegation.asset_id, asset_id); + + // Check the updated operator metadata + let updated_operator_metadata = + MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(updated_operator_metadata.delegation_count, 1); + assert_eq!(updated_operator_metadata.delegations.len(), 1); + let updated_operator_delegation = &updated_operator_metadata.delegations[0]; + assert_eq!(updated_operator_delegation.delegator, who.clone()); + assert_eq!(updated_operator_delegation.amount, amount + additional_amount); + assert_eq!(updated_operator_delegation.asset_id, asset_id); + }); +} diff --git a/pallets/rewards/src/tests/deposit.rs b/pallets/rewards/src/tests/deposit.rs new file mode 100644 index 00000000..d72c669e --- /dev/null +++ b/pallets/rewards/src/tests/deposit.rs @@ -0,0 +1,509 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{types::DelegatorStatus, CurrentRound, Error}; +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::Bob; +use sp_runtime::ArithmeticError; +use tangle_primitives::services::Asset; + +// helper function +pub fn create_and_mint_tokens( + asset_id: AssetId, + recipient: ::AccountId, + amount: Balance, +) { + assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient.clone(), false, 1)); + assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient.clone()), asset_id, recipient, amount)); +} + +pub fn mint_tokens( + owner: ::AccountId, + asset_id: AssetId, + recipient: ::AccountId, + amount: Balance, +) { + assert_ok!(Assets::mint(RuntimeOrigin::signed(owner), asset_id, recipient, amount)); +} + +#[test] +fn deposit_should_work_for_fungible_asset() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 200; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + assert_eq!( + System::events().last().unwrap().event, + RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { + who: who.clone(), + amount, + asset_id: Asset::Custom(VDOT), + }) + ); + }); +} + +#[test] +fn deposit_should_work_for_evm_asset() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 200; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + assert_eq!( + System::events().last().unwrap().event, + RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { + who: who.clone(), + amount, + asset_id: Asset::Custom(VDOT), + }) + ); + }); +} + +#[test] +fn multiple_deposit_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 200; + + create_and_mint_tokens(VDOT, who.clone(), amount * 4); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + assert_eq!( + System::events().last().unwrap().event, + RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { + who: who.clone(), + amount, + asset_id: Asset::Custom(VDOT), + }) + ); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&(amount * 2))); + assert_eq!( + System::events().last().unwrap().event, + RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { + who: who.clone(), + amount, + asset_id: Asset::Custom(VDOT), + }) + ); + }); +} + +#[test] +fn deposit_should_fail_for_insufficient_balance() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 2000; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + ), + ArithmeticError::Underflow + ); + }); +} + +#[test] +fn deposit_should_fail_for_bond_too_low() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let amount = 50; // Below the minimum stake amount + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + amount, + None + ), + Error::::BondTooLow + ); + }); +} + +#[test] +fn schedule_withdraw_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + + assert_ok!(MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert_eq!(metadata.deposits.get(&asset_id), None); + assert!(!metadata.withdraw_requests.is_empty()); + let request = metadata.withdraw_requests.first().unwrap(); + assert_eq!(request.asset_id, asset_id); + assert_eq!(request.amount, amount); + }); +} + +#[test] +fn schedule_withdraw_should_fail_if_not_delegator() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + assert_noop!( + MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + ), + Error::::NotDelegator + ); + }); +} + +#[test] +fn schedule_withdraw_should_fail_for_insufficient_balance() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 200; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + 100, + None + )); + + assert_noop!( + MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + ), + Error::::InsufficientBalance + ); + }); +} + +#[test] +fn schedule_withdraw_should_fail_if_withdraw_request_exists() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + + // Schedule the first withdraw + assert_ok!(MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + )); + }); +} + +#[test] +fn execute_withdraw_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit and schedule withdraw first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + assert_ok!(MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + )); + + // Simulate round passing + let current_round = 1; + >::put(current_round); + + assert_ok!(MultiAssetDelegation::execute_withdraw( + RuntimeOrigin::signed(who.clone()), + None + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()); + assert!(metadata.unwrap().withdraw_requests.is_empty()); + + // Check event + System::assert_last_event(RuntimeEvent::MultiAssetDelegation( + crate::Event::Executedwithdraw { who: who.clone() }, + )); + }); +} + +#[test] +fn execute_withdraw_should_fail_if_not_delegator() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + + assert_noop!( + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), + Error::::NotDelegator + ); + }); +} + +#[test] +fn execute_withdraw_should_fail_if_no_withdraw_request() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + + assert_noop!( + MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), + Error::::NowithdrawRequests + ); + }); +} + +#[test] +fn execute_withdraw_should_fail_if_withdraw_not_ready() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit and schedule withdraw first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + assert_ok!(MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + )); + + // Simulate round passing but not enough + let current_round = 0; + >::put(current_round); + + // should not actually withdraw anything + assert_ok!(MultiAssetDelegation::execute_withdraw( + RuntimeOrigin::signed(who.clone()), + None + )); + + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(!metadata.withdraw_requests.is_empty()); + }); +} + +#[test] +fn cancel_withdraw_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit and schedule withdraw first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + assert_ok!(MultiAssetDelegation::schedule_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + )); + + assert_ok!(MultiAssetDelegation::cancel_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.withdraw_requests.is_empty()); + assert_eq!(metadata.deposits.get(&asset_id), Some(&amount)); + assert_eq!(metadata.status, DelegatorStatus::Active); + + // Check event + System::assert_last_event(RuntimeEvent::MultiAssetDelegation( + crate::Event::Cancelledwithdraw { who: who.clone() }, + )); + }); +} + +#[test] +fn cancel_withdraw_should_fail_if_not_delegator() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + + assert_noop!( + MultiAssetDelegation::cancel_withdraw( + RuntimeOrigin::signed(who.clone()), + Asset::Custom(VDOT), + 1 + ), + Error::::NotDelegator + ); + }); +} + +#[test] +fn cancel_withdraw_should_fail_if_no_withdraw_request() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), 100); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + + assert_noop!( + MultiAssetDelegation::cancel_withdraw( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount + ), + Error::::NoMatchingwithdrawRequest + ); + }); +} diff --git a/pallets/rewards/src/tests/operator.rs b/pallets/rewards/src/tests/operator.rs new file mode 100644 index 00000000..210b49f4 --- /dev/null +++ b/pallets/rewards/src/tests/operator.rs @@ -0,0 +1,761 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::{ + types::{DelegatorBlueprintSelection::Fixed, OperatorStatus}, + CurrentRound, Error, +}; +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring::{Alice, Bob, Eve}; +use sp_runtime::Percent; +use tangle_primitives::services::Asset; + +#[test] +fn join_operator_success() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.stake, bond_amount); + assert_eq!(operator_info.delegation_count, 0); + assert_eq!(operator_info.request, None); + assert_eq!(operator_info.status, OperatorStatus::Active); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorJoined { + who: Alice.to_account_id(), + })); + }); +} + +#[test] +fn join_operator_already_operator() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + assert_noop!( + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + ), + Error::::AlreadyOperator + ); + }); +} + +#[test] +fn join_operator_insufficient_bond() { + new_test_ext().execute_with(|| { + let insufficient_bond = 5_000; + + assert_noop!( + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Eve.to_account_id()), + insufficient_bond + ), + Error::::BondTooLow + ); + }); +} + +#[test] +fn join_operator_insufficient_funds() { + new_test_ext().execute_with(|| { + let bond_amount = 350_000; // User 4 has only 200_000 + + assert_noop!( + MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + ), + pallet_balances::Error::::InsufficientBalance + ); + }); +} + +#[test] +fn join_operator_minimum_bond() { + new_test_ext().execute_with(|| { + let minimum_bond = 10_000; + let exact_bond = minimum_bond; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + exact_bond + )); + + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.stake, exact_bond); + }); +} + +#[test] +fn schedule_leave_operator_success() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Schedule leave operators without joining + assert_noop!( + MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NotAnOperator + ); + + // Set the current round + >::put(5); + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Schedule leave operators + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation( + Event::OperatorLeavingScheduled { who: Alice.to_account_id() }, + )); + }); +} + +#[test] +fn cancel_leave_operator_tests() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Set the current round + >::put(5); + + // Schedule leave operators + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Verify operator metadata after cancellation + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) + + // Test: Cancel leave operators successfully + assert_ok!(MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Verify operator metadata after cancellation + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.status, OperatorStatus::Active); // current_round (5) + leave_operators_delay (10) + + // Verify event for cancellation + System::assert_has_event(RuntimeEvent::MultiAssetDelegation( + Event::OperatorLeaveCancelled { who: Alice.to_account_id() }, + )); + + // Test: Cancel leave operators without being in leaving state + assert_noop!( + MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NotLeavingOperator + ); + + // Test: Schedule leave operators again + assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Test: Cancel leave operators without being an operator + assert_noop!( + MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( + Bob.to_account_id() + )), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn operator_bond_more_success() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + let additional_bond = 5_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // stake more TNT + assert_ok!(MultiAssetDelegation::operator_bond_more( + RuntimeOrigin::signed(Alice.to_account_id()), + additional_bond + )); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.stake, bond_amount + additional_bond); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorBondMore { + who: Alice.to_account_id(), + additional_bond, + })); + }); +} + +#[test] +fn operator_bond_more_not_an_operator() { + new_test_ext().execute_with(|| { + let additional_bond = 5_000; + + // Attempt to stake more without being an operator + assert_noop!( + MultiAssetDelegation::operator_bond_more( + RuntimeOrigin::signed(Alice.to_account_id()), + additional_bond + ), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn operator_bond_more_insufficient_balance() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + let additional_bond = 1_150_000; // Exceeds available balance + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Attempt to stake more with insufficient balance + assert_noop!( + MultiAssetDelegation::operator_bond_more( + RuntimeOrigin::signed(Alice.to_account_id()), + additional_bond + ), + pallet_balances::Error::::InsufficientBalance + ); + }); +} + +#[test] +fn schedule_operator_unstake_success() { + new_test_ext().execute_with(|| { + let bond_amount = 20_000; // Increased initial bond + let unstake_amount = 5_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Schedule unstake + assert_ok!(MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + )); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.request.unwrap().amount, unstake_amount); + + // Verify remaining stake is above minimum + assert!( + operator_info.stake.saturating_sub(unstake_amount) + >= MinOperatorBondAmount::get().into() + ); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation( + Event::OperatorBondLessScheduled { who: Alice.to_account_id(), unstake_amount }, + )); + }); +} + +// Add test for minimum stake requirement +#[test] +fn schedule_operator_unstake_respects_minimum_stake() { + new_test_ext().execute_with(|| { + let bond_amount = 20_000; + let unstake_amount = 15_000; // Would leave less than minimum required + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Attempt to schedule unstake that would leave less than minimum + assert_noop!( + MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + ), + Error::::InsufficientStakeRemaining + ); + }); +} + +#[test] +fn schedule_operator_unstake_not_an_operator() { + new_test_ext().execute_with(|| { + let unstake_amount = 5_000; + + // Attempt to schedule unstake without being an operator + assert_noop!( + MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + ), + Error::::NotAnOperator + ); + }); +} + +// TO DO +// #[test] +// fn schedule_operator_unstake_active_services() { +// new_test_ext().execute_with(|| { +// let bond_amount = 10_000; +// let unstake_amount = 5_000; + +// // Join operator first +// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(Alice. +// to_account_id()), bond_amount)); + +// // Manually set the operator's delegation count to simulate active services +// Operators::::mutate(1, |operator| { +// if let Some(ref mut operator) = operator { +// operator.delegation_count = 1; +// } +// }); + +// // Attempt to schedule unstake with active services +// assert_noop!( +// +// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), +// unstake_amount), Error::::ActiveServicesUsingTNT +// ); +// }); +// } + +#[test] +fn execute_operator_unstake_success() { + new_test_ext().execute_with(|| { + let bond_amount = 20_000; + let unstake_amount = 5_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Schedule unstake + assert_ok!(MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + )); + + // Set the current round to simulate passage of time + >::put(15); + + // Execute unstake + assert_ok!(MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.stake, bond_amount - unstake_amount); + assert_eq!(operator_info.request, None); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation( + Event::OperatorBondLessExecuted { who: Alice.to_account_id() }, + )); + }); +} + +#[test] +fn execute_operator_unstake_not_an_operator() { + new_test_ext().execute_with(|| { + // Attempt to execute unstake without being an operator + assert_noop!( + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn execute_operator_unstake_no_scheduled_unstake() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Attempt to execute unstake without scheduling it + assert_noop!( + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NoScheduledBondLess + ); + }); +} + +#[test] +fn execute_operator_unstake_request_not_satisfied() { + new_test_ext().execute_with(|| { + let bond_amount = 20_000; + let unstake_amount = 5_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Schedule unstake + assert_ok!(MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + )); + + // Attempt to execute unstake before request is satisfied + assert_noop!( + MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::BondLessRequestNotSatisfied + ); + }); +} + +#[test] +fn cancel_operator_unstake_success() { + new_test_ext().execute_with(|| { + let bond_amount = 20_000; + let unstake_amount = 5_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Schedule unstake + assert_ok!(MultiAssetDelegation::schedule_operator_unstake( + RuntimeOrigin::signed(Alice.to_account_id()), + unstake_amount + )); + + // Cancel unstake + assert_ok!(MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + ))); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.request, None); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation( + Event::OperatorBondLessCancelled { who: Alice.to_account_id() }, + )); + }); +} + +#[test] +fn cancel_operator_unstake_not_an_operator() { + new_test_ext().execute_with(|| { + // Attempt to cancel unstake without being an operator + assert_noop!( + MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn cancel_operator_unstake_no_scheduled_unstake() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Attempt to cancel unstake without scheduling it + assert_noop!( + MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( + Alice.to_account_id() + )), + Error::::NoScheduledBondLess + ); + }); +} + +#[test] +fn go_offline_success() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Go offline + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.status, OperatorStatus::Inactive); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOffline { + who: Alice.to_account_id(), + })); + }); +} + +#[test] +fn go_offline_not_an_operator() { + new_test_ext().execute_with(|| { + // Attempt to go offline without being an operator + assert_noop!( + MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id())), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn go_online_success() { + new_test_ext().execute_with(|| { + let bond_amount = 10_000; + + // Join operator first + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + bond_amount + )); + + // Go offline first + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); + + // Go online + assert_ok!(MultiAssetDelegation::go_online(RuntimeOrigin::signed(Alice.to_account_id()))); + + // Verify operator metadata + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.status, OperatorStatus::Active); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOnline { + who: Alice.to_account_id(), + })); + }); +} + +#[test] +fn slash_operator_success() { + new_test_ext().execute_with(|| { + // Setup operator + let operator_stake = 10_000; + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + operator_stake + )); + + // Setup delegators + let delegator_stake = 5_000; + let asset_id = Asset::Custom(1); + let blueprint_id = 1; + + create_and_mint_tokens(1, Bob.to_account_id(), delegator_stake); + mint_tokens(Bob.to_account_id(), 1, Bob.to_account_id(), delegator_stake); + + // Setup delegator with fixed blueprint selection + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(Bob.to_account_id()), + asset_id, + delegator_stake, + None + )); + + assert_ok!(MultiAssetDelegation::add_blueprint_id( + RuntimeOrigin::signed(Bob.to_account_id()), + blueprint_id + )); + + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(Bob.to_account_id()), + Alice.to_account_id(), + asset_id, + delegator_stake, + Fixed(vec![blueprint_id].try_into().unwrap()), + )); + + // Slash 50% of stakes + let slash_percentage = Percent::from_percent(50); + assert_ok!(MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + blueprint_id, + slash_percentage + )); + + // Verify operator stake was slashed + let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); + assert_eq!(operator_info.stake, operator_stake / 2); + + // Verify delegator stake was slashed + let delegator = MultiAssetDelegation::delegators(Bob.to_account_id()).unwrap(); + let delegation = delegator + .delegations + .iter() + .find(|d| d.operator == Alice.to_account_id()) + .unwrap(); + assert_eq!(delegation.amount, delegator_stake / 2); + + // Verify event + System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorSlashed { + who: Alice.to_account_id(), + amount: operator_stake / 2, + })); + }); +} + +#[test] +fn slash_operator_not_an_operator() { + new_test_ext().execute_with(|| { + assert_noop!( + MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + 1, + Percent::from_percent(50) + ), + Error::::NotAnOperator + ); + }); +} + +#[test] +fn slash_operator_not_active() { + new_test_ext().execute_with(|| { + // Setup and deactivate operator + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + 10_000 + )); + assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); + + assert_noop!( + MultiAssetDelegation::slash_operator( + &Alice.to_account_id(), + 1, + Percent::from_percent(50) + ), + Error::::NotActiveOperator + ); + }); +} + +#[test] +fn slash_delegator_fixed_blueprint_not_selected() { + new_test_ext().execute_with(|| { + // Setup operator + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(Alice.to_account_id()), + 10_000 + )); + + create_and_mint_tokens(1, Bob.to_account_id(), 10_000); + + // Setup delegator with fixed blueprint selection + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(Bob.to_account_id()), + Asset::Custom(1), + 5_000, + None + )); + + assert_ok!(MultiAssetDelegation::add_blueprint_id( + RuntimeOrigin::signed(Bob.to_account_id()), + 1 + )); + + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(Bob.to_account_id()), + Alice.to_account_id(), + Asset::Custom(1), + 5_000, + Fixed(vec![2].try_into().unwrap()), + )); + + // Try to slash with unselected blueprint + assert_noop!( + MultiAssetDelegation::slash_delegator( + &Bob.to_account_id(), + &Alice.to_account_id(), + 5, + Percent::from_percent(50) + ), + Error::::BlueprintNotSelected + ); + }); +} diff --git a/pallets/rewards/src/tests/session_manager.rs b/pallets/rewards/src/tests/session_manager.rs new file mode 100644 index 00000000..7174d5f5 --- /dev/null +++ b/pallets/rewards/src/tests/session_manager.rs @@ -0,0 +1,156 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::CurrentRound; +use frame_support::assert_ok; +use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave}; +use tangle_primitives::services::Asset; + +#[test] +fn handle_round_change_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let who = Bob.to_account_id(); + let operator = Alice.to_account_id(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + CurrentRound::::put(1); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + create_and_mint_tokens(VDOT, who.clone(), amount); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id, + amount, + None + )); + + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id, + amount, + Default::default() + )); + + assert_ok!(Pallet::::handle_round_change()); + + // Assert + let current_round = MultiAssetDelegation::current_round(); + assert_eq!(current_round, 2); + + let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator.clone()).unwrap(); + assert_eq!(snapshot1.stake, 10_000); + assert_eq!(snapshot1.delegations.len(), 1); + assert_eq!(snapshot1.delegations[0].amount, amount); + assert_eq!(snapshot1.delegations[0].asset_id, asset_id); + }); +} + +#[test] +fn handle_round_change_with_unstake_should_work() { + new_test_ext().execute_with(|| { + // Arrange + let delegator1 = Alice.to_account_id(); + let delegator2 = Bob.to_account_id(); + let operator1 = Charlie.to_account_id(); + let operator2 = Dave.to_account_id(); + let asset_id = Asset::Custom(VDOT); + let amount1 = 1_000_000_000_000; + let amount2 = 1_000_000_000_000; + let unstake_amount = 50; + + CurrentRound::::put(1); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator1.clone()), + 10_000 + )); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator2.clone()), + 10_000 + )); + + create_and_mint_tokens(VDOT, delegator1.clone(), amount1); + mint_tokens(delegator1.clone(), VDOT, delegator2.clone(), amount2); + + // Deposit and delegate first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id, + amount1, + None, + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(delegator1.clone()), + operator1.clone(), + asset_id, + amount1, + Default::default() + )); + + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator2.clone()), + asset_id, + amount2, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(delegator2.clone()), + operator2.clone(), + asset_id, + amount2, + Default::default() + )); + + // Delegator1 schedules unstake + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(delegator1.clone()), + operator1.clone(), + asset_id, + unstake_amount, + )); + + assert_ok!(Pallet::::handle_round_change()); + + // Assert + let current_round = MultiAssetDelegation::current_round(); + assert_eq!(current_round, 2); + + // Check the snapshot for operator1 + let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator1.clone()).unwrap(); + assert_eq!(snapshot1.stake, 10_000); + assert_eq!(snapshot1.delegations.len(), 1); + assert_eq!(snapshot1.delegations[0].delegator, delegator1.clone()); + assert_eq!(snapshot1.delegations[0].amount, amount1 - unstake_amount); // Amount reduced by unstake_amount + assert_eq!(snapshot1.delegations[0].asset_id, asset_id); + + // Check the snapshot for operator2 + let snapshot2 = MultiAssetDelegation::at_stake(current_round, operator2.clone()).unwrap(); + assert_eq!(snapshot2.stake, 10000); + assert_eq!(snapshot2.delegations.len(), 1); + assert_eq!(snapshot2.delegations[0].delegator, delegator2.clone()); + assert_eq!(snapshot2.delegations[0].amount, amount2); + assert_eq!(snapshot2.delegations[0].asset_id, asset_id); + }); +} diff --git a/pallets/rewards/src/traits.rs b/pallets/rewards/src/traits.rs new file mode 100644 index 00000000..653ad9ef --- /dev/null +++ b/pallets/rewards/src/traits.rs @@ -0,0 +1,72 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +use super::*; +use crate::types::{BalanceOf, OperatorStatus}; +use sp_runtime::{traits::Zero, Percent}; +use sp_std::prelude::*; +use tangle_primitives::{ + services::Asset, traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex, +}; + +impl MultiAssetDelegationInfo> for crate::Pallet { + type AssetId = T::AssetId; + + fn get_current_round() -> RoundIndex { + Self::current_round() + } + + fn is_operator(operator: &T::AccountId) -> bool { + Operators::::get(operator).is_some() + } + + fn is_operator_active(operator: &T::AccountId) -> bool { + Operators::::get(operator) + .map_or(false, |metadata| matches!(metadata.status, OperatorStatus::Active)) + } + + fn get_operator_stake(operator: &T::AccountId) -> BalanceOf { + Operators::::get(operator).map_or(Zero::zero(), |metadata| metadata.stake) + } + + fn get_total_delegation_by_asset_id( + operator: &T::AccountId, + asset_id: &Asset, + ) -> BalanceOf { + Operators::::get(operator).map_or(Zero::zero(), |metadata| { + metadata + .delegations + .iter() + .filter(|stake| &stake.asset_id == asset_id) + .fold(Zero::zero(), |acc, stake| acc + stake.amount) + }) + } + + fn get_delegators_for_operator( + operator: &T::AccountId, + ) -> Vec<(T::AccountId, BalanceOf, Asset)> { + Operators::::get(operator).map_or(Vec::new(), |metadata| { + metadata + .delegations + .iter() + .map(|stake| (stake.delegator.clone(), stake.amount, stake.asset_id)) + .collect() + }) + } + + fn slash_operator(operator: &T::AccountId, blueprint_id: BlueprintId, percentage: Percent) { + let _ = Pallet::::slash_operator(operator, blueprint_id, percentage); + } +} diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs new file mode 100644 index 00000000..a1b0cb4d --- /dev/null +++ b/pallets/rewards/src/types.rs @@ -0,0 +1,59 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use crate::Config; +use frame_support::traits::Currency; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_runtime::RuntimeDebug; +use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use tangle_primitives::types::RoundIndex; + +pub mod delegator; +pub mod operator; +pub mod rewards; + +pub use delegator::*; +pub use operator::*; +pub use rewards::*; + +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +pub type OperatorMetadataOf = OperatorMetadata< + ::AccountId, + BalanceOf, + ::AssetId, + ::MaxDelegations, + ::MaxOperatorBlueprints, +>; + +pub type OperatorSnapshotOf = OperatorSnapshot< + ::AccountId, + BalanceOf, + ::AssetId, + ::MaxDelegations, +>; + +pub type DelegatorMetadataOf = DelegatorMetadata< + ::AccountId, + BalanceOf, + ::AssetId, + ::MaxWithdrawRequests, + ::MaxDelegations, + ::MaxUnstakeRequests, + ::MaxDelegatorBlueprints, +>; diff --git a/pallets/rewards/src/types/delegator.rs b/pallets/rewards/src/types/delegator.rs new file mode 100644 index 00000000..774b8f46 --- /dev/null +++ b/pallets/rewards/src/types/delegator.rs @@ -0,0 +1,219 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use super::*; +use frame_support::{pallet_prelude::Get, BoundedVec}; +use tangle_primitives::{services::Asset, BlueprintId}; + +/// Represents how a delegator selects which blueprints to work with. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] +pub enum DelegatorBlueprintSelection> { + /// The delegator works with a fixed set of blueprints. + Fixed(BoundedVec), + /// The delegator works with all available blueprints. + All, +} + +impl> Default for DelegatorBlueprintSelection { + fn default() -> Self { + DelegatorBlueprintSelection::Fixed(Default::default()) + } +} + +/// Represents the status of a delegator. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] +pub enum DelegatorStatus { + /// The delegator is active. + #[default] + Active, + /// The delegator has scheduled an exit to revoke all ongoing delegations. + LeavingScheduled(RoundIndex), +} + +/// Represents a request to withdraw a specific amount of an asset. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct WithdrawRequest { + /// The ID of the asset to be withdrawd. + pub asset_id: Asset, + /// The amount of the asset to be withdrawd. + pub amount: Balance, + /// The round in which the withdraw was requested. + pub requested_round: RoundIndex, +} + +/// Represents a request to reduce the bonded amount of a specific asset. +#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct BondLessRequest> { + /// The account ID of the operator. + pub operator: AccountId, + /// The ID of the asset to reduce the stake of. + pub asset_id: Asset, + /// The amount by which to reduce the stake. + pub amount: Balance, + /// The round in which the stake reduction was requested. + pub requested_round: RoundIndex, + /// The blueprint selection of the delegator. + pub blueprint_selection: DelegatorBlueprintSelection, +} + +/// Stores the state of a delegator, including deposits, delegations, and requests. +#[derive(Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct DelegatorMetadata< + AccountId, + Balance, + AssetId: Encode + Decode + TypeInfo, + MaxWithdrawRequests: Get, + MaxDelegations: Get, + MaxUnstakeRequests: Get, + MaxBlueprints: Get, +> { + /// A map of deposited assets and their respective amounts. + pub deposits: BTreeMap, Balance>, + /// A vector of withdraw requests. + pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, + /// A list of all current delegations. + pub delegations: + BoundedVec, MaxDelegations>, + /// A vector of requests to reduce the bonded amount. + pub delegator_unstake_requests: + BoundedVec, MaxUnstakeRequests>, + /// The current status of the delegator. + pub status: DelegatorStatus, +} + +impl< + AccountId, + Balance, + AssetId: Encode + Decode + TypeInfo, + MaxWithdrawRequests: Get, + MaxDelegations: Get, + MaxUnstakeRequests: Get, + MaxBlueprints: Get, + > Default + for DelegatorMetadata< + AccountId, + Balance, + AssetId, + MaxWithdrawRequests, + MaxDelegations, + MaxUnstakeRequests, + MaxBlueprints, + > +{ + fn default() -> Self { + DelegatorMetadata { + deposits: BTreeMap::new(), + delegations: BoundedVec::default(), + status: DelegatorStatus::default(), + withdraw_requests: BoundedVec::default(), + delegator_unstake_requests: BoundedVec::default(), + } + } +} + +impl< + AccountId, + Balance, + AssetId: Encode + Decode + TypeInfo, + MaxWithdrawRequests: Get, + MaxDelegations: Get, + MaxUnstakeRequests: Get, + MaxBlueprints: Get, + > + DelegatorMetadata< + AccountId, + Balance, + AssetId, + MaxWithdrawRequests, + MaxDelegations, + MaxUnstakeRequests, + MaxBlueprints, + > +{ + /// Returns a reference to the vector of withdraw requests. + pub fn get_withdraw_requests(&self) -> &Vec> { + &self.withdraw_requests + } + + /// Returns a reference to the list of delegations. + pub fn get_delegations( + &self, + ) -> &Vec> { + &self.delegations + } + + /// Returns a reference to the vector of unstake requests. + pub fn get_delegator_unstake_requests( + &self, + ) -> &Vec> { + &self.delegator_unstake_requests + } + + /// Checks if the list of delegations is empty. + pub fn is_delegations_empty(&self) -> bool { + self.delegations.is_empty() + } + + /// Calculates the total delegation amount for a specific asset. + pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance + // Asset) -> Balance + where + Balance: Default + core::ops::AddAssign + Clone, + AssetId: Eq + PartialEq, + { + let mut total = Balance::default(); + for stake in &self.delegations { + if stake.asset_id == asset_id { + total += stake.amount.clone(); + } + } + total + } + + /// Returns a list of delegations to a specific operator. + pub fn calculate_delegation_by_operator( + &self, + operator: AccountId, + ) -> Vec<&BondInfoDelegator> + where + AccountId: Eq + PartialEq, + { + self.delegations.iter().filter(|&stake| stake.operator == operator).collect() + } +} + +/// Represents a deposit of a specific asset. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct Deposit { + /// The amount of the asset deposited. + pub amount: Balance, + /// The ID of the deposited asset. + pub asset_id: Asset, +} + +/// Represents a stake between a delegator and an operator. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] +pub struct BondInfoDelegator> +{ + /// The account ID of the operator. + pub operator: AccountId, + /// The amount bonded. + pub amount: Balance, + /// The ID of the bonded asset. + pub asset_id: Asset, + /// The blueprint selection mode for this delegator. + pub blueprint_selection: DelegatorBlueprintSelection, +} diff --git a/pallets/rewards/src/types/operator.rs b/pallets/rewards/src/types/operator.rs new file mode 100644 index 00000000..e0e7ca27 --- /dev/null +++ b/pallets/rewards/src/types/operator.rs @@ -0,0 +1,139 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use super::*; +use frame_support::{pallet_prelude::*, BoundedVec}; +use tangle_primitives::services::Asset; + +/// A snapshot of the operator state at the start of the round. +#[derive(Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct OperatorSnapshot> +{ + /// The total value locked by the operator. + pub stake: Balance, + + /// The rewardable delegations. This list is a subset of total delegators, where certain + /// delegators are adjusted based on their scheduled status. + pub delegations: BoundedVec, MaxDelegations>, +} + +impl> + OperatorSnapshot +where + AssetId: PartialEq + Ord + Copy, + Balance: Default + core::ops::AddAssign + Copy, +{ + /// Calculates the total stake for a specific asset ID from all delegations. + pub fn get_stake_by_asset_id(&self, asset_id: Asset) -> Balance { + let mut total_stake = Balance::default(); + for stake in &self.delegations { + if stake.asset_id == asset_id { + total_stake += stake.amount; + } + } + total_stake + } + + /// Calculates the total stake for each asset and returns a list of (asset_id, total_stake). + pub fn get_total_stake_by_assets(&self) -> Vec<(Asset, Balance)> { + let mut stake_by_asset: BTreeMap, Balance> = BTreeMap::new(); + + for stake in &self.delegations { + let entry = stake_by_asset.entry(stake.asset_id).or_default(); + *entry += stake.amount; + } + + stake_by_asset.into_iter().collect() + } +} + +/// The activity status of the operator. +#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] +pub enum OperatorStatus { + /// Committed to be online. + #[default] + Active, + /// Temporarily inactive and excused for inactivity. + Inactive, + /// Bonded until the specified round. + Leaving(RoundIndex), +} + +/// A request scheduled to change the operator self-stake. +#[derive(PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] +pub struct OperatorBondLessRequest { + /// The amount by which the stake is to be decreased. + pub amount: Balance, + /// The round in which the request was made. + pub request_time: RoundIndex, +} + +/// Stores the metadata of an operator. +#[derive(Encode, Decode, RuntimeDebug, TypeInfo, Clone, Eq, PartialEq)] +pub struct OperatorMetadata< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxDelegations: Get, + MaxBlueprints: Get, +> { + /// The operator's self-stake amount. + pub stake: Balance, + /// The total number of delegations to this operator. + pub delegation_count: u32, + /// An optional pending request to decrease the operator's self-stake, with only one allowed at + /// any given time. + pub request: Option>, + /// A list of all current delegations. + pub delegations: BoundedVec, MaxDelegations>, + /// The current status of the operator. + pub status: OperatorStatus, + /// The set of blueprint IDs this operator works with. + pub blueprint_ids: BoundedVec, +} + +impl< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxDelegations: Get, + MaxBlueprints: Get, + > Default for OperatorMetadata +where + Balance: Default, +{ + fn default() -> Self { + Self { + stake: Balance::default(), + delegation_count: 0, + request: None, + delegations: BoundedVec::default(), + status: OperatorStatus::default(), + blueprint_ids: BoundedVec::default(), + } + } +} + +/// Represents a stake for an operator +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] +pub struct DelegatorBond { + /// The account ID of the delegator. + pub delegator: AccountId, + /// The amount bonded. + pub amount: Balance, + /// The ID of the bonded asset. + pub asset_id: Asset, +} diff --git a/pallets/rewards/src/types/rewards.rs b/pallets/rewards/src/types/rewards.rs new file mode 100644 index 00000000..6a1daad7 --- /dev/null +++ b/pallets/rewards/src/types/rewards.rs @@ -0,0 +1,43 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use super::*; +use sp_runtime::Percent; + +/// Configuration for rewards associated with a specific asset. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct RewardConfigForAssetVault { + // The annual percentage yield (APY) for the asset, represented as a Percent + pub apy: Percent, + // The minimum amount required before the asset can be rewarded. + pub cap: Balance, +} + +/// Configuration for rewards in the system. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct RewardConfig { + // A map of asset IDs to their respective reward configurations. + pub configs: BTreeMap>, + // A list of blueprint IDs that are whitelisted for rewards. + pub whitelisted_blueprint_ids: Vec, +} + +/// Asset action for vaults +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub enum AssetAction { + Add, + Remove, +} diff --git a/pallets/rewards/src/weights.rs b/pallets/rewards/src/weights.rs new file mode 100644 index 00000000..665c6195 --- /dev/null +++ b/pallets/rewards/src/weights.rs @@ -0,0 +1,55 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +//! Autogenerated weights for pallet_dkg +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-08-16, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/tangle +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_dkg +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_dkg. +pub trait WeightInfo { + fn set_fee() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn set_fee() -> Weight { + Weight::from_parts(32_778_000, 0) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} \ No newline at end of file From a8c87b505120a114eda4440a402d626a1a22a619 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 24 Dec 2024 21:06:56 +0530 Subject: [PATCH 37/63] wip --- Cargo.lock | 58 ++ pallets/rewards/src/functions.rs | 105 ++- pallets/rewards/src/functions/delegate.rs | 429 --------- pallets/rewards/src/functions/deposit.rs | 272 ------ pallets/rewards/src/functions/evm.rs | 143 --- pallets/rewards/src/functions/operator.rs | 342 -------- pallets/rewards/src/functions/rewards.rs | 144 ---- .../rewards/src/functions/session_manager.rs | 41 - pallets/rewards/src/lib.rs | 816 +++--------------- pallets/rewards/src/traits.rs | 158 +++- pallets/rewards/src/types.rs | 100 ++- pallets/rewards/src/types/delegator.rs | 219 ----- pallets/rewards/src/types/operator.rs | 139 --- pallets/rewards/src/types/rewards.rs | 43 - 14 files changed, 472 insertions(+), 2537 deletions(-) delete mode 100644 pallets/rewards/src/functions/delegate.rs delete mode 100644 pallets/rewards/src/functions/deposit.rs delete mode 100644 pallets/rewards/src/functions/evm.rs delete mode 100644 pallets/rewards/src/functions/operator.rs delete mode 100644 pallets/rewards/src/functions/rewards.rs delete mode 100644 pallets/rewards/src/functions/session_manager.rs delete mode 100644 pallets/rewards/src/types/delegator.rs delete mode 100644 pallets/rewards/src/types/operator.rs delete mode 100644 pallets/rewards/src/types/rewards.rs diff --git a/Cargo.lock b/Cargo.lock index 6f04abbe..4028768c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8464,6 +8464,64 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-rewards" +version = "1.2.3" +dependencies = [ + "ethabi", + "ethereum", + "ethers", + "fp-account", + "fp-consensus", + "fp-dynamic-fee", + "fp-ethereum", + "fp-evm", + "fp-rpc", + "fp-self-contained", + "fp-storage", + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "hex", + "hex-literal 0.4.1", + "itertools 0.13.0", + "libsecp256k1", + "log", + "num_enum", + "pallet-assets", + "pallet-balances", + "pallet-base-fee", + "pallet-dynamic-fee", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-chain-id", + "pallet-evm-precompile-blake2", + "pallet-evm-precompile-bn128", + "pallet-evm-precompile-curve25519", + "pallet-evm-precompile-ed25519", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", + "pallet-session", + "pallet-staking", + "pallet-timestamp", + "parity-scale-codec", + "precompile-utils", + "scale-info", + "serde", + "serde_json", + "smallvec", + "sp-core", + "sp-io", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "sp-staking", + "sp-std", + "tangle-primitives", +] + [[package]] name = "pallet-scheduler" version = "38.0.0" diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 9ee9c028..0c35cf9b 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -13,11 +13,100 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use super::*; - -pub mod delegate; -pub mod deposit; -pub mod evm; -pub mod operator; -pub mod rewards; -pub mod session_manager; + +use crate::{Config, UserRewardsOf}; +use frame_support::traits::Currency; +use sp_runtime::{traits::Zero, Saturating}; +use tangle_primitives::services::Asset; + +/// Calculate a user's score based on their staked assets and lock multipliers. +/// Score is calculated as follows: +/// - For TNT assets: +/// - Base score = staked amount +/// - Multiplier based on lock period (1x to 6x) +/// - For other assets: +/// - Base score = staked amount +/// - No additional multiplier +pub fn calculate_user_score( + asset: Asset, + rewards: &UserRewardsOf, +) -> u128 { + let base_score = match asset { + Asset::Native => { + // For TNT, include both restaking and boost rewards + let restaking_score = rewards.restaking_rewards + .saturating_add(rewards.service_rewards) + .saturated_into::(); + + // Apply lock multiplier to boost rewards + let boost_score = rewards.boost_rewards.amount + .saturated_into::() + .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); + + restaking_score.saturating_add(boost_score) + }, + _ => { + // For non-TNT assets, only consider service rewards + rewards.service_rewards.saturated_into::() + } + }; + + base_score +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{BoostInfo, LockMultiplier, UserRewards}; + use sp_runtime::traits::Zero; + + // Helper function to create UserRewards with specific values + fn create_user_rewards( + restaking: u128, + boost_amount: u128, + boost_multiplier: LockMultiplier, + service: u128, + ) -> UserRewardsOf { + UserRewards { + restaking_rewards: restaking.saturated_into(), + boost_rewards: BoostInfo { + amount: boost_amount.saturated_into(), + multiplier: boost_multiplier, + expiry: Zero::zero(), + }, + service_rewards: service.saturated_into(), + } + } + + #[test] + fn test_calculate_user_score_tnt() { + // Test TNT asset with different lock multipliers + let rewards = create_user_rewards::( + 1000, // restaking rewards + 500, // boost amount + LockMultiplier::ThreeMonths, // 3x multiplier + 200, // service rewards + ); + + let score = calculate_user_score::(Asset::Native, &rewards); + + // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 + assert_eq!(score, 2700); + } + + #[test] + fn test_calculate_user_score_other_asset() { + // Test non-TNT asset + let rewards = create_user_rewards::( + 1000, // restaking rewards + 500, // boost amount + LockMultiplier::SixMonths, // 6x multiplier (should not affect non-TNT) + 200, // service rewards + ); + + let score = calculate_user_score::(Asset::Evm(1), &rewards); + + // Expected: only service rewards are counted + assert_eq!(score, 200); + } +} diff --git a/pallets/rewards/src/functions/delegate.rs b/pallets/rewards/src/functions/delegate.rs deleted file mode 100644 index eac6ad6d..00000000 --- a/pallets/rewards/src/functions/delegate.rs +++ /dev/null @@ -1,429 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::*, Pallet}; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{fungibles::Mutate, tokens::Preservation, Get}, -}; -use sp_runtime::{ - traits::{CheckedSub, Zero}, - DispatchError, Percent, -}; -use sp_std::vec::Vec; -use tangle_primitives::services::EvmAddressMapping; -use tangle_primitives::{services::Asset, BlueprintId}; - -impl Pallet { - /// Processes the delegation of an amount of an asset to an operator. - /// Creates a new delegation for the delegator and updates their status to active, the deposit - /// of the delegator is moved to delegation. - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `operator` - The account ID of the operator. - /// * `asset_id` - The ID of the asset to be delegated. - /// * `amount` - The amount to be delegated. - /// - /// # Errors - /// - /// Returns an error if the delegator does not have enough deposited balance, - /// or if the operator is not found. - pub fn process_delegate( - who: T::AccountId, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - blueprint_selection: DelegatorBlueprintSelection, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Ensure enough deposited balance - let balance = - metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; - ensure!(*balance >= amount, Error::::InsufficientBalance); - - // Reduce the balance in deposits - *balance = balance.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; - if *balance == Zero::zero() { - metadata.deposits.remove(&asset_id); - } - - // Check if the delegation exists and update it, otherwise create a new delegation - if let Some(delegation) = metadata - .delegations - .iter_mut() - .find(|d| d.operator == operator && d.asset_id == asset_id) - { - delegation.amount += amount; - } else { - // Create the new delegation - let new_delegation = BondInfoDelegator { - operator: operator.clone(), - amount, - asset_id, - blueprint_selection, - }; - - // Create a mutable copy of delegations - let mut delegations = metadata.delegations.clone(); - delegations - .try_push(new_delegation) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - metadata.delegations = delegations; - - // Update the status - metadata.status = DelegatorStatus::Active; - } - - // Update the operator's metadata - if let Some(mut operator_metadata) = Operators::::get(&operator) { - // Check if the operator has capacity for more delegations - ensure!( - operator_metadata.delegation_count < T::MaxDelegations::get(), - Error::::MaxDelegationsExceeded - ); - - // Create and push the new delegation bond - let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; - - let mut delegations = operator_metadata.delegations.clone(); - - // Check if delegation already exists - if let Some(existing_delegation) = - delegations.iter_mut().find(|d| d.delegator == who && d.asset_id == asset_id) - { - existing_delegation.amount += amount; - } else { - delegations - .try_push(delegation) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - operator_metadata.delegation_count = - operator_metadata.delegation_count.saturating_add(1); - } - - operator_metadata.delegations = delegations; - - // Update storage - Operators::::insert(&operator, operator_metadata); - } else { - return Err(Error::::NotAnOperator.into()); - } - - Ok(()) - }) - } - - /// Schedules a stake reduction for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `operator` - The account ID of the operator. - /// * `asset_id` - The ID of the asset to be reduced. - /// * `amount` - The amount to be reduced. - /// - /// # Errors - /// - /// Returns an error if the delegator has no active delegation, - /// or if the unstake amount is greater than the current delegation amount. - pub fn process_schedule_delegator_unstake( - who: T::AccountId, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Ensure the delegator has an active delegation with the operator for the given asset - let delegation_index = metadata - .delegations - .iter() - .position(|d| d.operator == operator && d.asset_id == asset_id) - .ok_or(Error::::NoActiveDelegation)?; - - // Get the delegation and clone necessary data - let blueprint_selection = - metadata.delegations[delegation_index].blueprint_selection.clone(); - let delegation = &mut metadata.delegations[delegation_index]; - ensure!(delegation.amount >= amount, Error::::InsufficientBalance); - - delegation.amount -= amount; - - // Create the unstake request - let current_round = Self::current_round(); - let mut unstake_requests = metadata.delegator_unstake_requests.clone(); - unstake_requests - .try_push(BondLessRequest { - operator: operator.clone(), - asset_id, - amount, - requested_round: current_round, - blueprint_selection, - }) - .map_err(|_| Error::::MaxUnstakeRequestsExceeded)?; - metadata.delegator_unstake_requests = unstake_requests; - - // Remove the delegation if the remaining amount is zero - if delegation.amount.is_zero() { - metadata.delegations.remove(delegation_index); - } - - // Update the operator's metadata - Operators::::try_mutate(&operator, |maybe_operator_metadata| -> DispatchResult { - let operator_metadata = - maybe_operator_metadata.as_mut().ok_or(Error::::NotAnOperator)?; - - // Ensure the operator has a matching delegation - let operator_delegation_index = operator_metadata - .delegations - .iter() - .position(|d| d.delegator == who && d.asset_id == asset_id) - .ok_or(Error::::NoActiveDelegation)?; - - let operator_delegation = - &mut operator_metadata.delegations[operator_delegation_index]; - - // Reduce the amount in the operator's delegation - ensure!(operator_delegation.amount >= amount, Error::::InsufficientBalance); - operator_delegation.amount -= amount; - - // Remove the delegation if the remaining amount is zero - if operator_delegation.amount.is_zero() { - operator_metadata.delegations.remove(operator_delegation_index); - operator_metadata.delegation_count -= 1; - } - - Ok(()) - })?; - - Ok(()) - }) - } - - /// Executes scheduled stake reductions for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// - /// # Errors - /// - /// Returns an error if the delegator has no unstake requests or if none of the unstake requests - /// are ready. - pub fn process_execute_delegator_unstake(who: T::AccountId) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Ensure there are outstanding unstake requests - ensure!(!metadata.delegator_unstake_requests.is_empty(), Error::::NoBondLessRequest); - - let current_round = Self::current_round(); - - // Process all ready unstake requests - let mut executed_requests = Vec::new(); - metadata.delegator_unstake_requests.retain(|request| { - let delay = T::DelegationBondLessDelay::get(); - if current_round >= delay + request.requested_round { - // Add the amount back to the delegator's deposits - metadata - .deposits - .entry(request.asset_id) - .and_modify(|e| *e += request.amount) - .or_insert(request.amount); - executed_requests.push(request.clone()); - false // Remove this request - } else { - true // Keep this request - } - }); - - // If no requests were executed, return an error - ensure!(!executed_requests.is_empty(), Error::::BondLessNotReady); - - Ok(()) - }) - } - - /// Cancels a scheduled stake reduction for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `asset_id` - The ID of the asset for which to cancel the unstake request. - /// * `amount` - The amount of the unstake request to cancel. - /// - /// # Errors - /// - /// Returns an error if the delegator has no matching unstake request or if there is no active - /// delegation. - pub fn process_cancel_delegator_unstake( - who: T::AccountId, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Find and remove the matching unstake request - let request_index = metadata - .delegator_unstake_requests - .iter() - .position(|r| { - r.asset_id == asset_id && r.amount == amount && r.operator == operator - }) - .ok_or(Error::::NoBondLessRequest)?; - - let unstake_request = metadata.delegator_unstake_requests.remove(request_index); - - // Update the operator's metadata - Operators::::try_mutate( - &unstake_request.operator, - |maybe_operator_metadata| -> DispatchResult { - let operator_metadata = - maybe_operator_metadata.as_mut().ok_or(Error::::NotAnOperator)?; - - // Find the matching delegation and increase its amount, or insert a new - // delegation if not found - let mut delegations = operator_metadata.delegations.clone(); - if let Some(delegation) = delegations - .iter_mut() - .find(|d| d.asset_id == asset_id && d.delegator == who.clone()) - { - delegation.amount += amount; - } else { - delegations - .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - - // Increase the delegation count only when a new delegation is added - operator_metadata.delegation_count += 1; - } - operator_metadata.delegations = delegations; - - Ok(()) - }, - )?; - - // Update the delegator's metadata - let mut delegations = metadata.delegations.clone(); - - // If a similar delegation exists, increase the amount - if let Some(delegation) = delegations.iter_mut().find(|d| { - d.operator == unstake_request.operator && d.asset_id == unstake_request.asset_id - }) { - delegation.amount += unstake_request.amount; - } else { - // Create a new delegation - delegations - .try_push(BondInfoDelegator { - operator: unstake_request.operator.clone(), - amount: unstake_request.amount, - asset_id: unstake_request.asset_id, - blueprint_selection: unstake_request.blueprint_selection, - }) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - } - metadata.delegations = delegations; - - Ok(()) - }) - } - - /// Slashes a delegator's stake. - /// - /// # Arguments - /// - /// * `delegator` - The account ID of the delegator. - /// * `operator` - The account ID of the operator. - /// * `blueprint_id` - The ID of the blueprint. - /// * `percentage` - The percentage of the stake to slash. - /// - /// # Errors - /// - /// Returns an error if the delegator is not found, or if the delegation is not active. - pub fn slash_delegator( - delegator: &T::AccountId, - operator: &T::AccountId, - blueprint_id: BlueprintId, - percentage: Percent, - ) -> Result<(), DispatchError> { - Delegators::::try_mutate(delegator, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - let delegation = metadata - .delegations - .iter_mut() - .find(|d| &d.operator == operator) - .ok_or(Error::::NoActiveDelegation)?; - - // Check delegation type and blueprint_id - match &delegation.blueprint_selection { - DelegatorBlueprintSelection::Fixed(blueprints) => { - // For fixed delegation, ensure the blueprint_id is in the list - ensure!(blueprints.contains(&blueprint_id), Error::::BlueprintNotSelected); - }, - DelegatorBlueprintSelection::All => { - // For "All" type, no need to check blueprint_id - }, - } - - // Calculate and apply slash - let slash_amount = percentage.mul_floor(delegation.amount); - delegation.amount = delegation - .amount - .checked_sub(&slash_amount) - .ok_or(Error::::InsufficientStakeRemaining)?; - - match delegation.asset_id { - Asset::Custom(asset_id) => { - // Transfer slashed amount to the treasury - let _ = T::Fungibles::transfer( - asset_id, - &Self::pallet_account(), - &T::SlashedAmountRecipient::get(), - slash_amount, - Preservation::Expendable, - ); - }, - Asset::Erc20(address) => { - let slashed_amount_recipient_evm = - T::EvmAddressMapping::into_address(T::SlashedAmountRecipient::get()); - let (success, _weight) = Self::erc20_transfer( - address, - &Self::pallet_evm_account(), - slashed_amount_recipient_evm, - slash_amount, - ) - .map_err(|_| Error::::ERC20TransferFailed)?; - ensure!(success, Error::::ERC20TransferFailed); - }, - } - - // emit event - Self::deposit_event(Event::DelegatorSlashed { - who: delegator.clone(), - amount: slash_amount, - }); - - Ok(()) - }) - } -} diff --git a/pallets/rewards/src/functions/deposit.rs b/pallets/rewards/src/functions/deposit.rs deleted file mode 100644 index 5f7a17fa..00000000 --- a/pallets/rewards/src/functions/deposit.rs +++ /dev/null @@ -1,272 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::*, Pallet}; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, - traits::{fungibles::Mutate, tokens::Preservation, Get}, -}; -use sp_core::H160; -use tangle_primitives::services::{Asset, EvmAddressMapping}; - -impl Pallet { - /// Returns the account ID of the pallet. - pub fn pallet_account() -> T::AccountId { - T::PalletId::get().into_account_truncating() - } - - /// Returns the EVM account id of the pallet. - /// - /// This function retrieves the account id associated with the pallet by converting - /// the pallet evm address to an account id. - /// - /// # Returns - /// * `T::AccountId` - The account id of the pallet. - pub fn pallet_evm_account() -> H160 { - T::EvmAddressMapping::into_address(Self::pallet_account()) - } - - pub fn handle_transfer_to_pallet( - sender: &T::AccountId, - asset_id: Asset, - amount: BalanceOf, - evm_sender: Option, - ) -> DispatchResult { - match asset_id { - Asset::Custom(asset_id) => { - T::Fungibles::transfer( - asset_id, - sender, - &Self::pallet_account(), - amount, - Preservation::Expendable, - )?; - }, - Asset::Erc20(asset_address) => { - let sender = evm_sender.ok_or(Error::::ERC20TransferFailed)?; - let (success, _weight) = Self::erc20_transfer( - asset_address, - &sender, - Self::pallet_evm_account(), - amount, - ) - .map_err(|_| Error::::ERC20TransferFailed)?; - ensure!(success, Error::::ERC20TransferFailed); - }, - } - Ok(()) - } - - /// Processes the deposit of assets into the pallet. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `asset_id` - The optional asset ID of the assets to be deposited. - /// * `amount` - The amount of assets to be deposited. - /// - /// # Errors - /// - /// Returns an error if the user is already a delegator, if the stake amount is too low, or if - /// the transfer fails. - pub fn process_deposit( - who: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - evm_address: Option, - ) -> DispatchResult { - ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); - - // Transfer the amount to the pallet account - Self::handle_transfer_to_pallet(&who, asset_id, amount, evm_address)?; - - // Update storage - Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { - let metadata = maybe_metadata.get_or_insert_with(Default::default); - // Handle checked addition first to avoid ? operator in closure - if let Some(existing) = metadata.deposits.get(&asset_id) { - let new_amount = - existing.checked_add(&amount).ok_or(Error::::DepositOverflow)?; - metadata.deposits.insert(asset_id, new_amount); - } else { - metadata.deposits.insert(asset_id, amount); - } - Ok(()) - })?; - - Ok(()) - } - - /// Schedules an withdraw request for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `asset_id` - The optional asset ID of the assets to be withdrawd. - /// * `amount` - The amount of assets to be withdrawd. - /// - /// # Errors - /// - /// Returns an error if the user is not a delegator, if there is insufficient balance, or if the - /// asset is not supported. - pub fn process_schedule_withdraw( - who: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Ensure there is enough deposited balance - let balance = - metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; - ensure!(*balance >= amount, Error::::InsufficientBalance); - - // Reduce the balance in deposits - *balance -= amount; - if *balance == Zero::zero() { - metadata.deposits.remove(&asset_id); - } - - // Create the unstake request - let current_round = Self::current_round(); - let mut withdraw_requests = metadata.withdraw_requests.clone(); - withdraw_requests - .try_push(WithdrawRequest { asset_id, amount, requested_round: current_round }) - .map_err(|_| Error::::MaxWithdrawRequestsExceeded)?; - metadata.withdraw_requests = withdraw_requests; - - Ok(()) - }) - } - - /// Executes an withdraw request for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// - /// # Errors - /// - /// Returns an error if the user is not a delegator, if there are no withdraw requests, or if - /// the withdraw request is not ready. - pub fn process_execute_withdraw( - who: T::AccountId, - evm_address: Option, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Ensure there are outstanding withdraw requests - ensure!(!metadata.withdraw_requests.is_empty(), Error::::NowithdrawRequests); - - let current_round = Self::current_round(); - let delay = T::LeaveDelegatorsDelay::get(); - - // Process all ready withdraw requests - let mut i = 0; - while i < metadata.withdraw_requests.len() { - let request = &metadata.withdraw_requests[i]; - if current_round >= delay + request.requested_round { - let transfer_success = match request.asset_id { - Asset::Custom(asset_id) => T::Fungibles::transfer( - asset_id, - &Self::pallet_account(), - &who, - request.amount, - Preservation::Expendable, - ) - .is_ok(), - Asset::Erc20(asset_address) => { - if let Some(evm_addr) = evm_address { - if let Ok((success, _weight)) = Self::erc20_transfer( - asset_address, - &Self::pallet_evm_account(), - evm_addr, - request.amount, - ) { - success - } else { - false - } - } else { - false - } - }, - }; - - if transfer_success { - // Remove the completed request - metadata.withdraw_requests.remove(i); - } else { - // Only increment if we didn't remove the request - i += 1; - } - } else { - i += 1; - } - } - - Ok(()) - }) - } - - /// Cancels an withdraw request for a delegator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the delegator. - /// * `asset_id` - The asset ID of the withdraw request to cancel. - /// * `amount` - The amount of the withdraw request to cancel. - /// - /// # Errors - /// - /// Returns an error if the user is not a delegator or if there is no matching withdraw request. - pub fn process_cancel_withdraw( - who: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - Delegators::::try_mutate(&who, |maybe_metadata| { - let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; - - // Find and remove the matching withdraw request - let request_index = metadata - .withdraw_requests - .iter() - .position(|r| r.asset_id == asset_id && r.amount == amount) - .ok_or(Error::::NoMatchingwithdrawRequest)?; - - let withdraw_request = metadata.withdraw_requests.remove(request_index); - - // Add the amount back to the delegator's deposits - metadata - .deposits - .entry(asset_id) - .and_modify(|e| *e += withdraw_request.amount) - .or_insert(withdraw_request.amount); - - // Update the status if no more delegations exist - if metadata.delegations.is_empty() { - metadata.status = DelegatorStatus::Active; - } - - Ok(()) - }) - } -} diff --git a/pallets/rewards/src/functions/evm.rs b/pallets/rewards/src/functions/evm.rs deleted file mode 100644 index e2cb6140..00000000 --- a/pallets/rewards/src/functions/evm.rs +++ /dev/null @@ -1,143 +0,0 @@ -use super::*; -use crate::types::BalanceOf; -use ethabi::{Function, StateMutability, Token}; -use frame_support::{ - dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, - pallet_prelude::{Pays, Weight}, -}; -use parity_scale_codec::Encode; -use scale_info::prelude::string::String; -use sp_core::{H160, U256}; -use sp_runtime::traits::UniqueSaturatedInto; -use sp_std::{vec, vec::Vec}; -use tangle_primitives::services::{EvmGasWeightMapping, EvmRunner}; - -impl Pallet { - /// Moves a `value` amount of tokens from the caller's account to `to`. - pub fn erc20_transfer( - erc20: H160, - from: &H160, - to: H160, - value: BalanceOf, - ) -> Result<(bool, Weight), DispatchErrorWithPostInfo> { - #[allow(deprecated)] - let transfer_fn = Function { - name: String::from("transfer"), - inputs: vec![ - ethabi::Param { - name: String::from("to"), - kind: ethabi::ParamType::Address, - internal_type: None, - }, - ethabi::Param { - name: String::from("value"), - kind: ethabi::ParamType::Uint(256), - internal_type: None, - }, - ], - outputs: vec![ethabi::Param { - name: String::from("success"), - kind: ethabi::ParamType::Bool, - internal_type: None, - }], - constant: None, - state_mutability: StateMutability::NonPayable, - }; - - let args = [ - Token::Address(to), - Token::Uint(ethabi::Uint::from(value.using_encoded(U256::from_little_endian))), - ]; - - log::debug!(target: "evm", "Dispatching EVM call(0x{}): {}", hex::encode(transfer_fn.short_signature()), transfer_fn.signature()); - let data = transfer_fn.encode_input(&args).map_err(|_| Error::::EVMAbiEncode)?; - let gas_limit = 300_000; - let info = Self::evm_call(*from, erc20, U256::zero(), data, gas_limit)?; - let weight = Self::weight_from_call_info(&info); - - // decode the result and return it - let maybe_value = info.exit_reason.is_succeed().then_some(&info.value); - let success = if let Some(data) = maybe_value { - let result = transfer_fn.decode_output(data).map_err(|_| Error::::EVMAbiDecode)?; - let success = result.first().ok_or(Error::::EVMAbiDecode)?; - if let ethabi::Token::Bool(val) = success { - *val - } else { - false - } - } else { - false - }; - - Ok((success, weight)) - } - - /// Dispatches a call to the EVM and returns the result. - fn evm_call( - from: H160, - to: H160, - value: U256, - data: Vec, - gas_limit: u64, - ) -> Result { - let transactional = true; - let validate = false; - let result = - T::EvmRunner::call(from, to, data.clone(), value, gas_limit, transactional, validate); - match result { - Ok(info) => { - log::debug!( - target: "evm", - "Call from: {:?}, to: {:?}, data: 0x{}, gas_limit: {:?}, result: {:?}", - from, - to, - hex::encode(&data), - gas_limit, - info, - ); - // if we have a revert reason, emit an event - if info.exit_reason.is_revert() { - log::debug!( - target: "evm", - "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", - to, - hex::encode(&data), - hex::encode(&info.value), - ); - #[cfg(test)] - eprintln!( - "Call to: {:?} with data: 0x{} Reverted with reason: (0x{})", - to, - hex::encode(&data), - hex::encode(&info.value), - ); - Self::deposit_event(Event::::EvmReverted { - from, - to, - data, - reason: info.value.clone(), - }); - } - Ok(info) - }, - Err(e) => Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { actual_weight: Some(e.weight), pays_fee: Pays::Yes }, - error: e.error.into(), - }), - } - } - - /// Convert the gas used in the call info to weight. - pub fn weight_from_call_info(info: &fp_evm::CallInfo) -> Weight { - let mut gas_to_weight = T::EvmGasWeightMapping::gas_to_weight( - info.used_gas.standard.unique_saturated_into(), - true, - ); - if let Some(weight_info) = info.weight_info { - if let Some(proof_size_usage) = weight_info.proof_size_usage { - *gas_to_weight.proof_size_mut() = proof_size_usage; - } - } - gas_to_weight - } -} diff --git a/pallets/rewards/src/functions/operator.rs b/pallets/rewards/src/functions/operator.rs deleted file mode 100644 index 9e6e2b39..00000000 --- a/pallets/rewards/src/functions/operator.rs +++ /dev/null @@ -1,342 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -/// Functions for the pallet. -use super::*; -use crate::{types::*, Pallet}; -use frame_support::{ - ensure, - pallet_prelude::DispatchResult, - traits::{Currency, ExistenceRequirement, Get, ReservableCurrency}, - BoundedVec, -}; -use sp_runtime::{ - traits::{CheckedAdd, CheckedSub}, - DispatchError, Percent, -}; -use tangle_primitives::{BlueprintId, ServiceManager}; - -impl Pallet { - /// Handles the deposit of stake amount and creation of an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// * `bond_amount` - The amount to be bonded by the operator. - /// - /// # Errors - /// - /// Returns an error if the user is already an operator or if the stake amount is too low. - pub fn handle_deposit_and_create_operator( - who: T::AccountId, - bond_amount: BalanceOf, - ) -> DispatchResult { - ensure!(!Operators::::contains_key(&who), Error::::AlreadyOperator); - ensure!(bond_amount >= T::MinOperatorBondAmount::get(), Error::::BondTooLow); - T::Currency::reserve(&who, bond_amount)?; - - let operator_metadata = OperatorMetadata { - delegations: BoundedVec::default(), - delegation_count: 0, - blueprint_ids: BoundedVec::default(), - stake: bond_amount, - request: None, - status: OperatorStatus::Active, - }; - - Operators::::insert(&who, operator_metadata); - - Ok(()) - } - - /// Processes the leave operation for an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found, already leaving, or cannot exit. - #[allow(clippy::single_match)] - pub fn process_leave_operator(who: &T::AccountId) -> DispatchResult { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - - match operator.status { - OperatorStatus::Leaving(_) => return Err(Error::::AlreadyLeaving.into()), - _ => {}, - }; - - ensure!(T::ServiceManager::can_exit(who), Error::::CannotExit); - - let current_round = Self::current_round(); - let leaving_time = current_round + T::LeaveOperatorsDelay::get(); - - operator.status = OperatorStatus::Leaving(leaving_time); - Operators::::insert(who, operator); - - Ok(()) - } - - /// Cancels the leave operation for an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found or not in leaving state. - pub fn process_cancel_leave_operator(who: &T::AccountId) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - - match operator.status { - OperatorStatus::Leaving(_) => {}, - _ => return Err(Error::::NotLeavingOperator.into()), - }; - - operator.status = OperatorStatus::Active; - Operators::::insert(who, operator); - - Ok(()) - } - - /// Executes the leave operation for an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found, not in leaving state, or the leaving round - /// has not been reached. - pub fn process_execute_leave_operators(who: &T::AccountId) -> Result<(), DispatchError> { - let operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - let current_round = Self::current_round(); - - match operator.status { - OperatorStatus::Leaving(leaving_round) => { - ensure!(current_round >= leaving_round, Error::::LeavingRoundNotReached); - }, - _ => return Err(Error::::NotLeavingOperator.into()), - }; - - T::Currency::unreserve(who, operator.stake); - Operators::::remove(who); - - Ok(()) - } - - /// Processes an additional TNT stake for an operator, called - /// by themselves. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// * `additional_bond` - The additional amount to be bonded by the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found or if the reserve fails. - pub fn process_operator_bond_more( - who: &T::AccountId, - additional_bond: BalanceOf, - ) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - - // Check for potential overflow before reserving funds - operator.stake = - operator.stake.checked_add(&additional_bond).ok_or(Error::::StakeOverflow)?; - - // Only reserve funds if the addition would be safe - T::Currency::reserve(who, additional_bond)?; - - Operators::::insert(who, operator); - - Ok(()) - } - - /// Schedules a native TNT stake reduction for an operator, called - /// by themselves. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// * `unstake_amount` - The amount to be reduced from the operator's stake. - /// - /// # Errors - /// - /// Returns an error if the operator is not found, has active services, or cannot exit. - pub fn process_schedule_operator_unstake( - who: &T::AccountId, - unstake_amount: BalanceOf, - ) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - ensure!(T::ServiceManager::can_exit(who), Error::::CannotExit); - - // Ensure there's no existing unstake request - ensure!(operator.request.is_none(), Error::::PendingUnstakeRequestExists); - - // Ensure the unstake amount doesn't exceed current stake - ensure!(unstake_amount <= operator.stake, Error::::UnstakeAmountTooLarge); - - // Ensure operator maintains minimum required stake after unstaking - let remaining_stake = operator - .stake - .checked_sub(&unstake_amount) - .ok_or(Error::::UnstakeAmountTooLarge)?; - ensure!( - remaining_stake >= T::MinOperatorBondAmount::get(), - Error::::InsufficientStakeRemaining - ); - - operator.request = Some(OperatorBondLessRequest { - amount: unstake_amount, - request_time: Self::current_round(), - }); - Operators::::insert(who, operator); - - Ok(()) - } - - /// Executes a scheduled stake reduction for an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found, has no scheduled stake reduction, or the - /// request is not satisfied. - pub fn process_execute_operator_unstake(who: &T::AccountId) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - let request = operator.request.as_ref().ok_or(Error::::NoScheduledBondLess)?; - let current_round = Self::current_round(); - - ensure!( - current_round >= T::OperatorBondLessDelay::get() + request.request_time, - Error::::BondLessRequestNotSatisfied - ); - - operator.stake = operator - .stake - .checked_sub(&request.amount) - .ok_or(Error::::UnstakeAmountTooLarge)?; - - operator.request = None; - Operators::::insert(who, operator); - - Ok(()) - } - - /// Cancels a scheduled stake reduction for an operator. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found or has no scheduled stake reduction. - pub fn process_cancel_operator_unstake(who: &T::AccountId) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - ensure!(operator.request.is_some(), Error::::NoScheduledBondLess); - - operator.request = None; - Operators::::insert(who, operator); - - Ok(()) - } - - /// Sets the operator status to offline. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found or not currently active. - pub fn process_go_offline(who: &T::AccountId) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - ensure!(operator.status == OperatorStatus::Active, Error::::NotActiveOperator); - - operator.status = OperatorStatus::Inactive; - Operators::::insert(who, operator); - - Ok(()) - } - - /// Sets the operator status to online. - /// - /// # Arguments - /// - /// * `who` - The account ID of the operator. - /// - /// # Errors - /// - /// Returns an error if the operator is not found or not currently inactive. - pub fn process_go_online(who: &T::AccountId) -> Result<(), DispatchError> { - let mut operator = Operators::::get(who).ok_or(Error::::NotAnOperator)?; - ensure!(operator.status == OperatorStatus::Inactive, Error::::NotOfflineOperator); - - operator.status = OperatorStatus::Active; - Operators::::insert(who, operator); - - Ok(()) - } - - pub fn slash_operator( - operator: &T::AccountId, - blueprint_id: BlueprintId, - percentage: Percent, - ) -> Result<(), DispatchError> { - Operators::::try_mutate(operator, |maybe_operator| { - let operator_data = maybe_operator.as_mut().ok_or(Error::::NotAnOperator)?; - ensure!(operator_data.status == OperatorStatus::Active, Error::::NotActiveOperator); - - // Slash operator stake - let amount = percentage.mul_floor(operator_data.stake); - operator_data.stake = operator_data - .stake - .checked_sub(&amount) - .ok_or(Error::::InsufficientStakeRemaining)?; - - // Slash each delegator - for delegator in operator_data.delegations.iter() { - // Ignore errors from individual delegator slashing - let _ = - Self::slash_delegator(&delegator.delegator, operator, blueprint_id, percentage); - } - - // transfer the slashed amount to the treasury - T::Currency::unreserve(operator, amount); - let _ = T::Currency::transfer( - operator, - &T::SlashedAmountRecipient::get(), - amount, - ExistenceRequirement::AllowDeath, - ); - - // emit event - Self::deposit_event(Event::OperatorSlashed { who: operator.clone(), amount }); - - Ok(()) - }) - } -} diff --git a/pallets/rewards/src/functions/rewards.rs b/pallets/rewards/src/functions/rewards.rs deleted file mode 100644 index 23288fce..00000000 --- a/pallets/rewards/src/functions/rewards.rs +++ /dev/null @@ -1,144 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::*, Pallet}; -use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; -use sp_runtime::DispatchError; -use sp_std::vec::Vec; -use tangle_primitives::{services::Asset, RoundIndex}; - -impl Pallet { - #[allow(clippy::type_complexity)] - pub fn distribute_rewards(_round: RoundIndex) -> DispatchResult { - // let mut delegation_info: BTreeMap< - // T::AssetId, - // Vec, T::AssetId>>, - // > = BTreeMap::new(); - - // // Iterate through all operator snapshots for the given round - // // TODO: Could be dangerous with many operators - // for (_, operator_snapshot) in AtStake::::iter_prefix(round) { - // for delegation in &operator_snapshot.delegations { - // delegation_info.entry(delegation.asset_id).or_default().push(delegation.clone()); - // } - // } - - // // Get the reward configuration - // if let Some(reward_config) = RewardConfigStorage::::get() { - // // Distribute rewards for each asset - // for (asset_id, delegations) in delegation_info.iter() { - // // We only reward asset in a reward vault - // if let Some(vault_id) = AssetLookupRewardVaults::::get(asset_id) { - // if let Some(config) = reward_config.configs.get(&vault_id) { - // // Calculate total amount and distribute rewards - // let total_amount: BalanceOf = - // delegations.iter().fold(Zero::zero(), |acc, d| acc + d.amount); - // let cap: BalanceOf = config.cap; - - // if total_amount >= cap { - // // Calculate the total reward based on the APY - // let total_reward = - // Self::calculate_total_reward(config.apy, total_amount)?; - - // for delegation in delegations { - // // Calculate the percentage of the cap that the user is staking - // let staking_percentage = - // delegation.amount.saturating_mul(100u32.into()) / cap; - // // Calculate the reward based on the staking percentage - // let reward = - // total_reward.saturating_mul(staking_percentage) / 100u32.into(); - // // Distribute the reward to the delegator - // Self::distribute_reward_to_delegator( - // &delegation.delegator, - // reward, - // )?; - // } - // } - // } - // } - // } - // } - - Ok(()) - } - - fn _calculate_total_reward( - apy: sp_runtime::Percent, - total_amount: BalanceOf, - ) -> Result, DispatchError> { - let total_reward = apy.mul_floor(total_amount); - Ok(total_reward) - } - - fn _distribute_reward_to_delegator( - delegator: &T::AccountId, - reward: BalanceOf, - ) -> DispatchResult { - // mint rewards to delegator - let _ = T::Currency::deposit_creating(delegator, reward); - Ok(()) - } - - pub fn add_asset_to_vault( - vault_id: &T::VaultId, - asset_id: &Asset, - ) -> DispatchResult { - // Ensure the asset is not already associated with any vault - ensure!( - !AssetLookupRewardVaults::::contains_key(asset_id), - Error::::AssetAlreadyInVault - ); - - // Update RewardVaults storage - RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { - let assets = maybe_assets.get_or_insert_with(Vec::new); - - // Ensure the asset is not already in the vault - ensure!(!assets.contains(asset_id), Error::::AssetAlreadyInVault); - - assets.push(*asset_id); - - Ok(()) - })?; - - // Update AssetLookupRewardVaults storage - AssetLookupRewardVaults::::insert(asset_id, vault_id); - - Ok(()) - } - - pub fn remove_asset_from_vault( - vault_id: &T::VaultId, - asset_id: &Asset, - ) -> DispatchResult { - // Update RewardVaults storage - RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { - let assets = maybe_assets.as_mut().ok_or(Error::::VaultNotFound)?; - - // Ensure the asset is in the vault - ensure!(assets.contains(asset_id), Error::::AssetNotInVault); - - assets.retain(|id| id != asset_id); - - Ok(()) - })?; - - // Update AssetLookupRewardVaults storage - AssetLookupRewardVaults::::remove(asset_id); - - Ok(()) - } -} diff --git a/pallets/rewards/src/functions/session_manager.rs b/pallets/rewards/src/functions/session_manager.rs deleted file mode 100644 index 050f3b70..00000000 --- a/pallets/rewards/src/functions/session_manager.rs +++ /dev/null @@ -1,41 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::*, Pallet}; - -use frame_support::pallet_prelude::DispatchResult; - -impl Pallet { - pub fn handle_round_change() -> DispatchResult { - // Increment the current round - CurrentRound::::mutate(|round| *round += 1); - let current_round = Self::current_round(); - - // Iterate through all operators and build their snapshots - for (operator, metadata) in Operators::::iter() { - // Create the operator snapshot - let snapshot = OperatorSnapshot { - stake: metadata.stake, - delegations: metadata.delegations.clone(), - }; - - // Store the snapshot in AtStake storage - AtStake::::insert(current_round, operator.clone(), snapshot); - } - - Ok(()) - } -} diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 6f6d33dc..5cf8a6a0 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -14,85 +14,73 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -//! # Tangle Multi Asset Delegation Pallet +//! # Tangle Rewards Pallet //! -//! This crate provides the delegation framework for the Tangle network, enabling the delegation of -//! assets to operators for earning rewards. +//! This pallet provides a reward management system for the Tangle network, enabling users to +//! accumulate and claim rewards. //! //! ## Key Components //! -//! - **Operators**: Operators are entities within the Tangle network that can receive delegated -//! assets from delegators. They manage these assets, perform jobs and generate rewards for -//! delegators. -//! - **Deposits**: Depositors must first reserve (deposit) their assets before they can delegate -//! them to operators. This ensures that the assets are locked and available for delegation. -//! - **Delegation**: Delegation is the process where delegators assign their deposited assets to -//! operators to earn rewards. +//! - **Rewards**: Users can earn rewards through various network activities. These rewards are +//! tracked and stored until claimed. +//! - **Claimable Rewards**: The system maintains a record of rewards that are available for +//! claiming by each user. +//! - **Total Rewards**: The system tracks the total amount of rewards that have been distributed +//! across the network. //! -//! ## Workflow for Delegators +//! ## Workflow //! -//! 1. **Deposit**: Before a delegator can delegate assets to an operator, they must first deposit -//! the desired amount of assets. This reserves the assets in the delegator's account. -//! 2. **Delegate**: After depositing assets, the delegator can delegate these assets to an -//! operator. The operator then manages these assets, and the delegator can earn rewards from the -//! operator's activities. -//! 3. **Unstake**: If a delegator wants to reduce their delegation, they can schedule a unstake -//! request. This request will be executed after a specified delay, ensuring network stability. -//! 4. **withdraw Request**: To completely remove assets from delegation, a delegator must submit an -//! withdraw request. Similar to unstake requests, withdraw requests also have a delay before -//! they can be executed. +//! 1. **Earning Rewards**: Users earn rewards through their participation in network activities. +//! These rewards are added to their account by authorized entities. //! -//! ## Workflow for Operators +//! 2. **Claiming Rewards**: Users can claim their accumulated rewards at any time. When claimed, +//! the rewards are transferred to the user's account and removed from their claimable balance. //! -//! - **Join Operators**: An account can join as an operator by depositing a minimum stake amount. -//! This stake is reserved and ensures that the operator has a stake in the network. -//! - **Leave Operators**: Operators can leave the network by scheduling a leave request. This -//! request is subject to a delay, during which the operator's status changes to 'Leaving'. -//! - **Stake More**: Operators can increase their stake to strengthen their stake in the network. -//! - **Stake Less**: Operators can schedule a stake reduction request, which is executed after a -//! delay. -//! - **Go Offline/Online**: Operators can change their status to offline if they need to -//! temporarily stop participating in the network, and can come back online when ready. +//! ## Features +//! +//! - **Secure Storage**: All reward balances are securely stored and tracked on-chain +//! - **Root-Only Additions**: Only root accounts can add rewards, ensuring security +//! - **Safe Transfers**: Claims are validated to ensure sufficient balance before processing +//! - **Event Tracking**: All reward additions and claims are tracked through events + #![cfg_attr(not(feature = "std"), no_std)] pub use pallet::*; -#[cfg(test)] -mod mock; +// #[cfg(test)] +// mod mock; -#[cfg(test)] -mod mock_evm; +// #[cfg(test)] +// mod mock_evm; -#[cfg(test)] -mod tests; +// #[cfg(test)] +// mod tests; -pub mod weights; +// pub mod weights; // #[cfg(feature = "runtime-benchmarks")] // TODO(@1xstj): Fix benchmarking and re-enable // mod benchmarking; -pub mod functions; -pub mod traits; +use scale_info::TypeInfo; +use sp_runtime::Saturating; +use tangle_primitives::services::Asset; pub mod types; -pub use functions::*; +pub use types::*; +/// The pallet's account ID. #[frame_support::pallet] pub mod pallet { - use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; + use super::*; use frame_support::{ pallet_prelude::*, - traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, + traits::{Currency, LockableCurrency, ReservableCurrency}, PalletId, }; + use frame_system::pallet_prelude::*; - use scale_info::TypeInfo; - use sp_core::H160; - use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; - use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; - use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex}; + use sp_runtime::traits::{AccountIdConversion, Zero}; - /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. @@ -104,713 +92,163 @@ pub mod pallet { + LockableCurrency; /// Type representing the unique ID of an asset. - type AssetId: Parameter - + Member - + Copy - + MaybeSerializeDeserialize - + Ord - + Default - + MaxEncodedLen - + Encode - + Decode - + TypeInfo; - - /// Type representing the unique ID of a vault. - type VaultId: Parameter - + Member - + Copy - + MaybeSerializeDeserialize - + Ord - + Default - + MaxEncodedLen - + TypeInfo; - - /// The maximum number of blueprints a delegator can have in Fixed mode. - #[pallet::constant] - type MaxDelegatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - - /// The maximum number of blueprints an operator can support. - #[pallet::constant] - type MaxOperatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - - /// The maximum number of withdraw requests a delegator can have. - #[pallet::constant] - type MaxWithdrawRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - - /// The maximum number of delegations a delegator can have. - #[pallet::constant] - type MaxDelegations: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - - /// The maximum number of unstake requests a delegator can have. - #[pallet::constant] - type MaxUnstakeRequests: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; - - /// The minimum amount of stake required for an operator. - #[pallet::constant] - type MinOperatorBondAmount: Get>; - - /// The minimum amount of stake required for a delegate. - #[pallet::constant] - type MinDelegateAmount: Get>; - - /// The duration for which the stake is locked. - #[pallet::constant] - type BondDuration: Get; - - /// The service manager that manages active services. - type ServiceManager: ServiceManager>; - - /// Number of rounds that operators remain bonded before the exit request is executable. - #[pallet::constant] - type LeaveOperatorsDelay: Get; - - /// Number of rounds operator requests to decrease self-stake must wait to be executable. - #[pallet::constant] - type OperatorBondLessDelay: Get; - - /// Number of rounds that delegators remain bonded before the exit request is executable. - #[pallet::constant] - type LeaveDelegatorsDelay: Get; - - /// Number of rounds that delegation unstake requests must wait before being executable. - #[pallet::constant] - type DelegationBondLessDelay: Get; - - /// The fungibles trait used for managing fungible assets. - type Fungibles: fungibles::Inspect> - + fungibles::Mutate; + type AssetId: Parameter + Member + Copy + Ord + Default + MaxEncodedLen + TypeInfo; /// The pallet's account ID. type PalletId: Get; - /// The origin with privileged access + /// The origin that can manage reward assets type ForceOrigin: EnsureOrigin; - - /// The address that receives slashed funds - type SlashedAmountRecipient: Get; - - /// A type that implements the `EvmRunner` trait for the execution of EVM - /// transactions. - type EvmRunner: tangle_primitives::services::EvmRunner; - - /// A type that implements the `EvmGasWeightMapping` trait for the conversion of EVM gas to - /// Substrate weight and vice versa. - type EvmGasWeightMapping: tangle_primitives::services::EvmGasWeightMapping; - - /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address - type EvmAddressMapping: tangle_primitives::services::EvmAddressMapping; - - /// A type representing the weights required by the dispatchables of this pallet. - type WeightInfo: crate::weights::WeightInfo; } - /// The pallet struct. #[pallet::pallet] #[pallet::without_storage_info] pub struct Pallet(_); - /// Storage for operator information. + /// Stores the user rewards for each user and asset combination #[pallet::storage] - #[pallet::getter(fn operator_info)] - pub type Operators = - StorageMap<_, Blake2_128Concat, T::AccountId, OperatorMetadataOf>; - - /// Storage for the current round. - #[pallet::storage] - #[pallet::getter(fn current_round)] - pub type CurrentRound = StorageValue<_, RoundIndex, ValueQuery>; - - /// Snapshot of collator delegation stake at the start of the round. - #[pallet::storage] - #[pallet::getter(fn at_stake)] - pub type AtStake = StorageDoubleMap< + #[pallet::getter(fn user_rewards)] + pub type UserRewards = StorageDoubleMap< _, Blake2_128Concat, - RoundIndex, - Blake2_128Concat, T::AccountId, - OperatorSnapshotOf, - OptionQuery, + Blake2_128Concat, + Asset, + UserRewardsOf, + ValueQuery, >; - /// Storage for delegator information. - #[pallet::storage] - #[pallet::getter(fn delegators)] - pub type Delegators = - StorageMap<_, Blake2_128Concat, T::AccountId, DelegatorMetadataOf>; - - #[pallet::storage] - #[pallet::getter(fn reward_vaults)] - /// Storage for the reward vaults - pub type RewardVaults = - StorageMap<_, Blake2_128Concat, T::VaultId, Vec>, OptionQuery>; - + /// Stores the whitelisted assets that can be used for rewards #[pallet::storage] - #[pallet::getter(fn asset_reward_vault_lookup)] - /// Storage for the reward vaults - pub type AssetLookupRewardVaults = - StorageMap<_, Blake2_128Concat, Asset, T::VaultId, OptionQuery>; + #[pallet::getter(fn allowed_reward_assets)] + pub type AllowedRewardAssets = + StorageMap<_, Blake2_128Concat, Asset, bool, ValueQuery>; - #[pallet::storage] - #[pallet::getter(fn reward_config)] - /// Storage for the reward configuration, which includes APY, cap for assets, and whitelisted - /// blueprints. - pub type RewardConfigStorage = - StorageValue<_, RewardConfig>, OptionQuery>; + type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; - /// Events emitted by the pallet. #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - /// An operator has joined. - OperatorJoined { who: T::AccountId }, - /// An operator has scheduled to leave. - OperatorLeavingScheduled { who: T::AccountId }, - /// An operator has cancelled their leave request. - OperatorLeaveCancelled { who: T::AccountId }, - /// An operator has executed their leave request. - OperatorLeaveExecuted { who: T::AccountId }, - /// An operator has increased their stake. - OperatorBondMore { who: T::AccountId, additional_bond: BalanceOf }, - /// An operator has scheduled to decrease their stake. - OperatorBondLessScheduled { who: T::AccountId, unstake_amount: BalanceOf }, - /// An operator has executed their stake decrease. - OperatorBondLessExecuted { who: T::AccountId }, - /// An operator has cancelled their stake decrease request. - OperatorBondLessCancelled { who: T::AccountId }, - /// An operator has gone offline. - OperatorWentOffline { who: T::AccountId }, - /// An operator has gone online. - OperatorWentOnline { who: T::AccountId }, - /// A deposit has been made. - Deposited { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, - /// An withdraw has been scheduled. - Scheduledwithdraw { who: T::AccountId, amount: BalanceOf, asset_id: Asset }, - /// An withdraw has been executed. - Executedwithdraw { who: T::AccountId }, - /// An withdraw has been cancelled. - Cancelledwithdraw { who: T::AccountId }, - /// A delegation has been made. - Delegated { - who: T::AccountId, - operator: T::AccountId, + /// Rewards have been added for an account + RewardsAdded { + account: T::AccountId, + asset: Asset, amount: BalanceOf, - asset_id: Asset, + reward_type: RewardType, }, - /// A delegator unstake request has been scheduled. - ScheduledDelegatorBondLess { - who: T::AccountId, - operator: T::AccountId, + /// Rewards have been claimed by an account + RewardsClaimed { + account: T::AccountId, + asset: Asset, amount: BalanceOf, - asset_id: Asset, - }, - /// A delegator unstake request has been executed. - ExecutedDelegatorBondLess { who: T::AccountId }, - /// A delegator unstake request has been cancelled. - CancelledDelegatorBondLess { who: T::AccountId }, - /// Event emitted when an incentive APY and cap are set for a reward vault - IncentiveAPYAndCapSet { vault_id: T::VaultId, apy: sp_runtime::Percent, cap: BalanceOf }, - /// Event emitted when a blueprint is whitelisted for rewards - BlueprintWhitelisted { blueprint_id: u32 }, - /// Asset has been updated to reward vault - AssetUpdatedInVault { - who: T::AccountId, - vault_id: T::VaultId, - asset_id: Asset, - action: AssetAction, + reward_type: RewardType, }, - /// Operator has been slashed - OperatorSlashed { who: T::AccountId, amount: BalanceOf }, - /// Delegator has been slashed - DelegatorSlashed { who: T::AccountId, amount: BalanceOf }, - /// EVM execution reverted with a reason. - EvmReverted { from: H160, to: H160, data: Vec, reason: Vec }, + /// Asset has been whitelisted for rewards + AssetWhitelisted { asset: Asset }, + /// Asset has been removed from whitelist + AssetRemoved { asset: Asset }, + } + + /// Type of reward being added or claimed + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] + pub enum RewardType { + Restaking, + Boost, + Service, } - /// Errors emitted by the pallet. #[pallet::error] pub enum Error { - /// The account is already an operator. - AlreadyOperator, - /// The stake amount is too low. - BondTooLow, - /// The account is not an operator. - NotAnOperator, - /// The account cannot exit. - CannotExit, - /// The operator is already leaving. - AlreadyLeaving, - /// The account is not leaving as an operator. - NotLeavingOperator, - /// The round does not match the scheduled leave round. - NotLeavingRound, - /// Leaving round not reached - LeavingRoundNotReached, - /// There is no scheduled unstake request. - NoScheduledBondLess, - /// The unstake request is not satisfied. - BondLessRequestNotSatisfied, - /// The operator is not active. - NotActiveOperator, - /// The operator is not offline. - NotOfflineOperator, - /// The account is already a delegator. - AlreadyDelegator, - /// The account is not a delegator. - NotDelegator, - /// A withdraw request already exists. - WithdrawRequestAlreadyExists, - /// The account has insufficient balance. - InsufficientBalance, - /// There is no withdraw request. - NoWithdrawRequest, - /// There is no unstake request. - NoBondLessRequest, - /// The unstake request is not ready. - BondLessNotReady, - /// A unstake request already exists. - BondLessRequestAlreadyExists, - /// There are active services using the asset. - ActiveServicesUsingAsset, - /// There is not active delegation - NoActiveDelegation, - /// The asset is not whitelisted + /// No rewards available to claim + NoRewardsAvailable, + /// Insufficient rewards balance in pallet account + InsufficientRewardsBalance, + /// Asset is not whitelisted for rewards AssetNotWhitelisted, - /// The origin is not authorized to perform this action - NotAuthorized, - /// Maximum number of blueprints exceeded - MaxBlueprintsExceeded, - /// The asset ID is not found - AssetNotFound, - /// The blueprint ID is already whitelisted - BlueprintAlreadyWhitelisted, - /// No withdraw requests found - NowithdrawRequests, - /// No matching withdraw reqests found - NoMatchingwithdrawRequest, - /// Asset already exists in a reward vault - AssetAlreadyInVault, - /// Asset not found in reward vault - AssetNotInVault, - /// The reward vault does not exist - VaultNotFound, - /// Error returned when trying to add a blueprint ID that already exists. - DuplicateBlueprintId, - /// Error returned when trying to remove a blueprint ID that doesn't exist. - BlueprintIdNotFound, - /// Error returned when trying to add/remove blueprint IDs while not in Fixed mode. - NotInFixedMode, - /// Error returned when the maximum number of delegations is exceeded. - MaxDelegationsExceeded, - /// Error returned when the maximum number of unstake requests is exceeded. - MaxUnstakeRequestsExceeded, - /// Error returned when the maximum number of withdraw requests is exceeded. - MaxWithdrawRequestsExceeded, - /// Deposit amount overflow - DepositOverflow, - /// Unstake underflow - UnstakeAmountTooLarge, - /// Overflow while adding stake - StakeOverflow, - /// Underflow while reducing stake - InsufficientStakeRemaining, - /// APY exceeds maximum allowed by the extrinsic - APYExceedsMaximum, - /// Cap cannot be zero - CapCannotBeZero, - /// Cap exceeds total supply of asset - CapExceedsTotalSupply, - /// An unstake request is already pending - PendingUnstakeRequestExists, - /// The blueprint is not selected - BlueprintNotSelected, - /// Erc20 transfer failed - ERC20TransferFailed, - /// EVM encode error - EVMAbiEncode, - /// EVM decode error - EVMAbiDecode, + /// Asset is already whitelisted + AssetAlreadyWhitelisted, } - /// Hooks for the pallet. - #[pallet::hooks] - impl Hooks> for Pallet {} - - /// The callable functions (extrinsics) of the pallet. #[pallet::call] impl Pallet { - /// Allows an account to join as an operator by providing a stake. - #[pallet::call_index(0)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn join_operators(origin: OriginFor, bond_amount: BalanceOf) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::handle_deposit_and_create_operator(who.clone(), bond_amount)?; - Self::deposit_event(Event::OperatorJoined { who }); - Ok(()) - } - - /// Schedules an operator to leave. - #[pallet::call_index(1)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn schedule_leave_operators(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_leave_operator(&who)?; - Self::deposit_event(Event::OperatorLeavingScheduled { who }); - Ok(()) - } - - /// Cancels a scheduled leave for an operator. - #[pallet::call_index(2)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn cancel_leave_operators(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_cancel_leave_operator(&who)?; - Self::deposit_event(Event::OperatorLeaveCancelled { who }); - Ok(()) - } - - /// Executes a scheduled leave for an operator. - #[pallet::call_index(3)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn execute_leave_operators(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_execute_leave_operators(&who)?; - Self::deposit_event(Event::OperatorLeaveExecuted { who }); - Ok(()) - } - - /// Allows an operator to increase their stake. - #[pallet::call_index(4)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn operator_bond_more( - origin: OriginFor, - additional_bond: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_operator_bond_more(&who, additional_bond)?; - Self::deposit_event(Event::OperatorBondMore { who, additional_bond }); - Ok(()) - } - - /// Schedules an operator to decrease their stake. - #[pallet::call_index(5)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn schedule_operator_unstake( - origin: OriginFor, - unstake_amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_schedule_operator_unstake(&who, unstake_amount)?; - Self::deposit_event(Event::OperatorBondLessScheduled { who, unstake_amount }); - Ok(()) - } - - /// Executes a scheduled stake decrease for an operator. - #[pallet::call_index(6)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn execute_operator_unstake(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_execute_operator_unstake(&who)?; - Self::deposit_event(Event::OperatorBondLessExecuted { who }); - Ok(()) - } - - /// Cancels a scheduled stake decrease for an operator. - #[pallet::call_index(7)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn cancel_operator_unstake(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_cancel_operator_unstake(&who)?; - Self::deposit_event(Event::OperatorBondLessCancelled { who }); - Ok(()) - } - - /// Allows an operator to go offline. - #[pallet::call_index(8)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn go_offline(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_go_offline(&who)?; - Self::deposit_event(Event::OperatorWentOffline { who }); - Ok(()) - } - - /// Allows an operator to go online. - #[pallet::call_index(9)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn go_online(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_go_online(&who)?; - Self::deposit_event(Event::OperatorWentOnline { who }); - Ok(()) - } - - /// Allows a user to deposit an asset. - #[pallet::call_index(10)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn deposit( + /// Claim rewards for a specific asset and reward type + #[pallet::weight(10_000)] + pub fn claim_rewards( origin: OriginFor, - asset_id: Asset, - amount: BalanceOf, - evm_address: Option, + asset: Asset, + reward_type: RewardType, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::process_deposit(who.clone(), asset_id, amount, evm_address)?; - Self::deposit_event(Event::Deposited { who, amount, asset_id }); - Ok(()) - } + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - /// Schedules an withdraw request. - #[pallet::call_index(11)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn schedule_withdraw( - origin: OriginFor, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_schedule_withdraw(who.clone(), asset_id, amount)?; - Self::deposit_event(Event::Scheduledwithdraw { who, amount, asset_id }); - Ok(()) - } + let mut amount = BalanceOf::::zero(); - /// Executes a scheduled withdraw request. - #[pallet::call_index(12)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn execute_withdraw(origin: OriginFor, evm_address: Option) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_execute_withdraw(who.clone(), evm_address)?; - Self::deposit_event(Event::Executedwithdraw { who }); - Ok(()) - } + // TODO : Implement helper function to get this value out + // UserRewards::::mutate(who.clone(), asset, |rewards| { + // amount = match reward_type { + // RewardType::Restaking => std::mem::take(&mut rewards.restaking_rewards), + // RewardType::Boost => std::mem::take(&mut rewards.boost_rewards), + // RewardType::Service => std::mem::take(&mut rewards.service_rewards), + // }; + // }); - /// Cancels a scheduled withdraw request. - #[pallet::call_index(13)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn cancel_withdraw( - origin: OriginFor, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_cancel_withdraw(who.clone(), asset_id, amount)?; - Self::deposit_event(Event::Cancelledwithdraw { who }); - Ok(()) - } + ensure!(!amount.is_zero(), Error::::NoRewardsAvailable); - /// Allows a user to delegate an amount of an asset to an operator. - #[pallet::call_index(14)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn delegate( - origin: OriginFor, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - blueprint_selection: DelegatorBlueprintSelection, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_delegate( - who.clone(), - operator.clone(), - asset_id, - amount, - blueprint_selection, - )?; - Self::deposit_event(Event::Delegated { who, operator, asset_id, amount }); - Ok(()) - } + let pallet_account = Self::account_id(); + ensure!( + T::Currency::free_balance(&pallet_account) >= amount, + Error::::InsufficientRewardsBalance + ); - /// Schedules a request to reduce a delegator's stake. - #[pallet::call_index(15)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn schedule_delegator_unstake( - origin: OriginFor, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_schedule_delegator_unstake( - who.clone(), - operator.clone(), - asset_id, + T::Currency::transfer( + &pallet_account, + &who, amount, + frame_support::traits::ExistenceRequirement::KeepAlive, )?; - Self::deposit_event(Event::ScheduledDelegatorBondLess { - who, - asset_id, - operator, - amount, - }); - Ok(()) - } - /// Executes a scheduled request to reduce a delegator's stake. - #[pallet::call_index(16)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn execute_delegator_unstake(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_execute_delegator_unstake(who.clone())?; - Self::deposit_event(Event::ExecutedDelegatorBondLess { who }); - Ok(()) - } + Self::deposit_event(Event::RewardsClaimed { account: who, asset, amount, reward_type }); - /// Cancels a scheduled request to reduce a delegator's stake. - #[pallet::call_index(17)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn cancel_delegator_unstake( - origin: OriginFor, - operator: T::AccountId, - asset_id: Asset, - amount: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::process_cancel_delegator_unstake(who.clone(), operator, asset_id, amount)?; - Self::deposit_event(Event::CancelledDelegatorBondLess { who }); Ok(()) } - /// Sets the APY and cap for a specific asset. - /// The APY is the annual percentage yield that the asset will earn. - /// The cap is the amount of assets required to be deposited to distribute the entire APY. - /// The APY is capped at 10% and will require runtime upgrade to change. - /// - /// While the cap is not met, the APY distributed will be `amount_deposited / cap * APY`. - #[pallet::call_index(18)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn set_incentive_apy_and_cap( - origin: OriginFor, - vault_id: T::VaultId, - apy: sp_runtime::Percent, - cap: BalanceOf, - ) -> DispatchResult { - // Ensure that the origin is authorized + /// Add an asset to the whitelist of allowed reward assets + #[pallet::weight(10_000)] + pub fn whitelist_asset(origin: OriginFor, asset: Asset) -> DispatchResult { T::ForceOrigin::ensure_origin(origin)?; - // Validate APY is not greater than 10% - ensure!(apy <= sp_runtime::Percent::from_percent(10), Error::::APYExceedsMaximum); - - // Validate cap is not zero - ensure!(!cap.is_zero(), Error::::CapCannotBeZero); + ensure!(!AllowedRewardAssets::::get(&asset), Error::::AssetAlreadyWhitelisted); - // Initialize the reward config if not already initialized - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); - - config.configs.insert(vault_id, RewardConfigForAssetVault { apy, cap }); - - *maybe_config = Some(config); - }); - - // Emit an event - Self::deposit_event(Event::IncentiveAPYAndCapSet { vault_id, apy, cap }); + AllowedRewardAssets::::insert(asset, true); + Self::deposit_event(Event::AssetWhitelisted { asset }); Ok(()) } - /// Whitelists a blueprint for rewards. - #[pallet::call_index(19)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn whitelist_blueprint_for_rewards( - origin: OriginFor, - blueprint_id: u32, - ) -> DispatchResult { - // Ensure that the origin is authorized + /// Remove an asset from the whitelist + #[pallet::weight(10_000)] + pub fn remove_asset(origin: OriginFor, asset: Asset) -> DispatchResult { T::ForceOrigin::ensure_origin(origin)?; - // Initialize the reward config if not already initialized - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); - - if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { - config.whitelisted_blueprint_ids.push(blueprint_id); - } + ensure!(AllowedRewardAssets::::get(&asset), Error::::AssetNotWhitelisted); - *maybe_config = Some(config); - }); - - // Emit an event - Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); - - Ok(()) - } - - /// Manage asset id to vault rewards - #[pallet::call_index(20)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn manage_asset_in_vault( - origin: OriginFor, - vault_id: T::VaultId, - asset_id: Asset, - action: AssetAction, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - match action { - AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, - AssetAction::Remove => Self::remove_asset_from_vault(&vault_id, &asset_id)?, - } - - Self::deposit_event(Event::AssetUpdatedInVault { who, vault_id, asset_id, action }); + AllowedRewardAssets::::remove(asset); + Self::deposit_event(Event::AssetRemoved { asset }); Ok(()) } + } - /// Adds a blueprint ID to a delegator's selection. - #[pallet::call_index(22)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn add_blueprint_id(origin: OriginFor, blueprint_id: BlueprintId) -> DispatchResult { - let who = ensure_signed(origin)?; - let mut metadata = Self::delegators(&who).ok_or(Error::::NotDelegator)?; - - // Update blueprint selection for all delegations - for delegation in metadata.delegations.iter_mut() { - match delegation.blueprint_selection { - DelegatorBlueprintSelection::Fixed(ref mut ids) => { - ensure!(!ids.contains(&blueprint_id), Error::::DuplicateBlueprintId); - ids.try_push(blueprint_id) - .map_err(|_| Error::::MaxBlueprintsExceeded)?; - }, - _ => return Err(Error::::NotInFixedMode.into()), - } - } - - Delegators::::insert(&who, metadata); - Ok(()) + impl Pallet { + /// The account ID of the rewards pot. + pub fn account_id() -> T::AccountId { + T::PalletId::get().into_account_truncating() } - /// Removes a blueprint ID from a delegator's selection. - #[pallet::call_index(23)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn remove_blueprint_id( - origin: OriginFor, - blueprint_id: BlueprintId, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - let mut metadata = Self::delegators(&who).ok_or(Error::::NotDelegator)?; - - // Update blueprint selection for all delegations - for delegation in metadata.delegations.iter_mut() { - match delegation.blueprint_selection { - DelegatorBlueprintSelection::Fixed(ref mut ids) => { - let pos = ids - .iter() - .position(|&id| id == blueprint_id) - .ok_or(Error::::BlueprintIdNotFound)?; - ids.remove(pos); - }, - _ => return Err(Error::::NotInFixedMode.into()), - } - } - - Delegators::::insert(&who, metadata); - Ok(()) + /// Check if an asset is whitelisted for rewards + pub fn is_asset_whitelisted(asset: Asset) -> bool { + AllowedRewardAssets::::get(&asset) } } } diff --git a/pallets/rewards/src/traits.rs b/pallets/rewards/src/traits.rs index 653ad9ef..d497dc0d 100644 --- a/pallets/rewards/src/traits.rs +++ b/pallets/rewards/src/traits.rs @@ -14,59 +14,143 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::types::{BalanceOf, OperatorStatus}; +use crate::types::{BalanceOf, LockMultiplier, OperatorStatus}; use sp_runtime::{traits::Zero, Percent}; use sp_std::prelude::*; use tangle_primitives::{ services::Asset, traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex, }; -impl MultiAssetDelegationInfo> for crate::Pallet { - type AssetId = T::AssetId; +/// Trait for handling reward operations +pub trait RewardsHandler { + /// Record rewards for a specific user and asset + fn record_rewards( + beneficiary: AccountId, + asset: Asset, + amount: Balance, + reward_type: RewardType, + boost_multiplier: Option, + boost_expiry: Option<::BlockNumber>, + ) -> DispatchResult; - fn get_current_round() -> RoundIndex { - Self::current_round() - } + /// Record a deposit for a specific account and asset with a lock multiplier + fn record_deposit( + account_id: AccountId, + asset_id: AssetId, + amount: Balance, + lock_multiplier: LockMultiplier, + ) -> DispatchResult; - fn is_operator(operator: &T::AccountId) -> bool { - Operators::::get(operator).is_some() - } + /// Query the deposit for a specific account and asset + fn query_deposit(account_id: AccountId, asset_id: AssetId) -> Balance; + + /// Record a service payment for a specific account and asset + fn record_service_payment( + account_id: AccountId, + asset_id: AssetId, + amount: Balance, + ) -> DispatchResult; + + /// Check if an asset is whitelisted for rewards + fn is_asset_whitelisted(asset: Asset) -> bool; +} + +impl RewardsHandler> for crate::Pallet { + fn record_rewards( + beneficiary: T::AccountId, + asset: Asset, + amount: BalanceOf, + reward_type: RewardType, + boost_multiplier: Option, + boost_expiry: Option, + ) -> DispatchResult { + // Check if asset is whitelisted + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); + + // Update rewards storage + UserRewards::::mutate(beneficiary.clone(), asset, |rewards| { + match reward_type { + RewardType::Restaking => { + rewards.restaking_rewards = rewards.restaking_rewards.saturating_add(amount); + }, + RewardType::Boost => { + if let (Some(multiplier), Some(expiry)) = (boost_multiplier, boost_expiry) { + rewards.boost_rewards = BoostInfo { + amount: rewards.boost_rewards.amount.saturating_add(amount), + multiplier, + expiry, + }; + } + }, + RewardType::Service => { + rewards.service_rewards = rewards.service_rewards.saturating_add(amount); + }, + } + }); - fn is_operator_active(operator: &T::AccountId) -> bool { - Operators::::get(operator) - .map_or(false, |metadata| matches!(metadata.status, OperatorStatus::Active)) + // Emit event + Self::deposit_event(Event::RewardsAdded { + account: beneficiary, + asset, + amount, + reward_type, + boost_multiplier, + boost_expiry, + }); + + Ok(()) } - fn get_operator_stake(operator: &T::AccountId) -> BalanceOf { - Operators::::get(operator).map_or(Zero::zero(), |metadata| metadata.stake) + fn record_deposit( + account_id: T::AccountId, + asset_id: T::AssetId, + amount: BalanceOf, + lock_multiplier: LockMultiplier, + ) -> DispatchResult { + let asset = Asset::new(asset_id); + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); + + UserRewards::::mutate(account_id.clone(), asset, |rewards| { + rewards.restaking_rewards = rewards.restaking_rewards.saturating_add(amount); + }); + + Self::deposit_event(Event::DepositRecorded { + account: account_id, + asset, + amount, + lock_multiplier, + }); + + Ok(()) } - fn get_total_delegation_by_asset_id( - operator: &T::AccountId, - asset_id: &Asset, - ) -> BalanceOf { - Operators::::get(operator).map_or(Zero::zero(), |metadata| { - metadata - .delegations - .iter() - .filter(|stake| &stake.asset_id == asset_id) - .fold(Zero::zero(), |acc, stake| acc + stake.amount) - }) + fn query_deposit(account_id: T::AccountId, asset_id: T::AssetId) -> BalanceOf { + let asset = Asset::new(asset_id); + UserRewards::::get(account_id, asset).restaking_rewards } - fn get_delegators_for_operator( - operator: &T::AccountId, - ) -> Vec<(T::AccountId, BalanceOf, Asset)> { - Operators::::get(operator).map_or(Vec::new(), |metadata| { - metadata - .delegations - .iter() - .map(|stake| (stake.delegator.clone(), stake.amount, stake.asset_id)) - .collect() - }) + fn record_service_payment( + account_id: T::AccountId, + asset_id: T::AssetId, + amount: BalanceOf, + ) -> DispatchResult { + let asset = Asset::new(asset_id); + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); + + UserRewards::::mutate(account_id.clone(), asset, |rewards| { + rewards.service_rewards = rewards.service_rewards.saturating_add(amount); + }); + + Self::deposit_event(Event::ServicePaymentRecorded { + account: account_id, + asset, + amount, + }); + + Ok(()) } - fn slash_operator(operator: &T::AccountId, blueprint_id: BlueprintId, percentage: Percent) { - let _ = Pallet::::slash_operator(operator, blueprint_id, percentage); + fn is_asset_whitelisted(asset: Asset) -> bool { + AllowedRewardAssets::::get(&asset) } } diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index a1b0cb4d..f3adb918 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -16,44 +16,82 @@ use crate::Config; use frame_support::traits::Currency; +use frame_system::pallet_prelude::BlockNumberFor; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; -use tangle_primitives::types::RoundIndex; +use tangle_primitives::{services::Asset, types::RoundIndex}; -pub mod delegator; -pub mod operator; -pub mod rewards; +/// Represents different types of rewards a user can earn +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct UserRewards { + /// Rewards earned from restaking (in TNT) + pub restaking_rewards: Balance, + /// Boost rewards information + pub boost_rewards: BoostInfo, + /// Service rewards in their respective assets + pub service_rewards: Balance, +} -pub use delegator::*; -pub use operator::*; -pub use rewards::*; +pub type UserRewardsOf = UserRewards, BlockNumberFor>; + +/// Information about a user's boost rewards +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct BoostInfo { + /// Amount of boost rewards + pub amount: Balance, + /// Multiplier for the boost (e.g. OneMonth = 1x, TwoMonths = 2x) + pub multiplier: LockMultiplier, + /// Block number when the boost expires + pub expiry: BlockNumber, +} + +impl Default for BoostInfo { + fn default() -> Self { + Self { + amount: Balance::default(), + multiplier: LockMultiplier::OneMonth, + expiry: BlockNumber::default(), + } + } +} + +impl Default for UserRewards { + fn default() -> Self { + Self { + restaking_rewards: Balance::default(), + boost_rewards: BoostInfo::default(), + service_rewards: Balance::default(), + } + } +} pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type OperatorMetadataOf = OperatorMetadata< - ::AccountId, - BalanceOf, - ::AssetId, - ::MaxDelegations, - ::MaxOperatorBlueprints, ->; - -pub type OperatorSnapshotOf = OperatorSnapshot< - ::AccountId, - BalanceOf, - ::AssetId, - ::MaxDelegations, ->; - -pub type DelegatorMetadataOf = DelegatorMetadata< - ::AccountId, - BalanceOf, - ::AssetId, - ::MaxWithdrawRequests, - ::MaxDelegations, - ::MaxUnstakeRequests, - ::MaxDelegatorBlueprints, ->; +/// Lock multiplier for rewards, representing months of lock period +#[derive(Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub enum LockMultiplier { + /// One month lock period (1x multiplier) + OneMonth = 1, + /// Two months lock period (2x multiplier) + TwoMonths = 2, + /// Three months lock period (3x multiplier) + ThreeMonths = 3, + /// Six months lock period (6x multiplier) + SixMonths = 6, +} + +impl Default for LockMultiplier { + fn default() -> Self { + Self::OneMonth + } +} + +impl LockMultiplier { + /// Get the multiplier value + pub fn value(&self) -> u32 { + *self as u32 + } +} diff --git a/pallets/rewards/src/types/delegator.rs b/pallets/rewards/src/types/delegator.rs deleted file mode 100644 index 774b8f46..00000000 --- a/pallets/rewards/src/types/delegator.rs +++ /dev/null @@ -1,219 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -use super::*; -use frame_support::{pallet_prelude::Get, BoundedVec}; -use tangle_primitives::{services::Asset, BlueprintId}; - -/// Represents how a delegator selects which blueprints to work with. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] -pub enum DelegatorBlueprintSelection> { - /// The delegator works with a fixed set of blueprints. - Fixed(BoundedVec), - /// The delegator works with all available blueprints. - All, -} - -impl> Default for DelegatorBlueprintSelection { - fn default() -> Self { - DelegatorBlueprintSelection::Fixed(Default::default()) - } -} - -/// Represents the status of a delegator. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] -pub enum DelegatorStatus { - /// The delegator is active. - #[default] - Active, - /// The delegator has scheduled an exit to revoke all ongoing delegations. - LeavingScheduled(RoundIndex), -} - -/// Represents a request to withdraw a specific amount of an asset. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct WithdrawRequest { - /// The ID of the asset to be withdrawd. - pub asset_id: Asset, - /// The amount of the asset to be withdrawd. - pub amount: Balance, - /// The round in which the withdraw was requested. - pub requested_round: RoundIndex, -} - -/// Represents a request to reduce the bonded amount of a specific asset. -#[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct BondLessRequest> { - /// The account ID of the operator. - pub operator: AccountId, - /// The ID of the asset to reduce the stake of. - pub asset_id: Asset, - /// The amount by which to reduce the stake. - pub amount: Balance, - /// The round in which the stake reduction was requested. - pub requested_round: RoundIndex, - /// The blueprint selection of the delegator. - pub blueprint_selection: DelegatorBlueprintSelection, -} - -/// Stores the state of a delegator, including deposits, delegations, and requests. -#[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct DelegatorMetadata< - AccountId, - Balance, - AssetId: Encode + Decode + TypeInfo, - MaxWithdrawRequests: Get, - MaxDelegations: Get, - MaxUnstakeRequests: Get, - MaxBlueprints: Get, -> { - /// A map of deposited assets and their respective amounts. - pub deposits: BTreeMap, Balance>, - /// A vector of withdraw requests. - pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, - /// A list of all current delegations. - pub delegations: - BoundedVec, MaxDelegations>, - /// A vector of requests to reduce the bonded amount. - pub delegator_unstake_requests: - BoundedVec, MaxUnstakeRequests>, - /// The current status of the delegator. - pub status: DelegatorStatus, -} - -impl< - AccountId, - Balance, - AssetId: Encode + Decode + TypeInfo, - MaxWithdrawRequests: Get, - MaxDelegations: Get, - MaxUnstakeRequests: Get, - MaxBlueprints: Get, - > Default - for DelegatorMetadata< - AccountId, - Balance, - AssetId, - MaxWithdrawRequests, - MaxDelegations, - MaxUnstakeRequests, - MaxBlueprints, - > -{ - fn default() -> Self { - DelegatorMetadata { - deposits: BTreeMap::new(), - delegations: BoundedVec::default(), - status: DelegatorStatus::default(), - withdraw_requests: BoundedVec::default(), - delegator_unstake_requests: BoundedVec::default(), - } - } -} - -impl< - AccountId, - Balance, - AssetId: Encode + Decode + TypeInfo, - MaxWithdrawRequests: Get, - MaxDelegations: Get, - MaxUnstakeRequests: Get, - MaxBlueprints: Get, - > - DelegatorMetadata< - AccountId, - Balance, - AssetId, - MaxWithdrawRequests, - MaxDelegations, - MaxUnstakeRequests, - MaxBlueprints, - > -{ - /// Returns a reference to the vector of withdraw requests. - pub fn get_withdraw_requests(&self) -> &Vec> { - &self.withdraw_requests - } - - /// Returns a reference to the list of delegations. - pub fn get_delegations( - &self, - ) -> &Vec> { - &self.delegations - } - - /// Returns a reference to the vector of unstake requests. - pub fn get_delegator_unstake_requests( - &self, - ) -> &Vec> { - &self.delegator_unstake_requests - } - - /// Checks if the list of delegations is empty. - pub fn is_delegations_empty(&self) -> bool { - self.delegations.is_empty() - } - - /// Calculates the total delegation amount for a specific asset. - pub fn calculate_delegation_by_asset(&self, asset_id: Asset) -> Balance - // Asset) -> Balance - where - Balance: Default + core::ops::AddAssign + Clone, - AssetId: Eq + PartialEq, - { - let mut total = Balance::default(); - for stake in &self.delegations { - if stake.asset_id == asset_id { - total += stake.amount.clone(); - } - } - total - } - - /// Returns a list of delegations to a specific operator. - pub fn calculate_delegation_by_operator( - &self, - operator: AccountId, - ) -> Vec<&BondInfoDelegator> - where - AccountId: Eq + PartialEq, - { - self.delegations.iter().filter(|&stake| stake.operator == operator).collect() - } -} - -/// Represents a deposit of a specific asset. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct Deposit { - /// The amount of the asset deposited. - pub amount: Balance, - /// The ID of the deposited asset. - pub asset_id: Asset, -} - -/// Represents a stake between a delegator and an operator. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct BondInfoDelegator> -{ - /// The account ID of the operator. - pub operator: AccountId, - /// The amount bonded. - pub amount: Balance, - /// The ID of the bonded asset. - pub asset_id: Asset, - /// The blueprint selection mode for this delegator. - pub blueprint_selection: DelegatorBlueprintSelection, -} diff --git a/pallets/rewards/src/types/operator.rs b/pallets/rewards/src/types/operator.rs deleted file mode 100644 index e0e7ca27..00000000 --- a/pallets/rewards/src/types/operator.rs +++ /dev/null @@ -1,139 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -use super::*; -use frame_support::{pallet_prelude::*, BoundedVec}; -use tangle_primitives::services::Asset; - -/// A snapshot of the operator state at the start of the round. -#[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct OperatorSnapshot> -{ - /// The total value locked by the operator. - pub stake: Balance, - - /// The rewardable delegations. This list is a subset of total delegators, where certain - /// delegators are adjusted based on their scheduled status. - pub delegations: BoundedVec, MaxDelegations>, -} - -impl> - OperatorSnapshot -where - AssetId: PartialEq + Ord + Copy, - Balance: Default + core::ops::AddAssign + Copy, -{ - /// Calculates the total stake for a specific asset ID from all delegations. - pub fn get_stake_by_asset_id(&self, asset_id: Asset) -> Balance { - let mut total_stake = Balance::default(); - for stake in &self.delegations { - if stake.asset_id == asset_id { - total_stake += stake.amount; - } - } - total_stake - } - - /// Calculates the total stake for each asset and returns a list of (asset_id, total_stake). - pub fn get_total_stake_by_assets(&self) -> Vec<(Asset, Balance)> { - let mut stake_by_asset: BTreeMap, Balance> = BTreeMap::new(); - - for stake in &self.delegations { - let entry = stake_by_asset.entry(stake.asset_id).or_default(); - *entry += stake.amount; - } - - stake_by_asset.into_iter().collect() - } -} - -/// The activity status of the operator. -#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)] -pub enum OperatorStatus { - /// Committed to be online. - #[default] - Active, - /// Temporarily inactive and excused for inactivity. - Inactive, - /// Bonded until the specified round. - Leaving(RoundIndex), -} - -/// A request scheduled to change the operator self-stake. -#[derive(PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] -pub struct OperatorBondLessRequest { - /// The amount by which the stake is to be decreased. - pub amount: Balance, - /// The round in which the request was made. - pub request_time: RoundIndex, -} - -/// Stores the metadata of an operator. -#[derive(Encode, Decode, RuntimeDebug, TypeInfo, Clone, Eq, PartialEq)] -pub struct OperatorMetadata< - AccountId, - Balance, - AssetId: Encode + Decode, - MaxDelegations: Get, - MaxBlueprints: Get, -> { - /// The operator's self-stake amount. - pub stake: Balance, - /// The total number of delegations to this operator. - pub delegation_count: u32, - /// An optional pending request to decrease the operator's self-stake, with only one allowed at - /// any given time. - pub request: Option>, - /// A list of all current delegations. - pub delegations: BoundedVec, MaxDelegations>, - /// The current status of the operator. - pub status: OperatorStatus, - /// The set of blueprint IDs this operator works with. - pub blueprint_ids: BoundedVec, -} - -impl< - AccountId, - Balance, - AssetId: Encode + Decode, - MaxDelegations: Get, - MaxBlueprints: Get, - > Default for OperatorMetadata -where - Balance: Default, -{ - fn default() -> Self { - Self { - stake: Balance::default(), - delegation_count: 0, - request: None, - delegations: BoundedVec::default(), - status: OperatorStatus::default(), - blueprint_ids: BoundedVec::default(), - } - } -} - -/// Represents a stake for an operator -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond { - /// The account ID of the delegator. - pub delegator: AccountId, - /// The amount bonded. - pub amount: Balance, - /// The ID of the bonded asset. - pub asset_id: Asset, -} diff --git a/pallets/rewards/src/types/rewards.rs b/pallets/rewards/src/types/rewards.rs deleted file mode 100644 index 6a1daad7..00000000 --- a/pallets/rewards/src/types/rewards.rs +++ /dev/null @@ -1,43 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -use super::*; -use sp_runtime::Percent; - -/// Configuration for rewards associated with a specific asset. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct RewardConfigForAssetVault { - // The annual percentage yield (APY) for the asset, represented as a Percent - pub apy: Percent, - // The minimum amount required before the asset can be rewarded. - pub cap: Balance, -} - -/// Configuration for rewards in the system. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct RewardConfig { - // A map of asset IDs to their respective reward configurations. - pub configs: BTreeMap>, - // A list of blueprint IDs that are whitelisted for rewards. - pub whitelisted_blueprint_ids: Vec, -} - -/// Asset action for vaults -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] -pub enum AssetAction { - Add, - Remove, -} From 3fed390d5454034e70e60a87aa00e2b6b07751a6 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 30 Dec 2024 16:32:20 +0530 Subject: [PATCH 38/63] wip tests and benchmarks --- pallets/rewards/src/benchmarking.rs | 276 +------ pallets/rewards/src/lib.rs | 13 +- pallets/rewards/src/mock.rs | 37 +- pallets/rewards/src/tests.rs | 120 ++- pallets/rewards/src/tests/delegate.rs | 539 ------------- pallets/rewards/src/tests/deposit.rs | 509 ------------- pallets/rewards/src/tests/operator.rs | 761 ------------------- pallets/rewards/src/tests/session_manager.rs | 156 ---- 8 files changed, 151 insertions(+), 2260 deletions(-) delete mode 100644 pallets/rewards/src/tests/delegate.rs delete mode 100644 pallets/rewards/src/tests/deposit.rs delete mode 100644 pallets/rewards/src/tests/operator.rs delete mode 100644 pallets/rewards/src/tests/session_manager.rs diff --git a/pallets/rewards/src/benchmarking.rs b/pallets/rewards/src/benchmarking.rs index b231ce4e..390f9e01 100644 --- a/pallets/rewards/src/benchmarking.rs +++ b/pallets/rewards/src/benchmarking.rs @@ -27,266 +27,42 @@ use sp_runtime::{traits::Zero, DispatchError}; const SEED: u32 = 0; benchmarks! { - join_operators { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - }: _(RawOrigin::Signed(caller.clone()), bond_amount) - verify { - assert!(Operators::::contains_key(&caller)); - } - - schedule_leave_operators { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let operator = Operators::::get(&caller).unwrap(); - match operator.status { - OperatorStatus::Leaving(_) => {}, - _ => panic!("Operator should be in Leaving status"), - } - } - - cancel_leave_operators { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - MultiAssetDelegation::::schedule_leave_operators(RawOrigin::Signed(caller.clone()).into())?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let operator = Operators::::get(&caller).unwrap(); - assert_eq!(operator.status, OperatorStatus::Active); - } - - execute_leave_operators { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - MultiAssetDelegation::::schedule_leave_operators(RawOrigin::Signed(caller.clone()).into())?; - let current_round = Pallet::::current_round(); - CurrentRound::::put(current_round + T::LeaveOperatorsDelay::get()); - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(!Operators::::contains_key(&caller)); - } - - operator_bond_more { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - let additional_bond: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); - }: _(RawOrigin::Signed(caller.clone()), additional_bond) + whitelist_asset { + let asset: Asset = Asset::Custom(1u32.into()); + }: _(RawOrigin::Root, asset) verify { - let operator = Operators::::get(&caller).unwrap(); - assert_eq!(operator.stake, bond_amount + additional_bond); + assert!(AllowedRewardAssets::::get(&asset)); } - schedule_operator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); - }: _(RawOrigin::Signed(caller.clone()), unstake_amount) - verify { - let operator = Operators::::get(&caller).unwrap(); - let request = operator.request.unwrap(); - assert_eq!(request.amount, unstake_amount); - } - - execute_operator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); - MultiAssetDelegation::::schedule_operator_unstake(RawOrigin::Signed(caller.clone()).into(), unstake_amount)?; - let current_round = Pallet::::current_round(); - CurrentRound::::put(current_round + T::OperatorBondLessDelay::get()); - }: _(RawOrigin::Signed(caller.clone())) - verify { - let operator = Operators::::get(&caller).unwrap(); - assert_eq!(operator.stake, bond_amount - unstake_amount); - } - - cancel_operator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - let unstake_amount: BalanceOf = T::Currency::minimum_balance() * 5u32.into(); - MultiAssetDelegation::::schedule_operator_unstake(RawOrigin::Signed(caller.clone()).into(), unstake_amount)?; - }: _(RawOrigin::Signed(caller.clone())) + remove_asset { + let asset: Asset = Asset::Custom(1u32.into()); + Rewards::::whitelist_asset(RawOrigin::Root.into(), asset)?; + }: _(RawOrigin::Root, asset) verify { - let operator = Operators::::get(&caller).unwrap(); - assert!(operator.request.is_none()); + assert!(!AllowedRewardAssets::::get(&asset)); } - go_offline { - + claim_rewards { let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let operator = Operators::::get(&caller).unwrap(); - assert_eq!(operator.status, OperatorStatus::Inactive); - } + let asset: Asset = Asset::Custom(1u32.into()); + let reward_type = RewardType::Restaking; + let reward_amount: BalanceOf = T::Currency::minimum_balance() * 100u32.into(); - go_online { + // Setup: Whitelist asset and add rewards + Rewards::::whitelist_asset(RawOrigin::Root.into(), asset)?; + let pallet_account = Rewards::::account_id(); + T::Currency::make_free_balance_be(&pallet_account, reward_amount * 2u32.into()); - let caller: T::AccountId = whitelisted_caller(); - let bond_amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(caller.clone()).into(), bond_amount)?; - MultiAssetDelegation::::go_offline(RawOrigin::Signed(caller.clone()).into())?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let operator = Operators::::get(&caller).unwrap(); - assert_eq!(operator.status, OperatorStatus::Active); - } - - deposit { + // Add rewards for the user + UserRewards::::insert(caller.clone(), asset, UserRewardInfo { + restaking_rewards: reward_amount, + boost_rewards: Zero::zero(), + service_rewards: Zero::zero(), + }); - let caller: T::AccountId = whitelisted_caller(); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - }: _(RawOrigin::Signed(caller.clone()), Some(asset_id), amount) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); - } - - schedule_withdraw { - - let caller: T::AccountId = whitelisted_caller(); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - }: _(RawOrigin::Signed(caller.clone()), Some(asset_id), amount) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.withdraw_requests.is_some()); - } - - execute_withdraw { - - let caller: T::AccountId = whitelisted_caller(); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - MultiAssetDelegation::::schedule_withdraw(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - let current_round = Pallet::::current_round(); - CurrentRound::::put(current_round + T::LeaveDelegatorsDelay::get()); - }: _(RawOrigin::Signed(caller.clone())) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.withdraw_requests.is_none()); - } - - cancel_withdraw { - - let caller: T::AccountId = whitelisted_caller(); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - MultiAssetDelegation::::schedule_withdraw(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.withdraw_requests.is_none()); - } - - delegate { - - let caller: T::AccountId = whitelisted_caller(); - let operator: T::AccountId = account("operator", 1, SEED); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - }: _(RawOrigin::Signed(caller.clone()), operator.clone(), asset_id, amount) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - let delegation = metadata.delegations.iter().find(|d| d.operator == operator && d.asset_id == asset_id).unwrap(); - assert_eq!(delegation.amount, amount); - } - - schedule_delegator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let operator: T::AccountId = account("operator", 1, SEED); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; - }: _(RawOrigin::Signed(caller.clone()), operator.clone(), asset_id, amount) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.delegator_unstake_requests.is_some()); - } - - execute_delegator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let operator: T::AccountId = account("operator", 1, SEED); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; - MultiAssetDelegation::::schedule_delegator_unstake(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; - let current_round = Pallet::::current_round(); - CurrentRound::::put(current_round + T::DelegationBondLessDelay::get()); - }: _(RawOrigin::Signed(caller.clone())) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.delegator_unstake_requests.is_none()); - } - - cancel_delegator_unstake { - - let caller: T::AccountId = whitelisted_caller(); - let operator: T::AccountId = account("operator", 1, SEED); - let asset_id: T::AssetId = 1_u32.into(); - let amount: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - MultiAssetDelegation::::join_operators(RawOrigin::Signed(operator.clone()).into(), T::Currency::minimum_balance() * 20u32.into())?; - MultiAssetDelegation::::deposit(RawOrigin::Signed(caller.clone()).into(), Some(asset_id), amount)?; - MultiAssetDelegation::::delegate(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; - MultiAssetDelegation::::schedule_delegator_unstake(RawOrigin::Signed(caller.clone()).into(), operator.clone(), asset_id, amount)?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - let metadata = Delegators::::get(&caller).unwrap(); - assert!(metadata.delegator_unstake_requests.is_none()); - } - - set_incentive_apy_and_cap { - - let caller: T::AccountId = whitelisted_caller(); - let asset_id: T::AssetId = 1_u32.into(); - let apy: u128 = 1000; - let cap: BalanceOf = T::Currency::minimum_balance() * 10u32.into(); - }: _(RawOrigin::Root, asset_id, apy, cap) - verify { - let config = RewardConfigStorage::::get().unwrap(); - let asset_config = config.configs.get(&asset_id).unwrap(); - assert_eq!(asset_config.apy, apy); - assert_eq!(asset_config.cap, cap); - } - - whitelist_blueprint_for_rewards { - - let caller: T::AccountId = whitelisted_caller(); - let blueprint_id: u32 = 1; - }: _(RawOrigin::Root, blueprint_id) + }: _(RawOrigin::Signed(caller.clone()), asset, reward_type) verify { - let config = RewardConfigStorage::::get().unwrap(); - assert!(config.whitelisted_blueprint_ids.contains(&blueprint_id)); + let rewards = UserRewards::::get(caller.clone(), asset).unwrap_or_default(); + assert!(rewards.restaking_rewards.is_zero()); } } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 5cf8a6a0..59b029d6 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -47,19 +47,18 @@ pub use pallet::*; -// #[cfg(test)] -// mod mock; +#[cfg(test)] +mod mock; -// #[cfg(test)] -// mod mock_evm; +#[cfg(test)] +mod mock_evm; -// #[cfg(test)] -// mod tests; +#[cfg(test)] +mod tests; // pub mod weights; // #[cfg(feature = "runtime-benchmarks")] -// TODO(@1xstj): Fix benchmarking and re-enable // mod benchmarking; use scale_info::TypeInfo; diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 1314749b..9d0b63fe 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -305,34 +305,6 @@ parameter_types! { pub const MaxDelegations: u32 = 50; } -impl pallet_multi_asset_delegation::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type MinOperatorBondAmount = MinOperatorBondAmount; - type BondDuration = BondDuration; - type ServiceManager = MockServiceManager; - type LeaveOperatorsDelay = ConstU32<10>; - type OperatorBondLessDelay = ConstU32<1>; - type LeaveDelegatorsDelay = ConstU32<1>; - type DelegationBondLessDelay = ConstU32<5>; - type MinDelegateAmount = ConstU128<100>; - type Fungibles = Assets; - type AssetId = AssetId; - type VaultId = AssetId; - type ForceOrigin = frame_system::EnsureRoot; - type PalletId = PID; - type MaxDelegatorBlueprints = MaxDelegatorBlueprints; - type MaxOperatorBlueprints = MaxOperatorBlueprints; - type MaxWithdrawRequests = MaxWithdrawRequests; - type MaxUnstakeRequests = MaxUnstakeRequests; - type MaxDelegations = MaxDelegations; - type SlashedAmountRecipient = SlashedAmountRecipient; - type EvmRunner = MockedEvmRunner; - type EvmGasWeightMapping = PalletEVMGasWeightMapping; - type EvmAddressMapping = PalletEVMAddressMapping; - type WeightInfo = (); -} - type Block = frame_system::mocking::MockBlock; construct_runtime!( @@ -342,7 +314,6 @@ construct_runtime!( Timestamp: pallet_timestamp, Balances: pallet_balances, Assets: pallet_assets, - MultiAssetDelegation: pallet_multi_asset_delegation, EVM: pallet_evm, Ethereum: pallet_ethereum, Session: pallet_session, @@ -402,8 +373,8 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { let test_accounts = vec![ AccountKeyring::Dave.into(), AccountKeyring::Eve.into(), - MultiAssetDelegation::pallet_account(), ]; + balances.extend(test_accounts.iter().map(|i: &AccountId| (i.clone(), 1_000_000_u128))); pallet_balances::GenesisConfig:: { balances } @@ -485,7 +456,8 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { >::on_initialize(1); let call = ::EvmRunner::call( - MultiAssetDelegation::pallet_evm_account(), + // MultiAssetDelegation::pallet_evm_account(), + H160::zero(), USDC_ERC20, serde_json::from_value::(json!({ "name": "initialize", @@ -526,7 +498,8 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { // Mint for i in 1..=authorities.len() { let call = ::EvmRunner::call( - MultiAssetDelegation::pallet_evm_account(), + // MultiAssetDelegation::pallet_evm_account(), + H160::zero(), USDC_ERC20, serde_json::from_value::(json!({ "name": "mint", diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 376a1b43..6da53581 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -14,11 +14,119 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::{mock::*, tests::RuntimeEvent}; +use crate::{mock::*, Error, Event, RewardType}; +use frame_support::{assert_noop, assert_ok}; +use sp_runtime::traits::Zero; +use tangle_primitives::services::Asset; -pub mod delegate; -pub mod deposit; -pub mod operator; -pub mod session_manager; +#[test] +fn test_whitelist_asset() { + new_test_ext().execute_with(|| { + let asset = Asset::::Native(0); + + // Only root can whitelist assets + assert_noop!( + Rewards::whitelist_asset(RuntimeOrigin::signed(1), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can whitelist asset + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + assert!(Rewards::is_asset_whitelisted(asset)); + + // Cannot whitelist same asset twice + assert_noop!( + Rewards::whitelist_asset(RuntimeOrigin::root(), asset), + Error::::AssetAlreadyWhitelisted + ); + }); +} -use crate::tests::deposit::{create_and_mint_tokens, mint_tokens}; +#[test] +fn test_remove_asset() { + new_test_ext().execute_with(|| { + let asset = Asset::::Native(0); + + // Whitelist asset first + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Only root can remove assets + assert_noop!( + Rewards::remove_asset(RuntimeOrigin::signed(1), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can remove asset + assert_ok!(Rewards::remove_asset(RuntimeOrigin::root(), asset)); + assert!(!Rewards::is_asset_whitelisted(asset)); + + // Cannot remove non-whitelisted asset + assert_noop!( + Rewards::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + }); +} + +#[test] +fn test_claim_rewards() { + new_test_ext().execute_with(|| { + let user = 1; + let asset = Asset::::Native(0); + let reward_type = RewardType::Restaking; + + // Cannot claim from non-whitelisted asset + assert_noop!( + Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Error::::AssetNotWhitelisted + ); + + // Whitelist asset + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Cannot claim when no rewards available + assert_noop!( + Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Error::::NoRewardsAvailable + ); + + // TODO: Add test for successful claim once we have a way to add rewards + }); +} + +#[test] +fn test_calculate_user_score() { + new_test_ext().execute_with(|| { + use crate::types::{BoostInfo, LockMultiplier, UserRewards}; + + // Test TNT asset scoring + let tnt_rewards = UserRewards { + restaking_rewards: 1000u32.into(), + boost_rewards: BoostInfo { + amount: 500u32.into(), + multiplier: LockMultiplier::ThreeMonths, + expiry: Zero::zero(), + }, + service_rewards: 200u32.into(), + }; + + let tnt_score = crate::functions::calculate_user_score::(Asset::::Native(0), &tnt_rewards); + // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 + assert_eq!(tnt_score, 2700); + + // Test non-TNT asset scoring + let other_rewards = UserRewards { + restaking_rewards: 1000u32.into(), + boost_rewards: BoostInfo { + amount: 500u32.into(), + multiplier: LockMultiplier::ThreeMonths, + expiry: Zero::zero(), + }, + service_rewards: 200u32.into(), + }; + + let other_score = crate::functions::calculate_user_score::(Asset::::Evm(1), &other_rewards); + // Expected: Only service rewards count for non-TNT assets + assert_eq!(other_score, 200); + }); +} diff --git a/pallets/rewards/src/tests/delegate.rs b/pallets/rewards/src/tests/delegate.rs deleted file mode 100644 index 92a7316d..00000000 --- a/pallets/rewards/src/tests/delegate.rs +++ /dev/null @@ -1,539 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -#![allow(clippy::all)] -use super::*; -use crate::{CurrentRound, Error}; -use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::{Alice, Bob}; -use tangle_primitives::services::Asset; - -#[test] -fn delegate_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - create_and_mint_tokens(VDOT, who.clone(), amount); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.deposits.get(&asset_id).is_none()); - assert_eq!(metadata.delegations.len(), 1); - let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator.clone()); - assert_eq!(delegation.amount, amount); - assert_eq!(delegation.asset_id, asset_id); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount); - assert_eq!(operator_delegation.asset_id, asset_id); - }); -} - -#[test] -fn schedule_delegator_unstake_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit and delegate first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - )); - - // Assert - // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(!metadata.delegator_unstake_requests.is_empty()); - let request = &metadata.delegator_unstake_requests[0]; - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, amount); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 0); - assert_eq!(operator_metadata.delegations.len(), 0); - }); -} - -#[test] -fn execute_delegator_unstake_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - )); - - // Simulate round passing - CurrentRound::::put(10); - - assert_ok!(MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed( - who.clone() - ),)); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.delegator_unstake_requests.is_empty()); - assert!(metadata.deposits.get(&asset_id).is_some()); - assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); - }); -} - -#[test] -fn cancel_delegator_unstake_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - )); - - // Assert - // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(!metadata.delegator_unstake_requests.is_empty()); - let request = &metadata.delegator_unstake_requests[0]; - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, amount); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 0); - assert_eq!(operator_metadata.delegations.len(), 0); - - assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount - )); - - // Assert - // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.delegator_unstake_requests.is_empty()); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount); // Amount added back - assert_eq!(operator_delegation.asset_id, asset_id); - }); -} - -#[test] -fn cancel_delegator_unstake_should_update_already_existing() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - 10, - )); - - // Assert - // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(!metadata.delegator_unstake_requests.is_empty()); - let request = &metadata.delegator_unstake_requests[0]; - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, 10); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount - 10); - assert_eq!(operator_delegation.asset_id, asset_id); - - assert_ok!(MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - 10 - )); - - // Assert - // Check the delegator metadata - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.delegator_unstake_requests.is_empty()); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount); // Amount added back - assert_eq!(operator_delegation.asset_id, asset_id); - }); -} - -#[test] -fn delegate_should_fail_if_not_enough_balance() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 10_000; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount - 20, - None - )); - - assert_noop!( - MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - ), - Error::::InsufficientBalance - ); - }); -} - -#[test] -fn schedule_delegator_unstake_should_fail_if_no_delegation() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - - assert_noop!( - MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - ), - Error::::NoActiveDelegation - ); - }); -} - -#[test] -fn execute_delegator_unstake_should_fail_if_not_ready() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit, delegate and schedule unstake first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - assert_noop!( - MultiAssetDelegation::cancel_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount - ), - Error::::NoBondLessRequest - ); - - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - )); - - assert_noop!( - MultiAssetDelegation::execute_delegator_unstake(RuntimeOrigin::signed(who.clone()),), - Error::::BondLessNotReady - ); - }); -} - -#[test] -fn delegate_should_not_create_multiple_on_repeat_delegation() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - let additional_amount = 50; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - create_and_mint_tokens(VDOT, who.clone(), amount + additional_amount); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount + additional_amount, - None - )); - - // Delegate first time - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default() - )); - - // Assert first delegation - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.deposits.get(&asset_id).is_some()); - assert_eq!(metadata.delegations.len(), 1); - let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator.clone()); - assert_eq!(delegation.amount, amount); - assert_eq!(delegation.asset_id, asset_id); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount); - assert_eq!(operator_delegation.asset_id, asset_id); - - // Delegate additional amount - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - additional_amount, - Default::default() - )); - - // Assert updated delegation - let updated_metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(updated_metadata.deposits.get(&asset_id).is_none()); - assert_eq!(updated_metadata.delegations.len(), 1); - let updated_delegation = &updated_metadata.delegations[0]; - assert_eq!(updated_delegation.operator, operator.clone()); - assert_eq!(updated_delegation.amount, amount + additional_amount); - assert_eq!(updated_delegation.asset_id, asset_id); - - // Check the updated operator metadata - let updated_operator_metadata = - MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(updated_operator_metadata.delegation_count, 1); - assert_eq!(updated_operator_metadata.delegations.len(), 1); - let updated_operator_delegation = &updated_operator_metadata.delegations[0]; - assert_eq!(updated_operator_delegation.delegator, who.clone()); - assert_eq!(updated_operator_delegation.amount, amount + additional_amount); - assert_eq!(updated_operator_delegation.asset_id, asset_id); - }); -} diff --git a/pallets/rewards/src/tests/deposit.rs b/pallets/rewards/src/tests/deposit.rs deleted file mode 100644 index d72c669e..00000000 --- a/pallets/rewards/src/tests/deposit.rs +++ /dev/null @@ -1,509 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::DelegatorStatus, CurrentRound, Error}; -use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::Bob; -use sp_runtime::ArithmeticError; -use tangle_primitives::services::Asset; - -// helper function -pub fn create_and_mint_tokens( - asset_id: AssetId, - recipient: ::AccountId, - amount: Balance, -) { - assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient.clone(), false, 1)); - assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient.clone()), asset_id, recipient, amount)); -} - -pub fn mint_tokens( - owner: ::AccountId, - asset_id: AssetId, - recipient: ::AccountId, - amount: Balance, -) { - assert_ok!(Assets::mint(RuntimeOrigin::signed(owner), asset_id, recipient, amount)); -} - -#[test] -fn deposit_should_work_for_fungible_asset() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let amount = 200; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); - assert_eq!( - System::events().last().unwrap().event, - RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who: who.clone(), - amount, - asset_id: Asset::Custom(VDOT), - }) - ); - }); -} - -#[test] -fn deposit_should_work_for_evm_asset() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let amount = 200; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); - assert_eq!( - System::events().last().unwrap().event, - RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who: who.clone(), - amount, - asset_id: Asset::Custom(VDOT), - }) - ); - }); -} - -#[test] -fn multiple_deposit_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let amount = 200; - - create_and_mint_tokens(VDOT, who.clone(), amount * 4); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); - assert_eq!( - System::events().last().unwrap().event, - RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who: who.clone(), - amount, - asset_id: Asset::Custom(VDOT), - }) - ); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&(amount * 2))); - assert_eq!( - System::events().last().unwrap().event, - RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { - who: who.clone(), - amount, - asset_id: Asset::Custom(VDOT), - }) - ); - }); -} - -#[test] -fn deposit_should_fail_for_insufficient_balance() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let amount = 2000; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - ), - ArithmeticError::Underflow - ); - }); -} - -#[test] -fn deposit_should_fail_for_bond_too_low() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let amount = 50; // Below the minimum stake amount - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - amount, - None - ), - Error::::BondTooLow - ); - }); -} - -#[test] -fn schedule_withdraw_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - - assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&asset_id), None); - assert!(!metadata.withdraw_requests.is_empty()); - let request = metadata.withdraw_requests.first().unwrap(); - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, amount); - }); -} - -#[test] -fn schedule_withdraw_should_fail_if_not_delegator() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - assert_noop!( - MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - ), - Error::::NotDelegator - ); - }); -} - -#[test] -fn schedule_withdraw_should_fail_for_insufficient_balance() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 200; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - 100, - None - )); - - assert_noop!( - MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - ), - Error::::InsufficientBalance - ); - }); -} - -#[test] -fn schedule_withdraw_should_fail_if_withdraw_request_exists() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - - // Schedule the first withdraw - assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - )); - }); -} - -#[test] -fn execute_withdraw_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - )); - - // Simulate round passing - let current_round = 1; - >::put(current_round); - - assert_ok!(MultiAssetDelegation::execute_withdraw( - RuntimeOrigin::signed(who.clone()), - None - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()); - assert!(metadata.unwrap().withdraw_requests.is_empty()); - - // Check event - System::assert_last_event(RuntimeEvent::MultiAssetDelegation( - crate::Event::Executedwithdraw { who: who.clone() }, - )); - }); -} - -#[test] -fn execute_withdraw_should_fail_if_not_delegator() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - - assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), - Error::::NotDelegator - ); - }); -} - -#[test] -fn execute_withdraw_should_fail_if_no_withdraw_request() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - - assert_noop!( - MultiAssetDelegation::execute_withdraw(RuntimeOrigin::signed(who.clone()), None), - Error::::NowithdrawRequests - ); - }); -} - -#[test] -fn execute_withdraw_should_fail_if_withdraw_not_ready() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - )); - - // Simulate round passing but not enough - let current_round = 0; - >::put(current_round); - - // should not actually withdraw anything - assert_ok!(MultiAssetDelegation::execute_withdraw( - RuntimeOrigin::signed(who.clone()), - None - )); - - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(!metadata.withdraw_requests.is_empty()); - }); -} - -#[test] -fn cancel_withdraw_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit and schedule withdraw first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - assert_ok!(MultiAssetDelegation::schedule_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - )); - - assert_ok!(MultiAssetDelegation::cancel_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.withdraw_requests.is_empty()); - assert_eq!(metadata.deposits.get(&asset_id), Some(&amount)); - assert_eq!(metadata.status, DelegatorStatus::Active); - - // Check event - System::assert_last_event(RuntimeEvent::MultiAssetDelegation( - crate::Event::Cancelledwithdraw { who: who.clone() }, - )); - }); -} - -#[test] -fn cancel_withdraw_should_fail_if_not_delegator() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - - assert_noop!( - MultiAssetDelegation::cancel_withdraw( - RuntimeOrigin::signed(who.clone()), - Asset::Custom(VDOT), - 1 - ), - Error::::NotDelegator - ); - }); -} - -#[test] -fn cancel_withdraw_should_fail_if_no_withdraw_request() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), 100); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - - assert_noop!( - MultiAssetDelegation::cancel_withdraw( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount - ), - Error::::NoMatchingwithdrawRequest - ); - }); -} diff --git a/pallets/rewards/src/tests/operator.rs b/pallets/rewards/src/tests/operator.rs deleted file mode 100644 index 210b49f4..00000000 --- a/pallets/rewards/src/tests/operator.rs +++ /dev/null @@ -1,761 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{ - types::{DelegatorBlueprintSelection::Fixed, OperatorStatus}, - CurrentRound, Error, -}; -use frame_support::{assert_noop, assert_ok}; -use sp_keyring::AccountKeyring::{Alice, Bob, Eve}; -use sp_runtime::Percent; -use tangle_primitives::services::Asset; - -#[test] -fn join_operator_success() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.stake, bond_amount); - assert_eq!(operator_info.delegation_count, 0); - assert_eq!(operator_info.request, None); - assert_eq!(operator_info.status, OperatorStatus::Active); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorJoined { - who: Alice.to_account_id(), - })); - }); -} - -#[test] -fn join_operator_already_operator() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - assert_noop!( - MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - ), - Error::::AlreadyOperator - ); - }); -} - -#[test] -fn join_operator_insufficient_bond() { - new_test_ext().execute_with(|| { - let insufficient_bond = 5_000; - - assert_noop!( - MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Eve.to_account_id()), - insufficient_bond - ), - Error::::BondTooLow - ); - }); -} - -#[test] -fn join_operator_insufficient_funds() { - new_test_ext().execute_with(|| { - let bond_amount = 350_000; // User 4 has only 200_000 - - assert_noop!( - MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - ), - pallet_balances::Error::::InsufficientBalance - ); - }); -} - -#[test] -fn join_operator_minimum_bond() { - new_test_ext().execute_with(|| { - let minimum_bond = 10_000; - let exact_bond = minimum_bond; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - exact_bond - )); - - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.stake, exact_bond); - }); -} - -#[test] -fn schedule_leave_operator_success() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Schedule leave operators without joining - assert_noop!( - MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NotAnOperator - ); - - // Set the current round - >::put(5); - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Schedule leave operators - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorLeavingScheduled { who: Alice.to_account_id() }, - )); - }); -} - -#[test] -fn cancel_leave_operator_tests() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Set the current round - >::put(5); - - // Schedule leave operators - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Verify operator metadata after cancellation - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.status, OperatorStatus::Leaving(15)); // current_round (5) + leave_operators_delay (10) - - // Test: Cancel leave operators successfully - assert_ok!(MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Verify operator metadata after cancellation - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.status, OperatorStatus::Active); // current_round (5) + leave_operators_delay (10) - - // Verify event for cancellation - System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorLeaveCancelled { who: Alice.to_account_id() }, - )); - - // Test: Cancel leave operators without being in leaving state - assert_noop!( - MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NotLeavingOperator - ); - - // Test: Schedule leave operators again - assert_ok!(MultiAssetDelegation::schedule_leave_operators(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Test: Cancel leave operators without being an operator - assert_noop!( - MultiAssetDelegation::cancel_leave_operators(RuntimeOrigin::signed( - Bob.to_account_id() - )), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn operator_bond_more_success() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - let additional_bond = 5_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // stake more TNT - assert_ok!(MultiAssetDelegation::operator_bond_more( - RuntimeOrigin::signed(Alice.to_account_id()), - additional_bond - )); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.stake, bond_amount + additional_bond); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorBondMore { - who: Alice.to_account_id(), - additional_bond, - })); - }); -} - -#[test] -fn operator_bond_more_not_an_operator() { - new_test_ext().execute_with(|| { - let additional_bond = 5_000; - - // Attempt to stake more without being an operator - assert_noop!( - MultiAssetDelegation::operator_bond_more( - RuntimeOrigin::signed(Alice.to_account_id()), - additional_bond - ), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn operator_bond_more_insufficient_balance() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - let additional_bond = 1_150_000; // Exceeds available balance - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Attempt to stake more with insufficient balance - assert_noop!( - MultiAssetDelegation::operator_bond_more( - RuntimeOrigin::signed(Alice.to_account_id()), - additional_bond - ), - pallet_balances::Error::::InsufficientBalance - ); - }); -} - -#[test] -fn schedule_operator_unstake_success() { - new_test_ext().execute_with(|| { - let bond_amount = 20_000; // Increased initial bond - let unstake_amount = 5_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Schedule unstake - assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - )); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.request.unwrap().amount, unstake_amount); - - // Verify remaining stake is above minimum - assert!( - operator_info.stake.saturating_sub(unstake_amount) - >= MinOperatorBondAmount::get().into() - ); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessScheduled { who: Alice.to_account_id(), unstake_amount }, - )); - }); -} - -// Add test for minimum stake requirement -#[test] -fn schedule_operator_unstake_respects_minimum_stake() { - new_test_ext().execute_with(|| { - let bond_amount = 20_000; - let unstake_amount = 15_000; // Would leave less than minimum required - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Attempt to schedule unstake that would leave less than minimum - assert_noop!( - MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - ), - Error::::InsufficientStakeRemaining - ); - }); -} - -#[test] -fn schedule_operator_unstake_not_an_operator() { - new_test_ext().execute_with(|| { - let unstake_amount = 5_000; - - // Attempt to schedule unstake without being an operator - assert_noop!( - MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - ), - Error::::NotAnOperator - ); - }); -} - -// TO DO -// #[test] -// fn schedule_operator_unstake_active_services() { -// new_test_ext().execute_with(|| { -// let bond_amount = 10_000; -// let unstake_amount = 5_000; - -// // Join operator first -// assert_ok!(MultiAssetDelegation::join_operators(RuntimeOrigin::signed(Alice. -// to_account_id()), bond_amount)); - -// // Manually set the operator's delegation count to simulate active services -// Operators::::mutate(1, |operator| { -// if let Some(ref mut operator) = operator { -// operator.delegation_count = 1; -// } -// }); - -// // Attempt to schedule unstake with active services -// assert_noop!( -// -// MultiAssetDelegation::schedule_operator_unstake(RuntimeOrigin::signed(Alice.to_account_id()), -// unstake_amount), Error::::ActiveServicesUsingTNT -// ); -// }); -// } - -#[test] -fn execute_operator_unstake_success() { - new_test_ext().execute_with(|| { - let bond_amount = 20_000; - let unstake_amount = 5_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Schedule unstake - assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - )); - - // Set the current round to simulate passage of time - >::put(15); - - // Execute unstake - assert_ok!(MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.stake, bond_amount - unstake_amount); - assert_eq!(operator_info.request, None); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessExecuted { who: Alice.to_account_id() }, - )); - }); -} - -#[test] -fn execute_operator_unstake_not_an_operator() { - new_test_ext().execute_with(|| { - // Attempt to execute unstake without being an operator - assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn execute_operator_unstake_no_scheduled_unstake() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Attempt to execute unstake without scheduling it - assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NoScheduledBondLess - ); - }); -} - -#[test] -fn execute_operator_unstake_request_not_satisfied() { - new_test_ext().execute_with(|| { - let bond_amount = 20_000; - let unstake_amount = 5_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Schedule unstake - assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - )); - - // Attempt to execute unstake before request is satisfied - assert_noop!( - MultiAssetDelegation::execute_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::BondLessRequestNotSatisfied - ); - }); -} - -#[test] -fn cancel_operator_unstake_success() { - new_test_ext().execute_with(|| { - let bond_amount = 20_000; - let unstake_amount = 5_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Schedule unstake - assert_ok!(MultiAssetDelegation::schedule_operator_unstake( - RuntimeOrigin::signed(Alice.to_account_id()), - unstake_amount - )); - - // Cancel unstake - assert_ok!(MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - ))); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.request, None); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation( - Event::OperatorBondLessCancelled { who: Alice.to_account_id() }, - )); - }); -} - -#[test] -fn cancel_operator_unstake_not_an_operator() { - new_test_ext().execute_with(|| { - // Attempt to cancel unstake without being an operator - assert_noop!( - MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn cancel_operator_unstake_no_scheduled_unstake() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Attempt to cancel unstake without scheduling it - assert_noop!( - MultiAssetDelegation::cancel_operator_unstake(RuntimeOrigin::signed( - Alice.to_account_id() - )), - Error::::NoScheduledBondLess - ); - }); -} - -#[test] -fn go_offline_success() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Go offline - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.status, OperatorStatus::Inactive); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOffline { - who: Alice.to_account_id(), - })); - }); -} - -#[test] -fn go_offline_not_an_operator() { - new_test_ext().execute_with(|| { - // Attempt to go offline without being an operator - assert_noop!( - MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id())), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn go_online_success() { - new_test_ext().execute_with(|| { - let bond_amount = 10_000; - - // Join operator first - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - bond_amount - )); - - // Go offline first - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); - - // Go online - assert_ok!(MultiAssetDelegation::go_online(RuntimeOrigin::signed(Alice.to_account_id()))); - - // Verify operator metadata - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.status, OperatorStatus::Active); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorWentOnline { - who: Alice.to_account_id(), - })); - }); -} - -#[test] -fn slash_operator_success() { - new_test_ext().execute_with(|| { - // Setup operator - let operator_stake = 10_000; - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - operator_stake - )); - - // Setup delegators - let delegator_stake = 5_000; - let asset_id = Asset::Custom(1); - let blueprint_id = 1; - - create_and_mint_tokens(1, Bob.to_account_id(), delegator_stake); - mint_tokens(Bob.to_account_id(), 1, Bob.to_account_id(), delegator_stake); - - // Setup delegator with fixed blueprint selection - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(Bob.to_account_id()), - asset_id, - delegator_stake, - None - )); - - assert_ok!(MultiAssetDelegation::add_blueprint_id( - RuntimeOrigin::signed(Bob.to_account_id()), - blueprint_id - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(Bob.to_account_id()), - Alice.to_account_id(), - asset_id, - delegator_stake, - Fixed(vec![blueprint_id].try_into().unwrap()), - )); - - // Slash 50% of stakes - let slash_percentage = Percent::from_percent(50); - assert_ok!(MultiAssetDelegation::slash_operator( - &Alice.to_account_id(), - blueprint_id, - slash_percentage - )); - - // Verify operator stake was slashed - let operator_info = MultiAssetDelegation::operator_info(Alice.to_account_id()).unwrap(); - assert_eq!(operator_info.stake, operator_stake / 2); - - // Verify delegator stake was slashed - let delegator = MultiAssetDelegation::delegators(Bob.to_account_id()).unwrap(); - let delegation = delegator - .delegations - .iter() - .find(|d| d.operator == Alice.to_account_id()) - .unwrap(); - assert_eq!(delegation.amount, delegator_stake / 2); - - // Verify event - System::assert_has_event(RuntimeEvent::MultiAssetDelegation(Event::OperatorSlashed { - who: Alice.to_account_id(), - amount: operator_stake / 2, - })); - }); -} - -#[test] -fn slash_operator_not_an_operator() { - new_test_ext().execute_with(|| { - assert_noop!( - MultiAssetDelegation::slash_operator( - &Alice.to_account_id(), - 1, - Percent::from_percent(50) - ), - Error::::NotAnOperator - ); - }); -} - -#[test] -fn slash_operator_not_active() { - new_test_ext().execute_with(|| { - // Setup and deactivate operator - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - 10_000 - )); - assert_ok!(MultiAssetDelegation::go_offline(RuntimeOrigin::signed(Alice.to_account_id()))); - - assert_noop!( - MultiAssetDelegation::slash_operator( - &Alice.to_account_id(), - 1, - Percent::from_percent(50) - ), - Error::::NotActiveOperator - ); - }); -} - -#[test] -fn slash_delegator_fixed_blueprint_not_selected() { - new_test_ext().execute_with(|| { - // Setup operator - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(Alice.to_account_id()), - 10_000 - )); - - create_and_mint_tokens(1, Bob.to_account_id(), 10_000); - - // Setup delegator with fixed blueprint selection - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(Bob.to_account_id()), - Asset::Custom(1), - 5_000, - None - )); - - assert_ok!(MultiAssetDelegation::add_blueprint_id( - RuntimeOrigin::signed(Bob.to_account_id()), - 1 - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(Bob.to_account_id()), - Alice.to_account_id(), - Asset::Custom(1), - 5_000, - Fixed(vec![2].try_into().unwrap()), - )); - - // Try to slash with unselected blueprint - assert_noop!( - MultiAssetDelegation::slash_delegator( - &Bob.to_account_id(), - &Alice.to_account_id(), - 5, - Percent::from_percent(50) - ), - Error::::BlueprintNotSelected - ); - }); -} diff --git a/pallets/rewards/src/tests/session_manager.rs b/pallets/rewards/src/tests/session_manager.rs deleted file mode 100644 index 7174d5f5..00000000 --- a/pallets/rewards/src/tests/session_manager.rs +++ /dev/null @@ -1,156 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::CurrentRound; -use frame_support::assert_ok; -use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave}; -use tangle_primitives::services::Asset; - -#[test] -fn handle_round_change_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let who = Bob.to_account_id(); - let operator = Alice.to_account_id(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - CurrentRound::::put(1); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - create_and_mint_tokens(VDOT, who.clone(), amount); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id, - amount, - None - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id, - amount, - Default::default() - )); - - assert_ok!(Pallet::::handle_round_change()); - - // Assert - let current_round = MultiAssetDelegation::current_round(); - assert_eq!(current_round, 2); - - let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator.clone()).unwrap(); - assert_eq!(snapshot1.stake, 10_000); - assert_eq!(snapshot1.delegations.len(), 1); - assert_eq!(snapshot1.delegations[0].amount, amount); - assert_eq!(snapshot1.delegations[0].asset_id, asset_id); - }); -} - -#[test] -fn handle_round_change_with_unstake_should_work() { - new_test_ext().execute_with(|| { - // Arrange - let delegator1 = Alice.to_account_id(); - let delegator2 = Bob.to_account_id(); - let operator1 = Charlie.to_account_id(); - let operator2 = Dave.to_account_id(); - let asset_id = Asset::Custom(VDOT); - let amount1 = 1_000_000_000_000; - let amount2 = 1_000_000_000_000; - let unstake_amount = 50; - - CurrentRound::::put(1); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator1.clone()), - 10_000 - )); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator2.clone()), - 10_000 - )); - - create_and_mint_tokens(VDOT, delegator1.clone(), amount1); - mint_tokens(delegator1.clone(), VDOT, delegator2.clone(), amount2); - - // Deposit and delegate first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1.clone()), - asset_id, - amount1, - None, - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator1.clone()), - operator1.clone(), - asset_id, - amount1, - Default::default() - )); - - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2.clone()), - asset_id, - amount2, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(delegator2.clone()), - operator2.clone(), - asset_id, - amount2, - Default::default() - )); - - // Delegator1 schedules unstake - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(delegator1.clone()), - operator1.clone(), - asset_id, - unstake_amount, - )); - - assert_ok!(Pallet::::handle_round_change()); - - // Assert - let current_round = MultiAssetDelegation::current_round(); - assert_eq!(current_round, 2); - - // Check the snapshot for operator1 - let snapshot1 = MultiAssetDelegation::at_stake(current_round, operator1.clone()).unwrap(); - assert_eq!(snapshot1.stake, 10_000); - assert_eq!(snapshot1.delegations.len(), 1); - assert_eq!(snapshot1.delegations[0].delegator, delegator1.clone()); - assert_eq!(snapshot1.delegations[0].amount, amount1 - unstake_amount); // Amount reduced by unstake_amount - assert_eq!(snapshot1.delegations[0].asset_id, asset_id); - - // Check the snapshot for operator2 - let snapshot2 = MultiAssetDelegation::at_stake(current_round, operator2.clone()).unwrap(); - assert_eq!(snapshot2.stake, 10000); - assert_eq!(snapshot2.delegations.len(), 1); - assert_eq!(snapshot2.delegations[0].delegator, delegator2.clone()); - assert_eq!(snapshot2.delegations[0].amount, amount2); - assert_eq!(snapshot2.delegations[0].asset_id, asset_id); - }); -} From 7ac3deccccf5ac83d17eb4cab6e208e5f34067e7 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 30 Dec 2024 16:34:38 +0530 Subject: [PATCH 39/63] cleanup clippy --- pallets/rewards/src/lib.rs | 24 ----- pallets/rewards/src/mock.rs | 5 +- pallets/rewards/src/tests.rs | 194 ++++++++++++++++++----------------- 3 files changed, 99 insertions(+), 124 deletions(-) diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 59b029d6..48b666bb 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -19,30 +19,6 @@ //! This pallet provides a reward management system for the Tangle network, enabling users to //! accumulate and claim rewards. //! -//! ## Key Components -//! -//! - **Rewards**: Users can earn rewards through various network activities. These rewards are -//! tracked and stored until claimed. -//! - **Claimable Rewards**: The system maintains a record of rewards that are available for -//! claiming by each user. -//! - **Total Rewards**: The system tracks the total amount of rewards that have been distributed -//! across the network. -//! -//! ## Workflow -//! -//! 1. **Earning Rewards**: Users earn rewards through their participation in network activities. -//! These rewards are added to their account by authorized entities. -//! -//! 2. **Claiming Rewards**: Users can claim their accumulated rewards at any time. When claimed, -//! the rewards are transferred to the user's account and removed from their claimable balance. -//! -//! ## Features -//! -//! - **Secure Storage**: All reward balances are securely stored and tracked on-chain -//! - **Root-Only Additions**: Only root accounts can add rewards, ensuring security -//! - **Safe Transfers**: Claims are validated to ensure sufficient balance before processing -//! - **Event Tracking**: All reward additions and claims are tracked through events - #![cfg_attr(not(feature = "std"), no_std)] pub use pallet::*; diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 9d0b63fe..8e662ea8 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -370,10 +370,7 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { let mut balances: Vec<_> = authorities.iter().map(|i| (i.clone(), 200_000_u128)).collect(); // Add test accounts with enough balance - let test_accounts = vec![ - AccountKeyring::Dave.into(), - AccountKeyring::Eve.into(), - ]; + let test_accounts = vec![AccountKeyring::Dave.into(), AccountKeyring::Eve.into()]; balances.extend(test_accounts.iter().map(|i: &AccountId| (i.clone(), 1_000_000_u128))); diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 6da53581..e426c46a 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -21,112 +21,114 @@ use tangle_primitives::services::Asset; #[test] fn test_whitelist_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::::Native(0); - - // Only root can whitelist assets - assert_noop!( - Rewards::whitelist_asset(RuntimeOrigin::signed(1), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can whitelist asset - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); - assert!(Rewards::is_asset_whitelisted(asset)); - - // Cannot whitelist same asset twice - assert_noop!( - Rewards::whitelist_asset(RuntimeOrigin::root(), asset), - Error::::AssetAlreadyWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::::Native(0); + + // Only root can whitelist assets + assert_noop!( + Rewards::whitelist_asset(RuntimeOrigin::signed(1), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can whitelist asset + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + assert!(Rewards::is_asset_whitelisted(asset)); + + // Cannot whitelist same asset twice + assert_noop!( + Rewards::whitelist_asset(RuntimeOrigin::root(), asset), + Error::::AssetAlreadyWhitelisted + ); + }); } #[test] fn test_remove_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::::Native(0); - - // Whitelist asset first - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Only root can remove assets - assert_noop!( - Rewards::remove_asset(RuntimeOrigin::signed(1), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can remove asset - assert_ok!(Rewards::remove_asset(RuntimeOrigin::root(), asset)); - assert!(!Rewards::is_asset_whitelisted(asset)); - - // Cannot remove non-whitelisted asset - assert_noop!( - Rewards::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::::Native(0); + + // Whitelist asset first + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Only root can remove assets + assert_noop!( + Rewards::remove_asset(RuntimeOrigin::signed(1), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can remove asset + assert_ok!(Rewards::remove_asset(RuntimeOrigin::root(), asset)); + assert!(!Rewards::is_asset_whitelisted(asset)); + + // Cannot remove non-whitelisted asset + assert_noop!( + Rewards::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + }); } #[test] fn test_claim_rewards() { - new_test_ext().execute_with(|| { - let user = 1; - let asset = Asset::::Native(0); - let reward_type = RewardType::Restaking; - - // Cannot claim from non-whitelisted asset - assert_noop!( - Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), - Error::::AssetNotWhitelisted - ); - - // Whitelist asset - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Cannot claim when no rewards available - assert_noop!( - Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), - Error::::NoRewardsAvailable - ); - - // TODO: Add test for successful claim once we have a way to add rewards - }); + new_test_ext().execute_with(|| { + let user = 1; + let asset = Asset::::Native(0); + let reward_type = RewardType::Restaking; + + // Cannot claim from non-whitelisted asset + assert_noop!( + Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Error::::AssetNotWhitelisted + ); + + // Whitelist asset + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Cannot claim when no rewards available + assert_noop!( + Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Error::::NoRewardsAvailable + ); + + // TODO: Add test for successful claim once we have a way to add rewards + }); } #[test] fn test_calculate_user_score() { - new_test_ext().execute_with(|| { - use crate::types::{BoostInfo, LockMultiplier, UserRewards}; - - // Test TNT asset scoring - let tnt_rewards = UserRewards { - restaking_rewards: 1000u32.into(), - boost_rewards: BoostInfo { - amount: 500u32.into(), - multiplier: LockMultiplier::ThreeMonths, - expiry: Zero::zero(), - }, - service_rewards: 200u32.into(), - }; - - let tnt_score = crate::functions::calculate_user_score::(Asset::::Native(0), &tnt_rewards); - // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 - assert_eq!(tnt_score, 2700); - - // Test non-TNT asset scoring - let other_rewards = UserRewards { - restaking_rewards: 1000u32.into(), - boost_rewards: BoostInfo { - amount: 500u32.into(), - multiplier: LockMultiplier::ThreeMonths, - expiry: Zero::zero(), - }, - service_rewards: 200u32.into(), - }; - - let other_score = crate::functions::calculate_user_score::(Asset::::Evm(1), &other_rewards); - // Expected: Only service rewards count for non-TNT assets - assert_eq!(other_score, 200); - }); + new_test_ext().execute_with(|| { + use crate::types::{BoostInfo, LockMultiplier, UserRewards}; + + // Test TNT asset scoring + let tnt_rewards = UserRewards { + restaking_rewards: 1000u32.into(), + boost_rewards: BoostInfo { + amount: 500u32.into(), + multiplier: LockMultiplier::ThreeMonths, + expiry: Zero::zero(), + }, + service_rewards: 200u32.into(), + }; + + let tnt_score = + crate::functions::calculate_user_score::(Asset::::Native(0), &tnt_rewards); + // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 + assert_eq!(tnt_score, 2700); + + // Test non-TNT asset scoring + let other_rewards = UserRewards { + restaking_rewards: 1000u32.into(), + boost_rewards: BoostInfo { + amount: 500u32.into(), + multiplier: LockMultiplier::ThreeMonths, + expiry: Zero::zero(), + }, + service_rewards: 200u32.into(), + }; + + let other_score = + crate::functions::calculate_user_score::(Asset::::Evm(1), &other_rewards); + // Expected: Only service rewards count for non-TNT assets + assert_eq!(other_score, 200); + }); } From 5ddb1c3d0b7a80cac9c68df1c1f44e270baf2b11 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:11:17 +0530 Subject: [PATCH 40/63] fmt --- pallets/rewards/src/functions.rs | 143 ++++++++++++++++--------------- pallets/rewards/src/lib.rs | 2 + pallets/rewards/src/mock_evm.rs | 13 --- pallets/rewards/src/tests.rs | 119 +++++++++++++------------ 4 files changed, 133 insertions(+), 144 deletions(-) diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 0c35cf9b..9134b2b6 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -28,85 +28,88 @@ use tangle_primitives::services::Asset; /// - Base score = staked amount /// - No additional multiplier pub fn calculate_user_score( - asset: Asset, - rewards: &UserRewardsOf, + asset: Asset, + rewards: &UserRewardsOf, ) -> u128 { - let base_score = match asset { - Asset::Native => { - // For TNT, include both restaking and boost rewards - let restaking_score = rewards.restaking_rewards - .saturating_add(rewards.service_rewards) - .saturated_into::(); - - // Apply lock multiplier to boost rewards - let boost_score = rewards.boost_rewards.amount - .saturated_into::() - .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); - - restaking_score.saturating_add(boost_score) - }, - _ => { - // For non-TNT assets, only consider service rewards - rewards.service_rewards.saturated_into::() - } - }; + let base_score = match asset { + Asset::Native => { + // For TNT, include both restaking and boost rewards + let restaking_score = rewards + .restaking_rewards + .saturating_add(rewards.service_rewards) + .saturated_into::(); - base_score + // Apply lock multiplier to boost rewards + let boost_score = rewards + .boost_rewards + .amount + .saturated_into::() + .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); + + restaking_score.saturating_add(boost_score) + }, + _ => { + // For non-TNT assets, only consider service rewards + rewards.service_rewards.saturated_into::() + }, + }; + + base_score } #[cfg(test)] mod tests { - use super::*; - use crate::{BoostInfo, LockMultiplier, UserRewards}; - use sp_runtime::traits::Zero; + use super::*; + use crate::{BoostInfo, LockMultiplier, UserRewards}; + use sp_runtime::traits::Zero; + + // Helper function to create UserRewards with specific values + fn create_user_rewards( + restaking: u128, + boost_amount: u128, + boost_multiplier: LockMultiplier, + service: u128, + ) -> UserRewardsOf { + UserRewards { + restaking_rewards: restaking.saturated_into(), + boost_rewards: BoostInfo { + amount: boost_amount.saturated_into(), + multiplier: boost_multiplier, + expiry: Zero::zero(), + }, + service_rewards: service.saturated_into(), + } + } + + #[test] + fn test_calculate_user_score_tnt() { + // Test TNT asset with different lock multipliers + let rewards = create_user_rewards::( + 1000, // restaking rewards + 500, // boost amount + LockMultiplier::ThreeMonths, // 3x multiplier + 200, // service rewards + ); - // Helper function to create UserRewards with specific values - fn create_user_rewards( - restaking: u128, - boost_amount: u128, - boost_multiplier: LockMultiplier, - service: u128, - ) -> UserRewardsOf { - UserRewards { - restaking_rewards: restaking.saturated_into(), - boost_rewards: BoostInfo { - amount: boost_amount.saturated_into(), - multiplier: boost_multiplier, - expiry: Zero::zero(), - }, - service_rewards: service.saturated_into(), - } - } + let score = calculate_user_score::(Asset::Native, &rewards); - #[test] - fn test_calculate_user_score_tnt() { - // Test TNT asset with different lock multipliers - let rewards = create_user_rewards::( - 1000, // restaking rewards - 500, // boost amount - LockMultiplier::ThreeMonths, // 3x multiplier - 200, // service rewards - ); + // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 + assert_eq!(score, 2700); + } - let score = calculate_user_score::(Asset::Native, &rewards); - - // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 - assert_eq!(score, 2700); - } + #[test] + fn test_calculate_user_score_other_asset() { + // Test non-TNT asset + let rewards = create_user_rewards::( + 1000, // restaking rewards + 500, // boost amount + LockMultiplier::SixMonths, // 6x multiplier (should not affect non-TNT) + 200, // service rewards + ); - #[test] - fn test_calculate_user_score_other_asset() { - // Test non-TNT asset - let rewards = create_user_rewards::( - 1000, // restaking rewards - 500, // boost amount - LockMultiplier::SixMonths, // 6x multiplier (should not affect non-TNT) - 200, // service rewards - ); + let score = calculate_user_score::(Asset::Evm(1), &rewards); - let score = calculate_user_score::(Asset::Evm(1), &rewards); - - // Expected: only service rewards are counted - assert_eq!(score, 200); - } + // Expected: only service rewards are counted + assert_eq!(score, 200); + } } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 48b666bb..ddb4bc83 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -42,6 +42,8 @@ use sp_runtime::Saturating; use tangle_primitives::services::Asset; pub mod types; pub use types::*; +pub mod functions; +pub use functions::*; /// The pallet's account ID. #[frame_support::pallet] diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs index f9d9646a..697971da 100644 --- a/pallets/rewards/src/mock_evm.rs +++ b/pallets/rewards/src/mock_evm.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] -use crate as pallet_multi_asset_delegation; use crate::mock::{ AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, }; @@ -160,12 +159,6 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { who: &H160, fee: U256, ) -> Result> { - let pallet_multi_asset_delegation_address = - pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); - // Make pallet multi_asset_delegation account free to use - if who == &pallet_multi_asset_delegation_address { - return Ok(None); - } // fallback to the default implementation as OnChargeEVMTransaction< Runtime, @@ -178,12 +171,6 @@ impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { base_fee: U256, already_withdrawn: Self::LiquidityInfo, ) -> Self::LiquidityInfo { - let pallet_multi_asset_delegation_address = - pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); - // Make pallet multi_asset_delegation account free to use - if who == &pallet_multi_asset_delegation_address { - return already_withdrawn; - } // fallback to the default implementation as OnChargeEVMTransaction< Runtime, diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index e426c46a..58306265 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -13,30 +13,30 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use super::*; -use crate::{mock::*, Error, Event, RewardType}; +use crate::{functions, mock::Test, Error, Event, Pallet as Rewards, RewardType}; use frame_support::{assert_noop, assert_ok}; -use sp_runtime::traits::Zero; +use sp_runtime::{traits::Zero, AccountId32}; use tangle_primitives::services::Asset; #[test] fn test_whitelist_asset() { new_test_ext().execute_with(|| { - let asset = Asset::::Native(0); + let asset = Asset::::Custom(Zero::zero()); + let account: AccountId32 = AccountId32::new([1; 32]); - // Only root can whitelist assets + // Non-root cannot whitelist asset assert_noop!( - Rewards::whitelist_asset(RuntimeOrigin::signed(1), asset), + Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), sp_runtime::DispatchError::BadOrigin ); // Root can whitelist asset - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); - assert!(Rewards::is_asset_whitelisted(asset)); + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + assert!(Rewards::::is_asset_whitelisted(asset)); // Cannot whitelist same asset twice assert_noop!( - Rewards::whitelist_asset(RuntimeOrigin::root(), asset), + Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), Error::::AssetAlreadyWhitelisted ); }); @@ -45,24 +45,31 @@ fn test_whitelist_asset() { #[test] fn test_remove_asset() { new_test_ext().execute_with(|| { - let asset = Asset::::Native(0); + let asset = Asset::::Custom(Zero::zero()); + let account: AccountId32 = AccountId32::new([1; 32]); - // Whitelist asset first - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + // Cannot remove non-whitelisted asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + + // Whitelist the asset first + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - // Only root can remove assets + // Non-root cannot remove asset assert_noop!( - Rewards::remove_asset(RuntimeOrigin::signed(1), asset), + Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), sp_runtime::DispatchError::BadOrigin ); // Root can remove asset - assert_ok!(Rewards::remove_asset(RuntimeOrigin::root(), asset)); - assert!(!Rewards::is_asset_whitelisted(asset)); + assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); + assert!(!Rewards::::is_asset_whitelisted(asset)); - // Cannot remove non-whitelisted asset + // Cannot remove already removed asset assert_noop!( - Rewards::remove_asset(RuntimeOrigin::root(), asset), + Rewards::::remove_asset(RuntimeOrigin::root(), asset), Error::::AssetNotWhitelisted ); }); @@ -71,64 +78,54 @@ fn test_remove_asset() { #[test] fn test_claim_rewards() { new_test_ext().execute_with(|| { - let user = 1; - let asset = Asset::::Native(0); + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::::Custom(Zero::zero()); let reward_type = RewardType::Restaking; - // Cannot claim from non-whitelisted asset + // Cannot claim rewards for non-whitelisted asset assert_noop!( - Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), Error::::AssetNotWhitelisted ); - // Whitelist asset - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), asset)); + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - // Cannot claim when no rewards available + // Cannot claim rewards when none are available assert_noop!( - Rewards::claim_rewards(RuntimeOrigin::signed(user), asset, reward_type), + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), Error::::NoRewardsAvailable ); - - // TODO: Add test for successful claim once we have a way to add rewards }); } #[test] fn test_calculate_user_score() { new_test_ext().execute_with(|| { - use crate::types::{BoostInfo, LockMultiplier, UserRewards}; - - // Test TNT asset scoring - let tnt_rewards = UserRewards { - restaking_rewards: 1000u32.into(), - boost_rewards: BoostInfo { - amount: 500u32.into(), - multiplier: LockMultiplier::ThreeMonths, - expiry: Zero::zero(), - }, - service_rewards: 200u32.into(), - }; - - let tnt_score = - crate::functions::calculate_user_score::(Asset::::Native(0), &tnt_rewards); - // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 - assert_eq!(tnt_score, 2700); - - // Test non-TNT asset scoring - let other_rewards = UserRewards { - restaking_rewards: 1000u32.into(), - boost_rewards: BoostInfo { - amount: 500u32.into(), - multiplier: LockMultiplier::ThreeMonths, - expiry: Zero::zero(), - }, - service_rewards: 200u32.into(), - }; - - let other_score = - crate::functions::calculate_user_score::(Asset::::Evm(1), &other_rewards); - // Expected: Only service rewards count for non-TNT assets - assert_eq!(other_score, 200); + let tnt_rewards = vec![(1, 100), (2, 200), (3, 300)]; + + let other_rewards = vec![(4, 400), (5, 500), (6, 600)]; + + // Test native asset rewards calculation (with 6x multiplier) + let score = functions::calculate_user_score::( + Asset::::Custom(Zero::zero()), + &tnt_rewards, + ); + assert_eq!(score, 3600); // (100 + 200 + 300) * 6 + + // Test EVM asset rewards calculation (no multiplier) + let score = functions::calculate_user_score::( + Asset::::Erc20(sp_core::H160::zero()), + &other_rewards, + ); + assert_eq!(score, 1500); // 400 + 500 + 600 }); } From aa379fcb7cce3693c01cbf907c9ff1f4cd273cbf Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:27:34 +0530 Subject: [PATCH 41/63] more tests and fuzzing --- pallets/rewards/fuzzer/Cargo.toml | 33 ++ pallets/rewards/fuzzer/call.rs | 563 ++++++++++++++++++++++++++++++ pallets/rewards/src/mock.rs | 10 + pallets/rewards/src/tests.rs | 419 ++++++++++++++++------ 4 files changed, 926 insertions(+), 99 deletions(-) create mode 100644 pallets/rewards/fuzzer/Cargo.toml create mode 100644 pallets/rewards/fuzzer/call.rs diff --git a/pallets/rewards/fuzzer/Cargo.toml b/pallets/rewards/fuzzer/Cargo.toml new file mode 100644 index 00000000..e6dcedc9 --- /dev/null +++ b/pallets/rewards/fuzzer/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "pallet-rewards-fuzzer" +version = "2.0.0" +authors.workspace = true +edition.workspace = true +license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true +description = "Fuzzer for fixed point arithmetic primitives." +documentation = "https://docs.rs/sp-arithmetic-fuzzer" +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +honggfuzz = { workspace = true } + +pallet-rewards = { features = ["fuzzing"], workspace = true, default-features = true } + +frame-system = { workspace = true, default-features = true } +frame-support = { workspace = true, default-features = true } + +sp-runtime = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sp-tracing = { workspace = true, default-features = true } + +rand = { features = ["small_rng"], workspace = true, default-features = true } +log = { workspace = true, default-features = true } + +[[bin]] +name = "mad-fuzzer" +path = "call.rs" diff --git a/pallets/rewards/fuzzer/call.rs b/pallets/rewards/fuzzer/call.rs new file mode 100644 index 00000000..ecc81fc0 --- /dev/null +++ b/pallets/rewards/fuzzer/call.rs @@ -0,0 +1,563 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run mad-fuzzer`. `honggfuzz` CLI +//! options can be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug mad-fuzzer hfuzz_workspace/mad-fuzzer/*.fuzz`. + +use frame_support::{ + dispatch::PostDispatchInfo, + traits::{Currency, Get, GetCallName, Hooks, UnfilteredDispatchable}, +}; +use frame_system::ensure_signed_or_root; +use honggfuzz::fuzz; +use pallet_multi_asset_delegation::{mock::*, pallet as mad, types::*}; +use rand::{seq::SliceRandom, Rng}; +use sp_runtime::{ + traits::{Scale, Zero}, + Percent, +}; + +const MAX_ED_MULTIPLE: Balance = 10_000; +const MIN_ED_MULTIPLE: Balance = 10; + +fn random_account_id(rng: &mut R) -> AccountId { + rng.gen::<[u8; 32]>().into() +} + +/// Grab random accounts. +fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, AccountId) { + let acc = random_account_id(rng); + (RuntimeOrigin::signed(acc.clone()), acc) +} + +fn random_ed_multiple(rng: &mut R) -> Balance { + let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); + ExistentialDeposit::get() * multiple +} + +fn random_asset(rng: &mut R) -> Asset { + let asset_id = rng.gen_range(1..u128::MAX); + let is_evm = rng.gen_bool(0.5); + if is_evm { + let evm_address = rng.gen::<[u8; 20]>().into(); + Asset::Erc20(evm_address) + } else { + Asset::Custom(asset_id) + } +} + +fn fund_account(rng: &mut R, account: &AccountId) { + let target_amount = random_ed_multiple(rng); + if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(account)) { + let _ = Balances::deposit_creating(account, top_up); + } + assert!(Balances::free_balance(account) >= target_amount); +} + +/// Join operators call. +fn join_operators_call( + rng: &mut R, + origin: RuntimeOrigin, + who: &AccountId, +) -> (mad::Call, RuntimeOrigin) { + let minimum_bond = <::MinOperatorBondAmount as Get>::get(); + let multiplier = rng.gen_range(1..50u128); + let _ = Balances::deposit_creating(who, minimum_bond.mul(multiplier)); + let bond_amount = minimum_bond.mul(multiplier); + (mad::Call::join_operators { bond_amount }, origin) +} + +fn random_calls( + mut rng: &mut R, +) -> impl IntoIterator, RuntimeOrigin)> { + let op = as GetCallName>::get_call_names() + .choose(rng) + .cloned() + .unwrap(); + + match op { + "join_operators" => { + // join_operators + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [join_operators_call(&mut rng, origin, &who)].to_vec() + }, + "schedule_leave_operators" => { + // Schedule leave operators + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::schedule_leave_operators {}, origin), + ] + .to_vec() + }, + "cancel_leave_operators" => { + // Cancel leave operators + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::cancel_leave_operators {}, origin), + ] + .to_vec() + }, + "execute_leave_operators" => { + // Execute leave operators + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::execute_leave_operators {}, origin), + ] + .to_vec() + }, + "operator_bond_more" => { + // Operator bond more + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let additional_bond = random_ed_multiple(&mut rng); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::operator_bond_more { additional_bond }, origin), + ] + .to_vec() + }, + "schedule_operator_unstake" => { + // Schedule operator unstake + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let unstake_amount = random_ed_multiple(&mut rng); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::schedule_operator_unstake { unstake_amount }, origin), + ] + .to_vec() + }, + "execute_operator_unstake" => { + // Execute operator unstake + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::execute_operator_unstake {}, origin), + ] + .to_vec() + }, + "cancel_operator_unstake" => { + // Cancel operator unstake + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::cancel_operator_unstake {}, origin), + ] + .to_vec() + }, + "go_offline" => { + // Go offline + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [ + join_operators_call(&mut rng, origin.clone(), &who), + (mad::Call::go_offline {}, origin), + ] + .to_vec() + }, + "go_online" => { + // Go online + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [join_operators_call(&mut rng, origin.clone(), &who), (mad::Call::go_online {}, origin)] + .to_vec() + }, + "deposit" => { + // Deposit + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + let evm_address = + if rng.gen_bool(0.5) { Some(rng.gen::<[u8; 20]>().into()) } else { None }; + [(mad::Call::deposit { asset_id, amount, evm_address }, origin)].to_vec() + }, + "schedule_withdraw" => { + // Schedule withdraw + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + [(mad::Call::schedule_withdraw { asset_id, amount }, origin)].to_vec() + }, + "execute_withdraw" => { + // Execute withdraw + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let evm_address = + if rng.gen_bool(0.5) { Some(rng.gen::<[u8; 20]>().into()) } else { None }; + [(mad::Call::execute_withdraw { evm_address }, origin)].to_vec() + }, + "cancel_withdraw" => { + // Cancel withdraw + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + [(mad::Call::cancel_withdraw { asset_id, amount }, origin)].to_vec() + }, + "delegate" => { + // Delegate + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let (operator_origin, operator) = random_signed_origin(&mut rng); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + let blueprint_selection = { + let all = rng.gen_bool(0.5); + if all { + DelegatorBlueprintSelection::All + } else { + let count = rng.gen_range(1..MaxDelegatorBlueprints::get()); + DelegatorBlueprintSelection::Fixed( + (0..count) + .map(|_| rng.gen::()) + .collect::>() + .try_into() + .unwrap(), + ) + } + }; + [ + join_operators_call(&mut rng, operator_origin.clone(), &operator), + (mad::Call::delegate { operator, asset_id, amount, blueprint_selection }, origin), + ] + .to_vec() + }, + "schedule_delegator_unstake" => { + // Schedule delegator unstakes + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let (operator_origin, operator) = random_signed_origin(&mut rng); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + [ + join_operators_call(&mut rng, operator_origin.clone(), &operator), + (mad::Call::schedule_delegator_unstake { operator, asset_id, amount }, origin), + ] + .to_vec() + }, + "execute_delegator_unstake" => { + // Execute delegator unstake + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [(mad::Call::execute_delegator_unstake {}, origin)].to_vec() + }, + "cancel_delegator_unstake" => { + // Cancel delegator unstake + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + let (operator_origin, operator) = random_signed_origin(&mut rng); + let asset_id = random_asset(&mut rng); + let amount = random_ed_multiple(&mut rng); + [ + join_operators_call(&mut rng, operator_origin.clone(), &operator), + (mad::Call::cancel_delegator_unstake { operator, asset_id, amount }, origin), + ] + .to_vec() + }, + "set_incentive_apy_and_cap" => { + // Set incentive APY and cap + let is_root = rng.gen_bool(0.5); + let (origin, who) = if is_root { + (RuntimeOrigin::root(), [0u8; 32].into()) + } else { + random_signed_origin(&mut rng) + }; + fund_account(&mut rng, &who); + let vault_id = rng.gen(); + let apy = Percent::from_percent(rng.gen_range(0..100)); + let cap = rng.gen_range(0..Balance::MAX); + [(mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap }, origin)].to_vec() + }, + "whitelist_blueprint_for_rewards" => { + // Whitelist blueprint for rewards + let is_root = rng.gen_bool(0.5); + let (origin, who) = if is_root { + (RuntimeOrigin::root(), [0u8; 32].into()) + } else { + random_signed_origin(&mut rng) + }; + fund_account(&mut rng, &who); + let blueprint_id = rng.gen::(); + [(mad::Call::whitelist_blueprint_for_rewards { blueprint_id }, origin)].to_vec() + }, + "manage_asset_in_vault" => { + // Manage asset in vault + let is_root = rng.gen_bool(0.5); + let (origin, who) = if is_root { + (RuntimeOrigin::root(), [0u8; 32].into()) + } else { + random_signed_origin(&mut rng) + }; + fund_account(&mut rng, &who); + let asset_id = random_asset(&mut rng); + let vault_id = rng.gen(); + let action = if rng.gen() { AssetAction::Add } else { AssetAction::Remove }; + [(mad::Call::manage_asset_in_vault { asset_id, vault_id, action }, origin)].to_vec() + }, + "add_blueprint_id" => { + // Add blueprint ID + let is_root = rng.gen_bool(0.5); + let (origin, who) = if is_root { + (RuntimeOrigin::root(), [0u8; 32].into()) + } else { + random_signed_origin(&mut rng) + }; + fund_account(&mut rng, &who); + let blueprint_id = rng.gen::(); + [(mad::Call::add_blueprint_id { blueprint_id }, origin)].to_vec() + }, + "remove_blueprint_id" => { + // Remove blueprint ID + let is_root = rng.gen_bool(0.5); + let (origin, who) = if is_root { + (RuntimeOrigin::root(), [0u8; 32].into()) + } else { + random_signed_origin(&mut rng) + }; + fund_account(&mut rng, &who); + let blueprint_id = rng.gen::(); + [(mad::Call::remove_blueprint_id { blueprint_id }, origin)].to_vec() + }, + _ => { + unimplemented!("unknown call name: {}", op) + }, + } +} + +fn main() { + sp_tracing::try_init_simple(); + let mut ext = sp_io::TestExternalities::new_empty(); + let mut block_number = 1; + loop { + fuzz!(|seed: [u8; 32]| { + use ::rand::{rngs::SmallRng, SeedableRng}; + let mut rng = SmallRng::from_seed(seed); + + ext.execute_with(|| { + System::set_block_number(block_number); + Session::on_initialize(block_number); + Staking::on_initialize(block_number); + + for (call, origin) in random_calls(&mut rng) { + let outcome = call.clone().dispatch_bypass_filter(origin.clone()); + sp_tracing::trace!(?call, ?origin, ?outcome, "fuzzed call"); + + // execute sanity checks at a fixed interval, possibly on every block. + if let Ok(out) = outcome { + sp_tracing::info!("running sanity checks.."); + do_sanity_checks(call.clone(), origin.clone(), out); + } + } + + System::reset_events(); + block_number += 1; + }); + }) + } +} + +/// Perform sanity checks on the state after a call is executed successfully. +#[allow(unused)] +fn do_sanity_checks(call: mad::Call, origin: RuntimeOrigin, outcome: PostDispatchInfo) { + let caller = match ensure_signed_or_root(origin).unwrap() { + Some(signer) => signer, + None => + /*Root */ + { + [0u8; 32].into() + }, + }; + match call { + mad::Call::join_operators { bond_amount } => { + assert!(mad::Operators::::contains_key(&caller), "operator not found"); + assert_eq!( + MultiAssetDelegation::operator_info(&caller).unwrap_or_default().stake, + bond_amount + ); + assert!( + Balances::reserved_balance(&caller).ge(&bond_amount), + "bond amount not reserved" + ); + }, + mad::Call::schedule_leave_operators {} => { + assert!(mad::Operators::::contains_key(&caller), "operator not found"); + let current_round = mad::CurrentRound::::get(); + let leaving_time = + <::LeaveOperatorsDelay as Get>::get() + current_round; + assert_eq!( + mad::Operators::::get(&caller).unwrap_or_default().status, + OperatorStatus::Leaving(leaving_time) + ); + }, + mad::Call::cancel_leave_operators {} => { + assert_eq!( + mad::Operators::::get(&caller).unwrap_or_default().status, + OperatorStatus::Active + ); + }, + mad::Call::execute_leave_operators {} => { + assert!(!mad::Operators::::contains_key(&caller), "operator not removed"); + assert!(Balances::reserved_balance(&caller).is_zero(), "bond amount not unreserved"); + }, + mad::Call::operator_bond_more { additional_bond } => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + assert!(info.stake.ge(&additional_bond), "bond amount not increased"); + assert!( + Balances::reserved_balance(&caller).ge(&additional_bond), + "bond amount not reserved" + ); + }, + mad::Call::schedule_operator_unstake { unstake_amount } => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + let current_round = MultiAssetDelegation::current_round(); + let unstake_request = + OperatorBondLessRequest { amount: unstake_amount, request_time: current_round }; + assert_eq!(info.request, Some(unstake_request), "unstake request not set"); + }, + mad::Call::execute_operator_unstake {} => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + assert!(info.request.is_none(), "unstake request not removed"); + // reserved balance should be reduced and equal to the stake + assert!( + Balances::reserved_balance(&caller).eq(&info.stake), + "reserved balance not equal to stake" + ); + }, + mad::Call::cancel_operator_unstake {} => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + assert!(info.request.is_none(), "unstake request not removed"); + }, + mad::Call::go_offline {} => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + assert_eq!(info.status, OperatorStatus::Inactive, "status not set to inactive"); + }, + mad::Call::go_online {} => { + let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); + assert_eq!(info.status, OperatorStatus::Active, "status not set to active"); + }, + mad::Call::deposit { asset_id, amount, .. } => { + match asset_id { + Asset::Custom(id) => { + let pallet_balance = + Assets::balance(id, MultiAssetDelegation::pallet_account()); + assert!(pallet_balance.ge(&amount), "pallet balance not enough"); + }, + Asset::Erc20(token) => { + let pallet_balance = MultiAssetDelegation::query_erc20_balance_of( + token, + MultiAssetDelegation::pallet_evm_account(), + ) + .unwrap_or_default() + .0; + assert!(pallet_balance.ge(&amount.into()), "pallet balance not enough"); + }, + }; + + assert_eq!( + MultiAssetDelegation::delegators(&caller) + .unwrap_or_default() + .calculate_delegation_by_asset(asset_id), + amount + ); + }, + mad::Call::schedule_withdraw { asset_id, amount } => { + let round = MultiAssetDelegation::current_round(); + assert!( + MultiAssetDelegation::delegators(&caller) + .unwrap_or_default() + .get_withdraw_requests() + .contains(&WithdrawRequest { asset_id, amount, requested_round: round }), + "withdraw request not found" + ); + }, + mad::Call::execute_withdraw { .. } => { + assert!( + MultiAssetDelegation::delegators(&caller) + .unwrap_or_default() + .get_withdraw_requests() + .is_empty(), + "withdraw requests not removed" + ); + }, + mad::Call::cancel_withdraw { asset_id, amount } => { + let round = MultiAssetDelegation::current_round(); + assert!( + !MultiAssetDelegation::delegators(&caller) + .unwrap_or_default() + .get_withdraw_requests() + .contains(&WithdrawRequest { asset_id, amount, requested_round: round }), + "withdraw request not removed" + ); + }, + mad::Call::delegate { operator, asset_id, amount, .. } => { + let delegator = MultiAssetDelegation::delegators(&caller).unwrap_or_default(); + let operator_info = MultiAssetDelegation::operator_info(&operator).unwrap_or_default(); + assert!( + delegator + .calculate_delegation_by_operator(operator) + .iter() + .find_map(|x| { + if x.asset_id == asset_id { + Some(x.amount) + } else { + None + } + }) + .ge(&Some(amount)), + "delegation amount not set" + ); + assert!( + operator_info + .delegations + .iter() + .find_map(|x| { + if x.delegator == caller && x.asset_id == asset_id { + Some(x.amount) + } else { + None + } + }) + .ge(&Some(amount)), + "delegator not added to operator" + ); + }, + mad::Call::schedule_delegator_unstake { operator, asset_id, amount } => {}, + mad::Call::execute_delegator_unstake {} => {}, + mad::Call::cancel_delegator_unstake { operator, asset_id, amount } => {}, + mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap } => {}, + mad::Call::whitelist_blueprint_for_rewards { blueprint_id } => {}, + mad::Call::manage_asset_in_vault { vault_id, asset_id, action } => {}, + mad::Call::add_blueprint_id { blueprint_id } => {}, + mad::Call::remove_blueprint_id { blueprint_id } => {}, + other => unimplemented!("sanity checks for call: {other:?} not implemented"), + } +} diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 8e662ea8..3e379ef9 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -263,6 +263,15 @@ impl pallet_assets::Config for Runtime { type RemoveItemsLimit = ConstU32<5>; } +impl pallet_rewards::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssetId = AssetId; + type Balance = Balance; + type Currency = Balances; + type Assets = Assets; + type ServiceManager = MockServiceManager; +} + pub struct MockServiceManager; impl tangle_primitives::ServiceManager for MockServiceManager { @@ -319,6 +328,7 @@ construct_runtime!( Session: pallet_session, Staking: pallet_staking, Historical: pallet_session_historical, + Rewards: pallet_rewards, } ); diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 58306265..207a4065 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -13,119 +13,340 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate::{functions, mock::Test, Error, Event, Pallet as Rewards, RewardType}; +use crate::{mock::*, Error, Pallet as Rewards, RewardType}; use frame_support::{assert_noop, assert_ok}; -use sp_runtime::{traits::Zero, AccountId32}; +use sp_runtime::AccountId32; use tangle_primitives::services::Asset; +// Helper function to set up user rewards +fn setup_user_rewards( + account: T::AccountId, + asset: Asset, + restaking_rewards: BalanceOf, + service_rewards: BalanceOf, + boost_amount: BalanceOf, + multiplier: LockMultiplier, + expiry: BlockNumberFor, +) { + let rewards = UserRewards { + restaking_rewards, + service_rewards, + boost_rewards: BoostInfo { + amount: boost_amount, + multiplier, + expiry, + }, + }; + UserRewards::::insert(account, asset, rewards); +} + #[test] fn test_whitelist_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::::Custom(Zero::zero()); - let account: AccountId32 = AccountId32::new([1; 32]); - - // Non-root cannot whitelist asset - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can whitelist asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - assert!(Rewards::::is_asset_whitelisted(asset)); - - // Cannot whitelist same asset twice - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), - Error::::AssetAlreadyWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::Custom(0u32); + let account: AccountId32 = AccountId32::new([1; 32]); + + // Non-root cannot whitelist asset + assert_noop!( + Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can whitelist asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + assert!(Rewards::::is_asset_whitelisted(asset)); + + // Cannot whitelist same asset twice + assert_noop!( + Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), + Error::::AssetAlreadyWhitelisted + ); + }); } #[test] fn test_remove_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::::Custom(Zero::zero()); - let account: AccountId32 = AccountId32::new([1; 32]); - - // Cannot remove non-whitelisted asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - - // Whitelist the asset first - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Non-root cannot remove asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can remove asset - assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); - assert!(!Rewards::::is_asset_whitelisted(asset)); - - // Cannot remove already removed asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::Custom(0u32); + let account: AccountId32 = AccountId32::new([1; 32]); + + // Cannot remove non-whitelisted asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + + // Whitelist the asset first + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Non-root cannot remove asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can remove asset + assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); + assert!(!Rewards::::is_asset_whitelisted(asset)); + + // Cannot remove already removed asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + }); } #[test] fn test_claim_rewards() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::::Custom(Zero::zero()); - let reward_type = RewardType::Restaking; - - // Cannot claim rewards for non-whitelisted asset - assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), - Error::::AssetNotWhitelisted - ); - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Cannot claim rewards when none are available - assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), - Error::::NoRewardsAvailable - ); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Cannot claim rewards for non-whitelisted asset + assert_noop!( + Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), + Error::::AssetNotWhitelisted + ); + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Cannot claim rewards when none are available + assert_noop!( + Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), + Error::::NoRewardsAvailable + ); + }); } #[test] -fn test_calculate_user_score() { - new_test_ext().execute_with(|| { - let tnt_rewards = vec![(1, 100), (2, 200), (3, 300)]; - - let other_rewards = vec![(4, 400), (5, 500), (6, 600)]; - - // Test native asset rewards calculation (with 6x multiplier) - let score = functions::calculate_user_score::( - Asset::::Custom(Zero::zero()), - &tnt_rewards, - ); - assert_eq!(score, 3600); // (100 + 200 + 300) * 6 - - // Test EVM asset rewards calculation (no multiplier) - let score = functions::calculate_user_score::( - Asset::::Erc20(sp_core::H160::zero()), - &other_rewards, - ); - assert_eq!(score, 1500); // 400 + 500 + 600 - }); +fn test_reward_score_calculation() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let custom_asset = Asset::Custom(0u32); + let erc20_asset = Asset::Erc20(mock_address(1)); + let reward_type = RewardType::Restaking; + + // Whitelist both assets + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), custom_asset)); + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), erc20_asset)); + + // Set up rewards for custom asset with boost + setup_user_rewards::( + account.clone(), + custom_asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + // Set up rewards for ERC20 asset without boost + setup_user_rewards::( + account.clone(), + erc20_asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // Test claiming rewards for both assets + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + custom_asset, + reward_type + )); + + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + erc20_asset, + reward_type + )); + + // Verify rewards are cleared after claiming + let custom_rewards = Rewards::::user_rewards(account.clone(), custom_asset); + assert_eq!(custom_rewards.restaking_rewards, 0u128.into()); + + let erc20_rewards = Rewards::::user_rewards(account.clone(), erc20_asset); + assert_eq!(erc20_rewards.restaking_rewards, 0u128.into()); + }); +} + +#[test] +fn test_reward_distribution() { + new_test_ext().execute_with(|| { + let account1: AccountId32 = AccountId32::new([1; 32]); + let account2: AccountId32 = AccountId32::new([2; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up different rewards for each account + setup_user_rewards::( + account1.clone(), + asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + setup_user_rewards::( + account2.clone(), + asset, + 200u128.into(), // restaking rewards + 100u128.into(), // service rewards + 400u128.into(), // boost amount + LockMultiplier::SixMonths, + 200u64.into(), // expiry block + ); + + // Both accounts should be able to claim their rewards + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account1.clone()), + asset, + reward_type + )); + + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account2.clone()), + asset, + reward_type + )); + + // Verify rewards are cleared after claiming + let account1_rewards = Rewards::::user_rewards(account1, asset); + assert_eq!(account1_rewards.restaking_rewards, 0u128.into()); + + let account2_rewards = Rewards::::user_rewards(account2, asset); + assert_eq!(account2_rewards.restaking_rewards, 0u128.into()); + }); +} + +#[test] +fn test_different_reward_types() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up rewards for different reward types + setup_user_rewards::( + account.clone(), + asset, + 100u128.into(), // restaking rewards + 150u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + // Test claiming each type of reward + let reward_types = vec![ + RewardType::Restaking, + RewardType::Service, + RewardType::Boost, + ]; + + for reward_type in reward_types { + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + } + + // Verify all rewards are cleared + let rewards = Rewards::::user_rewards(account, asset); + assert_eq!(rewards.restaking_rewards, 0u128.into()); + assert_eq!(rewards.service_rewards, 0u128.into()); + assert_eq!(rewards.boost_rewards.amount, 0u128.into()); + }); +} + +#[test] +fn test_multiple_claims() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up initial rewards + setup_user_rewards::( + account.clone(), + asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // First claim should succeed + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + + // Second claim should fail as rewards are cleared + assert_noop!( + Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), + Error::::NoRewardsAvailable + ); + + // Set up new rewards + setup_user_rewards::( + account.clone(), + asset, + 200u128.into(), // restaking rewards + 100u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // Should be able to claim again with new rewards + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + }); +} + +#[test] +fn test_edge_cases() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Test with zero rewards + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + assert_noop!( + Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), + Error::::NoRewardsAvailable + ); + + // Test with invalid asset ID + let invalid_asset = Asset::Custom(u32::MAX); + assert_noop!( + Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), invalid_asset, reward_type), + Error::::AssetNotWhitelisted + ); + }); } From 7ab3e6fd979890ceba5e5504e7e219799d155372 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 1 Jan 2025 18:45:13 +0530 Subject: [PATCH 42/63] wip --- Cargo.lock | 4 ++-- pallets/rewards/src/impls.rs | 0 primitives/src/traits/mod.rs | 2 ++ primitives/src/traits/rewards.rs | 0 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 pallets/rewards/src/impls.rs create mode 100644 primitives/src/traits/rewards.rs diff --git a/Cargo.lock b/Cargo.lock index 0b78899e..d44256b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8825,7 +8825,7 @@ dependencies = [ [[package]] name = "pallet-rewards" -version = "1.2.3" +version = "1.2.4" dependencies = [ "ethabi", "ethereum", @@ -14947,7 +14947,7 @@ dependencies = [ [[package]] name = "tangle-subxt" -version = "0.7.1" +version = "0.7.2" dependencies = [ "parity-scale-codec", "scale-info", diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs new file mode 100644 index 00000000..e69de29b diff --git a/primitives/src/traits/mod.rs b/primitives/src/traits/mod.rs index fef97c98..04e6a277 100644 --- a/primitives/src/traits/mod.rs +++ b/primitives/src/traits/mod.rs @@ -2,8 +2,10 @@ pub mod assets; pub mod data_provider; pub mod multi_asset_delegation; pub mod services; +pub mod rewards; pub use assets::*; pub use data_provider::*; pub use multi_asset_delegation::*; pub use services::*; +pub use rewards::*; \ No newline at end of file diff --git a/primitives/src/traits/rewards.rs b/primitives/src/traits/rewards.rs new file mode 100644 index 00000000..e69de29b From 1cf02eacd3af76866e6b4e1199dd5d0329efcbc6 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:05:03 +0530 Subject: [PATCH 43/63] add precompile and fuzzer --- pallets/rewards/src/impls.rs | 110 +++++ pallets/rewards/src/mock.rs | 12 +- pallets/rewards/src/tests.rs | 677 +++++++++++++++----------- precompiles/rewards/Cargo.toml | 216 ++++++++ precompiles/rewards/Rewards.sol | 93 ++++ precompiles/rewards/fuzzer/Cargo.toml | 38 ++ precompiles/rewards/fuzzer/call.rs | 539 ++++++++++++++++++++ precompiles/rewards/src/lib.rs | 438 +++++++++++++++++ precompiles/rewards/src/mock.rs | 378 ++++++++++++++ precompiles/rewards/src/mock_evm.rs | 331 +++++++++++++ precompiles/rewards/src/tests.rs | 499 +++++++++++++++++++ primitives/src/traits/mod.rs | 4 +- primitives/src/traits/rewards.rs | 119 +++++ 13 files changed, 3150 insertions(+), 304 deletions(-) create mode 100644 precompiles/rewards/Cargo.toml create mode 100644 precompiles/rewards/Rewards.sol create mode 100644 precompiles/rewards/fuzzer/Cargo.toml create mode 100644 precompiles/rewards/fuzzer/call.rs create mode 100644 precompiles/rewards/src/lib.rs create mode 100644 precompiles/rewards/src/mock.rs create mode 100644 precompiles/rewards/src/mock_evm.rs create mode 100644 precompiles/rewards/src/tests.rs diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index e69de29b..9960198e 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -0,0 +1,110 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use crate::{Config, Pallet, UserRewards, UserRewardsOf, BoostInfo, LockMultiplier}; +use frame_support::traits::Currency; +use frame_system::pallet_prelude::BlockNumberFor; +use sp_runtime::traits::{Zero, Saturating}; +use tangle_primitives::{ + services::Asset, + traits::rewards::RewardsManager, +}; + +impl RewardsManager> for Pallet { + fn record_delegation_reward( + account_id: &T::AccountId, + asset: Asset, + amount: T::Balance, + lock_multiplier: u32, + ) -> Result<(), &'static str> { + // Check if asset is whitelisted + if !Self::is_asset_whitelisted(asset) { + return Err("Asset not whitelisted"); + } + + // Get current rewards or create new if none exist + let mut rewards = Self::user_rewards(account_id, asset); + + // Convert lock_multiplier to LockMultiplier enum + let multiplier = match lock_multiplier { + 1 => LockMultiplier::OneMonth, + 2 => LockMultiplier::TwoMonths, + 3 => LockMultiplier::ThreeMonths, + 6 => LockMultiplier::SixMonths, + _ => return Err("Invalid lock multiplier"), + }; + + // Update boost rewards + rewards.boost_rewards = BoostInfo { + amount: rewards.boost_rewards.amount.saturating_add(amount), + multiplier, + expiry: frame_system::Pallet::::block_number().saturating_add( + BlockNumberFor::::from(30u32 * lock_multiplier as u32) + ), + }; + + // Store updated rewards + >::insert(account_id, asset, rewards); + + Ok(()) + } + + fn record_service_reward( + account_id: &T::AccountId, + asset: Asset, + amount: T::Balance, + ) -> Result<(), &'static str> { + // Check if asset is whitelisted + if !Self::is_asset_whitelisted(asset) { + return Err("Asset not whitelisted"); + } + + // Get current rewards or create new if none exist + let mut rewards = Self::user_rewards(account_id, asset); + + // Update service rewards + rewards.service_rewards = rewards.service_rewards.saturating_add(amount); + + // Store updated rewards + >::insert(account_id, asset, rewards); + + Ok(()) + } + + fn query_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result<(T::Balance, T::Balance), &'static str> { + let rewards = Self::user_rewards(account_id, asset); + Ok((rewards.boost_rewards.amount, rewards.service_rewards)) + } + + fn query_delegation_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result { + let rewards = Self::user_rewards(account_id, asset); + Ok(rewards.boost_rewards.amount) + } + + fn query_service_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result { + let rewards = Self::user_rewards(account_id, asset); + Ok(rewards.service_rewards) + } +} \ No newline at end of file diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 3e379ef9..ad0c649f 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -264,12 +264,12 @@ impl pallet_assets::Config for Runtime { } impl pallet_rewards::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type AssetId = AssetId; - type Balance = Balance; - type Currency = Balances; - type Assets = Assets; - type ServiceManager = MockServiceManager; + type RuntimeEvent = RuntimeEvent; + type AssetId = AssetId; + type Balance = Balance; + type Currency = Balances; + type Assets = Assets; + type ServiceManager = MockServiceManager; } pub struct MockServiceManager; diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 207a4065..c3406779 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -20,333 +20,418 @@ use tangle_primitives::services::Asset; // Helper function to set up user rewards fn setup_user_rewards( - account: T::AccountId, - asset: Asset, - restaking_rewards: BalanceOf, - service_rewards: BalanceOf, - boost_amount: BalanceOf, - multiplier: LockMultiplier, - expiry: BlockNumberFor, + account: T::AccountId, + asset: Asset, + restaking_rewards: BalanceOf, + service_rewards: BalanceOf, + boost_amount: BalanceOf, + multiplier: LockMultiplier, + expiry: BlockNumberFor, ) { - let rewards = UserRewards { - restaking_rewards, - service_rewards, - boost_rewards: BoostInfo { - amount: boost_amount, - multiplier, - expiry, - }, - }; - UserRewards::::insert(account, asset, rewards); + let rewards = UserRewards { + restaking_rewards, + service_rewards, + boost_rewards: BoostInfo { amount: boost_amount, multiplier, expiry }, + }; + UserRewards::::insert(account, asset, rewards); } #[test] fn test_whitelist_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::Custom(0u32); - let account: AccountId32 = AccountId32::new([1; 32]); - - // Non-root cannot whitelist asset - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can whitelist asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - assert!(Rewards::::is_asset_whitelisted(asset)); - - // Cannot whitelist same asset twice - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), - Error::::AssetAlreadyWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::Custom(0u32); + let account: AccountId32 = AccountId32::new([1; 32]); + + // Non-root cannot whitelist asset + assert_noop!( + Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can whitelist asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + assert!(Rewards::::is_asset_whitelisted(asset)); + + // Cannot whitelist same asset twice + assert_noop!( + Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), + Error::::AssetAlreadyWhitelisted + ); + }); } #[test] fn test_remove_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::Custom(0u32); - let account: AccountId32 = AccountId32::new([1; 32]); - - // Cannot remove non-whitelisted asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - - // Whitelist the asset first - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Non-root cannot remove asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can remove asset - assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); - assert!(!Rewards::::is_asset_whitelisted(asset)); - - // Cannot remove already removed asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let asset = Asset::Custom(0u32); + let account: AccountId32 = AccountId32::new([1; 32]); + + // Cannot remove non-whitelisted asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + + // Whitelist the asset first + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Non-root cannot remove asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), + sp_runtime::DispatchError::BadOrigin + ); + + // Root can remove asset + assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); + assert!(!Rewards::::is_asset_whitelisted(asset)); + + // Cannot remove already removed asset + assert_noop!( + Rewards::::remove_asset(RuntimeOrigin::root(), asset), + Error::::AssetNotWhitelisted + ); + }); } #[test] fn test_claim_rewards() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Cannot claim rewards for non-whitelisted asset - assert_noop!( - Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), - Error::::AssetNotWhitelisted - ); - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Cannot claim rewards when none are available - assert_noop!( - Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), - Error::::NoRewardsAvailable - ); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Cannot claim rewards for non-whitelisted asset + assert_noop!( + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), + Error::::AssetNotWhitelisted + ); + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Cannot claim rewards when none are available + assert_noop!( + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), + Error::::NoRewardsAvailable + ); + }); } #[test] fn test_reward_score_calculation() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let custom_asset = Asset::Custom(0u32); - let erc20_asset = Asset::Erc20(mock_address(1)); - let reward_type = RewardType::Restaking; - - // Whitelist both assets - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), custom_asset)); - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), erc20_asset)); - - // Set up rewards for custom asset with boost - setup_user_rewards::( - account.clone(), - custom_asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); - - // Set up rewards for ERC20 asset without boost - setup_user_rewards::( - account.clone(), - erc20_asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry - ); - - // Test claiming rewards for both assets - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - custom_asset, - reward_type - )); - - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - erc20_asset, - reward_type - )); - - // Verify rewards are cleared after claiming - let custom_rewards = Rewards::::user_rewards(account.clone(), custom_asset); - assert_eq!(custom_rewards.restaking_rewards, 0u128.into()); - - let erc20_rewards = Rewards::::user_rewards(account.clone(), erc20_asset); - assert_eq!(erc20_rewards.restaking_rewards, 0u128.into()); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let custom_asset = Asset::Custom(0u32); + let erc20_asset = Asset::Erc20(mock_address(1)); + let reward_type = RewardType::Restaking; + + // Whitelist both assets + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), custom_asset)); + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), erc20_asset)); + + // Set up rewards for custom asset with boost + setup_user_rewards::( + account.clone(), + custom_asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + // Set up rewards for ERC20 asset without boost + setup_user_rewards::( + account.clone(), + erc20_asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // Test claiming rewards for both assets + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + custom_asset, + reward_type + )); + + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + erc20_asset, + reward_type + )); + + // Verify rewards are cleared after claiming + let custom_rewards = Rewards::::user_rewards(account.clone(), custom_asset); + assert_eq!(custom_rewards.restaking_rewards, 0u128.into()); + + let erc20_rewards = Rewards::::user_rewards(account.clone(), erc20_asset); + assert_eq!(erc20_rewards.restaking_rewards, 0u128.into()); + }); } #[test] fn test_reward_distribution() { - new_test_ext().execute_with(|| { - let account1: AccountId32 = AccountId32::new([1; 32]); - let account2: AccountId32 = AccountId32::new([2; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up different rewards for each account - setup_user_rewards::( - account1.clone(), - asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); - - setup_user_rewards::( - account2.clone(), - asset, - 200u128.into(), // restaking rewards - 100u128.into(), // service rewards - 400u128.into(), // boost amount - LockMultiplier::SixMonths, - 200u64.into(), // expiry block - ); - - // Both accounts should be able to claim their rewards - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account1.clone()), - asset, - reward_type - )); - - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account2.clone()), - asset, - reward_type - )); - - // Verify rewards are cleared after claiming - let account1_rewards = Rewards::::user_rewards(account1, asset); - assert_eq!(account1_rewards.restaking_rewards, 0u128.into()); - - let account2_rewards = Rewards::::user_rewards(account2, asset); - assert_eq!(account2_rewards.restaking_rewards, 0u128.into()); - }); + new_test_ext().execute_with(|| { + let account1: AccountId32 = AccountId32::new([1; 32]); + let account2: AccountId32 = AccountId32::new([2; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up different rewards for each account + setup_user_rewards::( + account1.clone(), + asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + setup_user_rewards::( + account2.clone(), + asset, + 200u128.into(), // restaking rewards + 100u128.into(), // service rewards + 400u128.into(), // boost amount + LockMultiplier::SixMonths, + 200u64.into(), // expiry block + ); + + // Both accounts should be able to claim their rewards + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account1.clone()), + asset, + reward_type + )); + + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account2.clone()), + asset, + reward_type + )); + + // Verify rewards are cleared after claiming + let account1_rewards = Rewards::::user_rewards(account1, asset); + assert_eq!(account1_rewards.restaking_rewards, 0u128.into()); + + let account2_rewards = Rewards::::user_rewards(account2, asset); + assert_eq!(account2_rewards.restaking_rewards, 0u128.into()); + }); } #[test] fn test_different_reward_types() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up rewards for different reward types - setup_user_rewards::( - account.clone(), - asset, - 100u128.into(), // restaking rewards - 150u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); - - // Test claiming each type of reward - let reward_types = vec![ - RewardType::Restaking, - RewardType::Service, - RewardType::Boost, - ]; - - for reward_type in reward_types { - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - )); - } - - // Verify all rewards are cleared - let rewards = Rewards::::user_rewards(account, asset); - assert_eq!(rewards.restaking_rewards, 0u128.into()); - assert_eq!(rewards.service_rewards, 0u128.into()); - assert_eq!(rewards.boost_rewards.amount, 0u128.into()); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up rewards for different reward types + setup_user_rewards::( + account.clone(), + asset, + 100u128.into(), // restaking rewards + 150u128.into(), // service rewards + 200u128.into(), // boost amount + LockMultiplier::ThreeMonths, + 100u64.into(), // expiry block + ); + + // Test claiming each type of reward + let reward_types = vec![RewardType::Restaking, RewardType::Service, RewardType::Boost]; + + for reward_type in reward_types { + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + } + + // Verify all rewards are cleared + let rewards = Rewards::::user_rewards(account, asset); + assert_eq!(rewards.restaking_rewards, 0u128.into()); + assert_eq!(rewards.service_rewards, 0u128.into()); + assert_eq!(rewards.boost_rewards.amount, 0u128.into()); + }); } #[test] fn test_multiple_claims() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up initial rewards - setup_user_rewards::( - account.clone(), - asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry - ); - - // First claim should succeed - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - )); - - // Second claim should fail as rewards are cleared - assert_noop!( - Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), - Error::::NoRewardsAvailable - ); - - // Set up new rewards - setup_user_rewards::( - account.clone(), - asset, - 200u128.into(), // restaking rewards - 100u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry - ); - - // Should be able to claim again with new rewards - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - )); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Whitelist the asset + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Set up initial rewards + setup_user_rewards::( + account.clone(), + asset, + 100u128.into(), // restaking rewards + 50u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // First claim should succeed + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + + // Second claim should fail as rewards are cleared + assert_noop!( + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), + Error::::NoRewardsAvailable + ); + + // Set up new rewards + setup_user_rewards::( + account.clone(), + asset, + 200u128.into(), // restaking rewards + 100u128.into(), // service rewards + 0u128.into(), // no boost + LockMultiplier::OneMonth, + 0u64.into(), // no expiry + ); + + // Should be able to claim again with new rewards + assert_ok!(Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + )); + }); } #[test] fn test_edge_cases() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Test with zero rewards - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - assert_noop!( - Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset, reward_type), - Error::::NoRewardsAvailable - ); - - // Test with invalid asset ID - let invalid_asset = Asset::Custom(u32::MAX); - assert_noop!( - Rewards::::claim_rewards(RuntimeOrigin::signed(account.clone()), invalid_asset, reward_type), - Error::::AssetNotWhitelisted - ); - }); + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + let reward_type = RewardType::Restaking; + + // Test with zero rewards + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + assert_noop!( + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset, + reward_type + ), + Error::::NoRewardsAvailable + ); + + // Test with invalid asset ID + let invalid_asset = Asset::Custom(u32::MAX); + assert_noop!( + Rewards::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + invalid_asset, + reward_type + ), + Error::::AssetNotWhitelisted + ); + }); +} + +#[test] +fn test_rewards_manager_implementation() { + new_test_ext().execute_with(|| { + use tangle_primitives::traits::rewards::RewardsManager; + + let account: AccountId32 = AccountId32::new([1; 32]); + let asset = Asset::Custom(0u32); + + // Whitelist the asset first + assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + + // Test recording delegation reward + assert_ok!(Rewards::::record_delegation_reward( + &account, + asset, + 100u128.into(), + 3, // 3 months lock + )); + + // Verify delegation rewards + let delegation_rewards = Rewards::::query_delegation_rewards(&account, asset) + .expect("Should return delegation rewards"); + assert_eq!(delegation_rewards, 100u128.into()); + + // Test recording service reward + assert_ok!(Rewards::::record_service_reward(&account, asset, 50u128.into(),)); + + // Verify service rewards + let service_rewards = Rewards::::query_service_rewards(&account, asset) + .expect("Should return service rewards"); + assert_eq!(service_rewards, 50u128.into()); + + // Test querying total rewards + let (delegation, service) = Rewards::::query_rewards(&account, asset) + .expect("Should return total rewards"); + assert_eq!(delegation, 100u128.into()); + assert_eq!(service, 50u128.into()); + + // Test recording rewards for non-whitelisted asset + let non_whitelisted = Asset::Custom(1u32); + assert_eq!( + Rewards::::record_delegation_reward( + &account, + non_whitelisted, + 100u128.into(), + 3 + ), + Err("Asset not whitelisted") + ); + assert_eq!( + Rewards::::record_service_reward(&account, non_whitelisted, 50u128.into()), + Err("Asset not whitelisted") + ); + + // Test invalid lock multiplier + assert_eq!( + Rewards::::record_delegation_reward(&account, asset, 100u128.into(), 4), + Err("Invalid lock multiplier") + ); + + // Test accumulating rewards + assert_ok!( + Rewards::::record_delegation_reward(&account, asset, 50u128.into(), 3,) + ); + assert_ok!(Rewards::::record_service_reward(&account, asset, 25u128.into(),)); + + let (delegation, service) = Rewards::::query_rewards(&account, asset) + .expect("Should return total rewards"); + assert_eq!(delegation, 150u128.into()); // 100 + 50 + assert_eq!(service, 75u128.into()); // 50 + 25 + }); } diff --git a/precompiles/rewards/Cargo.toml b/precompiles/rewards/Cargo.toml new file mode 100644 index 00000000..582aa066 --- /dev/null +++ b/precompiles/rewards/Cargo.toml @@ -0,0 +1,216 @@ +[package] +name = "pallet-evm-precompile-rewards" +version = "0.1.0" +authors = { workspace = true } +edition = "2021" +description = "A Precompile to make pallet-rewards calls encoding accessible to pallet-evm" + +[dependencies] +precompile-utils = { workspace = true } + +# Substrate +frame-support = { workspace = true } +frame-system = { workspace = true } +pallet-balances = { workspace = true } +pallet-multi-asset-delegation = { workspace = true } +parity-scale-codec = { workspace = true, features = ["derive"] } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +# Frontier +fp-evm = { workspace = true } +pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } + +tangle-primitives = { workspace = true } + +derive_more = { workspace = true, features = ["full"], optional = true } +hex-literal = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +sha3 = { workspace = true, optional = true } +ethereum = { workspace = true, features = ["with-codec"], optional = true } +ethers = { version = "2.0", optional = true } +hex = { workspace = true, optional = true } +num_enum = { workspace = true, optional = true } +libsecp256k1 = { workspace = true, optional = true } +serde_json = { workspace = true, optional = true } +smallvec = { workspace = true, optional = true } +sp-keystore = { workspace = true, optional = true } +pallet-assets = { workspace = true, features = ["std"], optional = true } +pallet-timestamp = { workspace = true, features = ["std"], optional = true } +scale-info = { workspace = true, features = ["derive", "std"], optional = true } +sp-io = { workspace = true, features = ["std"], optional = true } +fp-account = { workspace = true, optional = true } +fp-consensus = { workspace = true, optional = true } +fp-dynamic-fee = { workspace = true, optional = true } +fp-ethereum = { workspace = true, optional = true } +fp-rpc = { workspace = true, optional = true } +fp-self-contained = { workspace = true, optional = true } +fp-storage = { workspace = true, optional = true } +pallet-base-fee = { workspace = true, optional = true } +pallet-dynamic-fee = { workspace = true, optional = true } +pallet-ethereum = { workspace = true, optional = true } +pallet-evm-chain-id = { workspace = true, optional = true } +pallet-evm-precompile-blake2 = { workspace = true, optional = true } +pallet-evm-precompile-bn128 = { workspace = true, optional = true } +pallet-evm-precompile-curve25519 = { workspace = true, optional = true } +pallet-evm-precompile-ed25519 = { workspace = true, optional = true } +pallet-evm-precompile-modexp = { workspace = true, optional = true } +pallet-evm-precompile-sha3fips = { workspace = true, optional = true } +pallet-evm-precompile-simple = { workspace = true, optional = true } +pallet-session = { workspace = true, optional = true } +pallet-staking = { workspace = true, optional = true } +sp-staking = { workspace = true, optional = true } +frame-election-provider-support = { workspace = true, optional = true } +ethabi = { workspace = true, optional = true } + +[dev-dependencies] +derive_more = { workspace = true, features = ["full"] } +hex-literal = { workspace = true } +serde = { workspace = true } +sha3 = { workspace = true } +ethereum = { workspace = true, features = ["with-codec"] } +ethers = "2.0" +hex = { workspace = true } +num_enum = { workspace = true } +libsecp256k1 = { workspace = true } +serde_json = { workspace = true } +smallvec = { workspace = true } +sp-keystore = { workspace = true } + + +precompile-utils = { workspace = true, features = ["std", "testing"] } + +# Substrate +pallet-balances = { workspace = true, features = ["std"] } +pallet-assets = { workspace = true, features = ["std"] } +pallet-timestamp = { workspace = true, features = ["std"] } +scale-info = { workspace = true, features = ["derive", "std"] } +sp-io = { workspace = true, features = ["std"] } + +# Frontier Primitive +fp-account = { workspace = true } +fp-consensus = { workspace = true } +fp-dynamic-fee = { workspace = true } +fp-ethereum = { workspace = true } +fp-rpc = { workspace = true } +fp-self-contained = { workspace = true } +fp-storage = { workspace = true } + +# Frontier FRAME +pallet-base-fee = { workspace = true } +pallet-dynamic-fee = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } + +pallet-evm-precompile-blake2 = { workspace = true } +pallet-evm-precompile-bn128 = { workspace = true } +pallet-evm-precompile-curve25519 = { workspace = true } +pallet-evm-precompile-ed25519 = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-sha3fips = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } + +pallet-session = { workspace = true } +pallet-staking = { workspace = true } +sp-staking = { workspace = true } +frame-election-provider-support = { workspace = true } + +ethabi = { workspace = true } + +[features] +default = ["std"] +fuzzing = [ + "derive_more", + "hex-literal", + "serde", + "sha3", + "ethereum", + "ethers", + "hex", + "num_enum", + "libsecp256k1", + "serde_json", + "smallvec", + "sp-keystore", + "pallet-assets", + "pallet-timestamp", + "scale-info", + "sp-io", + "fp-account", + "fp-consensus", + "fp-dynamic-fee", + "fp-ethereum", + "fp-rpc", + "fp-self-contained", + "fp-storage", + "pallet-base-fee", + "pallet-dynamic-fee", + "pallet-ethereum", + "pallet-evm-chain-id", + "pallet-evm-precompile-blake2", + "pallet-evm-precompile-bn128", + "pallet-evm-precompile-curve25519", + "pallet-evm-precompile-ed25519", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", + "pallet-session", + "pallet-staking", + "sp-staking", + "frame-election-provider-support", + "ethabi", +] +std = [ + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "pallet-evm/std", + "pallet-multi-asset-delegation/std", + "parity-scale-codec/std", + "precompile-utils/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", + "tangle-primitives/std", + "pallet-assets/std", + "hex/std", + "scale-info/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-core/std", + "sp-std/std", + "sp-io/std", + "tangle-primitives/std", + "pallet-balances/std", + "pallet-timestamp/std", + "fp-account/std", + "fp-consensus/std", + "fp-dynamic-fee/std", + "fp-ethereum/std", + "fp-evm/std", + "fp-rpc/std", + "fp-self-contained/std", + "fp-storage/std", + "pallet-base-fee/std", + "pallet-dynamic-fee/std", + "pallet-ethereum/std", + "pallet-evm/std", + "pallet-evm-chain-id/std", + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-precompile-blake2/std", + "pallet-evm-precompile-bn128/std", + "pallet-evm-precompile-curve25519/std", + "pallet-evm-precompile-ed25519/std", + "precompile-utils/std", + "serde/std", + "pallet-session/std", + "pallet-staking/std", + "sp-staking/std", + "frame-election-provider-support/std", +] diff --git a/precompiles/rewards/Rewards.sol b/precompiles/rewards/Rewards.sol new file mode 100644 index 00000000..7bdd2f9e --- /dev/null +++ b/precompiles/rewards/Rewards.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The MultiAssetDelegation contract's address. +address constant MULTI_ASSET_DELEGATION = 0x0000000000000000000000000000000000000822; + +/// @dev The MultiAssetDelegation contract's instance. +MultiAssetDelegation constant MULTI_ASSET_DELEGATION_CONTRACT = MultiAssetDelegation(MULTI_ASSET_DELEGATION); + +/// @author The Tangle Team +/// @title Pallet MultiAssetDelegation Interface +/// @title The interface through which solidity contracts will interact with the MultiAssetDelegation pallet +/// @custom:address 0x0000000000000000000000000000000000000822 +interface MultiAssetDelegation { + /// @dev Join as an operator with a bond amount. + /// @param bondAmount The amount to bond as an operator. + function joinOperators(uint256 bondAmount) external returns (uint8); + + /// @dev Schedule to leave as an operator. + function scheduleLeaveOperators() external returns (uint8); + + /// @dev Cancel the scheduled leave as an operator. + function cancelLeaveOperators() external returns (uint8); + + /// @dev Execute the leave as an operator. + function executeLeaveOperators() external returns (uint8); + + /// @dev Bond more as an operator. + /// @param additionalBond The additional amount to bond. + function operatorBondMore(uint256 additionalBond) external returns (uint8); + + /// @dev Schedule to unstake as an operator. + /// @param unstakeAmount The amount to unstake. + function scheduleOperatorUnstake(uint256 unstakeAmount) external returns (uint8); + + /// @dev Execute the unstake as an operator. + function executeOperatorUnstake() external returns (uint8); + + /// @dev Cancel the scheduled unstake as an operator. + function cancelOperatorUnstake() external returns (uint8); + + /// @dev Go offline as an operator. + function goOffline() external returns (uint8); + + /// @dev Go online as an operator. + function goOnline() external returns (uint8); + + /// @dev Deposit an amount of an asset. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to deposit. + function deposit(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + + /// @dev Schedule a withdrawal of an amount of an asset. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to withdraw. + function scheduleWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + + /// @dev Execute the scheduled withdrawal. + function executeWithdraw() external returns (uint8); + + /// @dev Cancel the scheduled withdrawal. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to cancel withdrawal. + function cancelWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + + /// @dev Delegate an amount of an asset to an operator. + /// @param operator The address of the operator. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to delegate. + /// @param blueprintSelection The blueprint selection. + function delegate(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount, uint64[] memory blueprintSelection) external returns (uint8); + + /// @dev Schedule an unstake of an amount of an asset as a delegator. + /// @param operator The address of the operator. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to unstake. + function scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + + /// @dev Execute the scheduled unstake as a delegator. + function executeDelegatorUnstake() external returns (uint8); + + /// @dev Cancel the scheduled unstake as a delegator. + /// @param operator The address of the operator. + /// @param assetId The ID of the asset (0 for ERC20). + /// @param tokenAddress The address of the ERC20 token (if assetId is 0). + /// @param amount The amount to cancel unstake. + function cancelDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); +} \ No newline at end of file diff --git a/precompiles/rewards/fuzzer/Cargo.toml b/precompiles/rewards/fuzzer/Cargo.toml new file mode 100644 index 00000000..ae78a690 --- /dev/null +++ b/precompiles/rewards/fuzzer/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "pallet-evm-precompile-multi-asset-delegation-fuzzer" +version = "2.0.0" +authors.workspace = true +edition.workspace = true +license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true +description = "Fuzzer for pallet-multi-asset-delegation precompile" +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +honggfuzz = { workspace = true } + + +pallet-multi-asset-delegation = { workspace = true, features = ["fuzzing"], default-features = true } +pallet-evm-precompile-multi-asset-delegation = { features = ["fuzzing"], workspace = true, default-features = true } + +frame-system = { workspace = true, default-features = true } +frame-support = { workspace = true, default-features = true } + +fp-evm = { workspace = true } +precompile-utils = { workspace = true, features = ["std", "testing"] } +pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } + +sp-runtime = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sp-tracing = { workspace = true, default-features = true } + +rand = { features = ["small_rng"], workspace = true, default-features = true } +log = { workspace = true, default-features = true } + +[[bin]] +name = "mad-precompile-fuzzer" +path = "call.rs" diff --git a/precompiles/rewards/fuzzer/call.rs b/precompiles/rewards/fuzzer/call.rs new file mode 100644 index 00000000..34fe1cb3 --- /dev/null +++ b/precompiles/rewards/fuzzer/call.rs @@ -0,0 +1,539 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run mad-fuzzer`. `honggfuzz` CLI +//! options can be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug mad-fuzzer hfuzz_workspace/mad-fuzzer/*.fuzz`. + +use fp_evm::Context; +use fp_evm::PrecompileSet; +use frame_support::traits::{Currency, Get}; +use honggfuzz::fuzz; +use pallet_evm::AddressMapping; +use pallet_evm_precompile_multi_asset_delegation::{ + mock::*, mock_evm::PrecompilesValue, MultiAssetDelegationPrecompileCall as MADPrecompileCall, +}; +use pallet_multi_asset_delegation::{ + mock::{Asset, AssetId}, + pallet as mad, + types::*, +}; +use precompile_utils::prelude::*; +use precompile_utils::testing::*; +use rand::{seq::SliceRandom, Rng}; +use sp_runtime::traits::{Scale, Zero}; + +const MAX_ED_MULTIPLE: Balance = 10_000; +const MIN_ED_MULTIPLE: Balance = 10; + +type PCall = MADPrecompileCall; + +fn random_address(rng: &mut R) -> Address { + Address(rng.gen::<[u8; 20]>().into()) +} + +/// Grab random accounts. +fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, Address) { + let addr = random_address(rng); + let signer = >::into_account_id(addr.0); + (RuntimeOrigin::signed(signer), addr) +} + +fn random_ed_multiple(rng: &mut R) -> Balance { + let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); + ExistentialDeposit::get() * multiple +} + +fn random_asset(rng: &mut R) -> Asset { + let asset_id = rng.gen_range(1..u128::MAX); + let is_evm = rng.gen_bool(0.5); + if is_evm { + let evm_address = rng.gen::<[u8; 20]>().into(); + Asset::Erc20(evm_address) + } else { + Asset::Custom(asset_id) + } +} + +fn fund_account(rng: &mut R, address: &Address) { + let target_amount = random_ed_multiple(rng); + let signer = >::into_account_id(address.0); + if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(signer)) { + let _ = Balances::deposit_creating(&signer, top_up); + } + assert!(Balances::free_balance(signer) >= target_amount); +} + +/// Join operators call. +fn join_operators_call(rng: &mut R, who: &Address) -> (PCall, Address) { + let minimum_bond = <::MinOperatorBondAmount as Get>::get(); + let multiplier = rng.gen_range(1..50u64); + let who_account_id = >::into_account_id(who.0); + let _ = Balances::deposit_creating(&who_account_id, minimum_bond.mul(multiplier)); + let bond_amount = minimum_bond.mul(multiplier).into(); + (PCall::join_operators { bond_amount }, *who) +} + +fn random_calls(mut rng: &mut R) -> impl IntoIterator { + let op = PCall::selectors().choose(rng).cloned().unwrap(); + match op { + _ if op == PCall::join_operators_selectors()[0] => { + // join_operators + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(&mut rng, &who)] + }, + _ if op == PCall::schedule_leave_operators_selectors()[0] => { + // Schedule leave operators + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::schedule_leave_operators {}, who)] + }, + _ if op == PCall::cancel_leave_operators_selectors()[0] => { + // Cancel leave operators + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::cancel_leave_operators {}, who)] + }, + _ if op == PCall::execute_leave_operators_selectors()[0] => { + // Execute leave operators + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::execute_leave_operators {}, who)] + }, + _ if op == PCall::operator_bond_more_selectors()[0] => { + // Operator bond more + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let additional_bond = random_ed_multiple(&mut rng).into(); + vec![ + join_operators_call(rng, &who), + (PCall::operator_bond_more { additional_bond }, who), + ] + }, + _ if op == PCall::schedule_operator_unstake_selectors()[0] => { + // Schedule operator unstake + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let unstake_amount = random_ed_multiple(&mut rng).into(); + vec![ + join_operators_call(rng, &who), + (PCall::schedule_operator_unstake { unstake_amount }, who), + ] + }, + _ if op == PCall::execute_operator_unstake_selectors()[0] => { + // Execute operator unstake + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::execute_operator_unstake {}, who)] + }, + _ if op == PCall::cancel_operator_unstake_selectors()[0] => { + // Cancel operator unstake + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::cancel_operator_unstake {}, who)] + }, + _ if op == PCall::go_offline_selectors()[0] => { + // Go offline + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::go_offline {}, who)] + }, + _ if op == PCall::go_online_selectors()[0] => { + // Go online + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![join_operators_call(rng, &who), (PCall::go_online {}, who)] + }, + _ if op == PCall::deposit_selectors()[0] => { + // Deposit + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + vec![(PCall::deposit { asset_id, amount, token_address }, who)] + }, + _ if op == PCall::schedule_withdraw_selectors()[0] => { + // Schedule withdraw + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + vec![(PCall::schedule_withdraw { asset_id, token_address, amount }, who)] + }, + _ if op == PCall::execute_withdraw_selectors()[0] => { + // Execute withdraw + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![(PCall::execute_withdraw {}, who)] + }, + _ if op == PCall::cancel_withdraw_selectors()[0] => { + // Cancel withdraw + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + vec![(PCall::cancel_withdraw { asset_id, amount, token_address }, who)] + }, + _ if op == PCall::delegate_selectors()[0] => { + // Delegate + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (_, operator) = random_signed_origin(&mut rng); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + let blueprint_selection = { + let count = rng.gen_range(1..MaxDelegatorBlueprints::get()); + (0..count).map(|_| rng.gen::()).collect::>() + }; + vec![ + join_operators_call(&mut rng, &operator), + ( + PCall::delegate { + operator: operator.0.into(), + asset_id, + token_address, + amount, + blueprint_selection, + }, + who, + ), + ] + }, + _ if op == PCall::schedule_delegator_unstake_selectors()[0] => { + // Schedule delegator unstakes + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (_, operator) = random_signed_origin(&mut rng); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + vec![ + join_operators_call(&mut rng, &operator), + ( + PCall::schedule_delegator_unstake { + operator: operator.0.into(), + asset_id, + token_address, + amount, + }, + who, + ), + ] + }, + _ if op == PCall::execute_delegator_unstake_selectors()[0] => { + // Execute delegator unstake + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + vec![(PCall::execute_delegator_unstake {}, who)] + }, + _ if op == PCall::cancel_delegator_unstake_selectors()[0] => { + // Cancel delegator unstake + let who = random_address(&mut rng); + fund_account(&mut rng, &who); + let (_, operator) = random_signed_origin(&mut rng); + let (asset_id, token_address) = match random_asset(&mut rng) { + Asset::Custom(id) => (id.into(), Default::default()), + Asset::Erc20(token) => (0.into(), token.into()), + }; + let amount = random_ed_multiple(&mut rng).into(); + vec![ + join_operators_call(&mut rng, &operator), + ( + PCall::cancel_delegator_unstake { + operator: operator.0.into(), + asset_id, + token_address, + amount, + }, + who, + ), + ] + }, + _ => { + unimplemented!("unknown call name: {}", op) + }, + } +} + +fn main() { + sp_tracing::try_init_simple(); + let mut ext = ExtBuilder::default().build(); + let mut block_number = 1; + let to = Precompile1.into(); + loop { + fuzz!(|seed: [u8; 32]| { + use ::rand::{rngs::SmallRng, SeedableRng}; + let mut rng = SmallRng::from_seed(seed); + + ext.execute_with(|| { + System::set_block_number(block_number); + for (call, who) in random_calls(&mut rng) { + let mut handle = MockHandle::new( + to, + Context { + address: to, + caller: who.into(), + apparent_value: Default::default(), + }, + ); + let mut handle_clone = MockHandle::new( + to, + Context { + address: to, + caller: who.into(), + apparent_value: Default::default(), + }, + ); + let encoded = call.encode(); + handle.input = encoded.clone(); + let call_clone = PCall::parse_call_data(&mut handle).unwrap(); + handle_clone.input = encoded; + let outcome = PrecompilesValue::get().execute(&mut handle).unwrap(); + sp_tracing::trace!(?who, ?outcome, "fuzzed call"); + + // execute sanity checks at a fixed interval, possibly on every block. + if let Ok(out) = outcome { + sp_tracing::info!("running sanity checks.."); + do_sanity_checks(call_clone, who, out); + } + } + + System::reset_events(); + block_number += 1; + }); + }) + } +} + +/// Perform sanity checks on the state after a call is executed successfully. +#[allow(unused)] +fn do_sanity_checks(call: PCall, origin: Address, outcome: PrecompileOutput) { + let caller = >::into_account_id(origin.0); + match call { + PCall::join_operators { bond_amount } => { + assert!(mad::Operators::::contains_key(caller), "operator not found"); + assert_eq!( + MultiAssetDelegation::operator_info(caller).unwrap_or_default().stake, + bond_amount.as_u64() + ); + assert!( + Balances::reserved_balance(caller).ge(&bond_amount.as_u64()), + "bond amount not reserved" + ); + }, + PCall::schedule_leave_operators {} => { + assert!(mad::Operators::::contains_key(caller), "operator not found"); + let current_round = mad::CurrentRound::::get(); + let leaving_time = + <::LeaveOperatorsDelay as Get>::get() + current_round; + assert_eq!( + mad::Operators::::get(caller).unwrap_or_default().status, + OperatorStatus::Leaving(leaving_time) + ); + }, + PCall::cancel_leave_operators {} => { + assert_eq!( + mad::Operators::::get(caller).unwrap_or_default().status, + OperatorStatus::Active + ); + }, + PCall::execute_leave_operators {} => { + assert!(!mad::Operators::::contains_key(caller), "operator not removed"); + assert!(Balances::reserved_balance(caller).is_zero(), "bond amount not unreserved"); + }, + PCall::operator_bond_more { additional_bond } => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + assert!(info.stake.ge(&additional_bond.as_u64()), "bond amount not increased"); + assert!( + Balances::reserved_balance(caller).ge(&additional_bond.as_u64()), + "bond amount not reserved" + ); + }, + PCall::schedule_operator_unstake { unstake_amount } => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + let current_round = MultiAssetDelegation::current_round(); + let unstake_request = OperatorBondLessRequest { + amount: unstake_amount.as_u64(), + request_time: current_round, + }; + assert_eq!(info.request, Some(unstake_request), "unstake request not set"); + }, + PCall::execute_operator_unstake {} => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + assert!(info.request.is_none(), "unstake request not removed"); + // reserved balance should be reduced and equal to the stake + assert!( + Balances::reserved_balance(caller).eq(&info.stake), + "reserved balance not equal to stake" + ); + }, + PCall::cancel_operator_unstake {} => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + assert!(info.request.is_none(), "unstake request not removed"); + }, + PCall::go_offline {} => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + assert_eq!(info.status, OperatorStatus::Inactive, "status not set to inactive"); + }, + PCall::go_online {} => { + let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); + assert_eq!(info.status, OperatorStatus::Active, "status not set to active"); + }, + PCall::deposit { asset_id, amount, token_address } => { + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + match deposit_asset { + Asset::Custom(id) => { + let pallet_balance = + Assets::balance(id, MultiAssetDelegation::pallet_account()); + assert!(pallet_balance.ge(&amount.as_u64()), "pallet balance not enough"); + }, + Asset::Erc20(token) => { + let pallet_balance = MultiAssetDelegation::query_erc20_balance_of( + token, + MultiAssetDelegation::pallet_evm_account(), + ) + .unwrap_or_default() + .0; + assert!(pallet_balance.ge(&amount), "pallet balance not enough"); + }, + }; + + assert_eq!( + MultiAssetDelegation::delegators(caller) + .unwrap_or_default() + .calculate_delegation_by_asset(deposit_asset), + amount.as_u64() + ); + }, + PCall::schedule_withdraw { asset_id, amount, token_address } => { + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + let round = MultiAssetDelegation::current_round(); + assert!( + MultiAssetDelegation::delegators(caller) + .unwrap_or_default() + .get_withdraw_requests() + .contains(&WithdrawRequest { + asset_id: deposit_asset, + amount: amount.as_u64(), + requested_round: round + }), + "withdraw request not found" + ); + }, + PCall::execute_withdraw { .. } => { + assert!( + MultiAssetDelegation::delegators(caller) + .unwrap_or_default() + .get_withdraw_requests() + .is_empty(), + "withdraw requests not removed" + ); + }, + PCall::cancel_withdraw { asset_id, amount, token_address } => { + let round = MultiAssetDelegation::current_round(); + + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + assert!( + !MultiAssetDelegation::delegators(caller) + .unwrap_or_default() + .get_withdraw_requests() + .contains(&WithdrawRequest { + asset_id: deposit_asset, + amount: amount.as_u64(), + requested_round: round + }), + "withdraw request not removed" + ); + }, + PCall::delegate { operator, asset_id, amount, token_address, .. } => { + let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + let operator_account = AccountId::from(operator.0); + let delegator = MultiAssetDelegation::delegators(caller).unwrap_or_default(); + let operator_info = + MultiAssetDelegation::operator_info(operator_account).unwrap_or_default(); + assert!( + delegator + .calculate_delegation_by_operator(operator_account) + .iter() + .find_map(|x| { + if x.asset_id == deposit_asset { + Some(x.amount) + } else { + None + } + }) + .ge(&Some(amount.as_u64())), + "delegation amount not set" + ); + assert!( + operator_info + .delegations + .iter() + .find_map(|x| { + if x.delegator == caller && x.asset_id == deposit_asset { + Some(x.amount) + } else { + None + } + }) + .ge(&Some(amount.as_u64())), + "delegator not added to operator" + ); + }, + _ => { + // ignore other calls + }, + } +} diff --git a/precompiles/rewards/src/lib.rs b/precompiles/rewards/src/lib.rs new file mode 100644 index 00000000..05100dc9 --- /dev/null +++ b/precompiles/rewards/src/lib.rs @@ -0,0 +1,438 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// This file is part of pallet-evm-precompile-multi-asset-delegation package. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! This file contains the implementation of the MultiAssetDelegationPrecompile struct which +//! provides an interface between the EVM and the native MultiAssetDelegation pallet of the runtime. +//! It allows EVM contracts to call functions of the MultiAssetDelegation pallet, in order to enable +//! EVM accounts to interact with the delegation system. +//! +//! The MultiAssetDelegationPrecompile struct implements core methods that correspond to the +//! functions of the MultiAssetDelegation pallet. These methods can be called from EVM contracts. +//! They include functions to join as an operator, delegate assets, withdraw assets, etc. +//! +//! Each method records the gas cost for the operation, performs the requested operation, and +//! returns the result in a format that can be used by the EVM. +//! +//! The MultiAssetDelegationPrecompile struct is generic over the Runtime type, which is the type of +//! the runtime that includes the MultiAssetDelegation pallet. This allows the precompile to work +//! with any runtime that includes the MultiAssetDelegation pallet and meets the other trait bounds +//! required by the precompile. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(any(test, feature = "fuzzing"))] +pub mod mock; +#[cfg(any(test, feature = "fuzzing"))] +pub mod mock_evm; +#[cfg(test)] +mod tests; + +use fp_evm::PrecompileHandle; +use frame_support::{ + dispatch::{GetDispatchInfo, PostDispatchInfo}, + traits::Currency, +}; +use pallet_evm::AddressMapping; +use pallet_multi_asset_delegation::types::DelegatorBlueprintSelection; +use precompile_utils::prelude::*; +use sp_core::{H160, H256, U256}; +use sp_runtime::traits::Dispatchable; +use sp_std::{marker::PhantomData, vec::Vec}; +use tangle_primitives::{services::Asset, types::WrappedAccountId32}; + +type BalanceOf = + <::Currency as Currency< + ::AccountId, + >>::Balance; + +type AssetIdOf = ::AssetId; + +pub struct MultiAssetDelegationPrecompile(PhantomData); + +#[precompile_utils::precompile] +impl MultiAssetDelegationPrecompile +where + Runtime: pallet_multi_asset_delegation::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, + BalanceOf: TryFrom + Into + solidity::Codec, + AssetIdOf: TryFrom + Into + From, + Runtime::AccountId: From, +{ + #[precompile::public("joinOperators(uint256)")] + fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let bond_amount: BalanceOf = + bond_amount.try_into().map_err(|_| revert("Invalid bond amount"))?; + let call = pallet_multi_asset_delegation::Call::::join_operators { bond_amount }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("scheduleLeaveOperators()")] + fn schedule_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::schedule_leave_operators {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("cancelLeaveOperators()")] + fn cancel_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::cancel_leave_operators {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("executeLeaveOperators()")] + fn execute_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::execute_leave_operators {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("operatorBondMore(uint256)")] + fn operator_bond_more(handle: &mut impl PrecompileHandle, additional_bond: U256) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let additional_bond: BalanceOf = + additional_bond.try_into().map_err(|_| revert("Invalid bond amount"))?; + let call = + pallet_multi_asset_delegation::Call::::operator_bond_more { additional_bond }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("executeWithdraw()")] + fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::execute_withdraw { + evm_address: Some(handle.context().caller), + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("scheduleOperatorUnstake(uint256)")] + fn schedule_operator_unstake( + handle: &mut impl PrecompileHandle, + unstake_amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let unstake_amount: BalanceOf = + unstake_amount.try_into().map_err(|_| revert("Invalid unstake amount"))?; + let call = pallet_multi_asset_delegation::Call::::schedule_operator_unstake { + unstake_amount, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("executeOperatorUnstake()")] + fn execute_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::execute_operator_unstake {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("cancelOperatorUnstake()")] + fn cancel_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::cancel_operator_unstake {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("goOffline()")] + fn go_offline(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::go_offline {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("goOnline()")] + fn go_online(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::go_online {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("deposit(uint256,address,uint256)")] + fn deposit( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::deposit { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + evm_address: Some(caller), + }, + )?; + + Ok(()) + } + + #[precompile::public("scheduleWithdraw(uint256,address,uint256)")] + fn schedule_withdraw( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::schedule_withdraw { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; + + Ok(()) + } + + #[precompile::public("cancelWithdraw(uint256,address,uint256)")] + fn cancel_withdraw( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::cancel_withdraw { + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; + + Ok(()) + } + + #[precompile::public("delegate(bytes32,uint256,address,uint256,uint64[])")] + fn delegate( + handle: &mut impl PrecompileHandle, + operator: H256, + asset_id: U256, + token_address: Address, + amount: U256, + blueprint_selection: Vec, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::delegate { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + blueprint_selection: DelegatorBlueprintSelection::Fixed( + blueprint_selection.try_into().map_err(|_| { + RevertReason::custom("Too many blueprint ids for fixed selection") + })?, + ), + }, + )?; + + Ok(()) + } + + #[precompile::public("scheduleDelegatorUnstake(bytes32,uint256,address,uint256)")] + fn schedule_delegator_unstake( + handle: &mut impl PrecompileHandle, + operator: H256, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; + + Ok(()) + } + + #[precompile::public("executeDelegatorUnstake()")] + fn execute_delegator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = pallet_multi_asset_delegation::Call::::execute_delegator_unstake {}; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("cancelDelegatorUnstake(bytes32,uint256,address,uint256)")] + fn cancel_delegator_unstake( + handle: &mut impl PrecompileHandle, + operator: H256, + asset_id: U256, + token_address: Address, + amount: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let operator = + Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); + + let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), amount) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { + operator, + asset_id: deposit_asset, + amount: amount + .try_into() + .map_err(|_| RevertReason::value_is_too_large("amount"))?, + }, + )?; + + Ok(()) + } +} diff --git a/precompiles/rewards/src/mock.rs b/precompiles/rewards/src/mock.rs new file mode 100644 index 00000000..6d5407aa --- /dev/null +++ b/precompiles/rewards/src/mock.rs @@ -0,0 +1,378 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// This file is part of pallet-evm-precompile-multi-asset-delegation package. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test utilities +use super::*; +use crate::mock_evm::*; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU64}, + weights::Weight, + PalletId, +}; +use pallet_evm::GasWeightMapping; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; +use sp_core::{ + self, + sr25519::{Public as sr25519Public, Signature}, + ConstU32, H160, +}; +use sp_runtime::{ + traits::{IdentifyAccount, Verify}, + AccountId32, BuildStorage, +}; +use tangle_primitives::{ + services::{EvmAddressMapping, EvmGasWeightMapping}, + ServiceManager, +}; + +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; +pub type Balance = u64; + +type Block = frame_system::mocking::MockBlock; +type AssetId = u128; + +const PRECOMPILE_ADDRESS_BYTES: [u8; 32] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +]; + +#[derive( + Eq, + PartialEq, + Ord, + PartialOrd, + Clone, + Encode, + Decode, + Debug, + MaxEncodedLen, + Serialize, + Deserialize, + derive_more::Display, + scale_info::TypeInfo, +)] +pub enum TestAccount { + Empty, + Alex, + Bobo, + Dave, + Charlie, + Eve, + PrecompileAddress, +} + +impl Default for TestAccount { + fn default() -> Self { + Self::Empty + } +} + +// needed for associated type in pallet_evm +impl AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> AccountId32 { + match h160_account { + a if a == H160::repeat_byte(0x01) => TestAccount::Alex.into(), + a if a == H160::repeat_byte(0x02) => TestAccount::Bobo.into(), + a if a == H160::repeat_byte(0x03) => TestAccount::Charlie.into(), + a if a == H160::repeat_byte(0x04) => TestAccount::Dave.into(), + a if a == H160::repeat_byte(0x05) => TestAccount::Eve.into(), + a if a == H160::from_low_u64_be(6) => TestAccount::PrecompileAddress.into(), + _ => TestAccount::Empty.into(), + } + } +} + +impl AddressMapping for TestAccount { + fn into_account_id(h160_account: H160) -> sp_core::sr25519::Public { + match h160_account { + a if a == H160::repeat_byte(0x01) => sr25519Public::from_raw([1u8; 32]), + a if a == H160::repeat_byte(0x02) => sr25519Public::from_raw([2u8; 32]), + a if a == H160::repeat_byte(0x03) => sr25519Public::from_raw([3u8; 32]), + a if a == H160::repeat_byte(0x04) => sr25519Public::from_raw([4u8; 32]), + a if a == H160::repeat_byte(0x05) => sr25519Public::from_raw([5u8; 32]), + a if a == H160::from_low_u64_be(6) => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), + _ => sr25519Public::from_raw([0u8; 32]), + } + } +} + +impl From for H160 { + fn from(x: TestAccount) -> H160 { + match x { + TestAccount::Alex => H160::repeat_byte(0x01), + TestAccount::Bobo => H160::repeat_byte(0x02), + TestAccount::Charlie => H160::repeat_byte(0x03), + TestAccount::Dave => H160::repeat_byte(0x04), + TestAccount::Eve => H160::repeat_byte(0x05), + TestAccount::PrecompileAddress => H160::from_low_u64_be(6), + _ => Default::default(), + } + } +} + +impl From for AccountId32 { + fn from(x: TestAccount) -> Self { + match x { + TestAccount::Alex => AccountId32::from([1u8; 32]), + TestAccount::Bobo => AccountId32::from([2u8; 32]), + TestAccount::Charlie => AccountId32::from([3u8; 32]), + TestAccount::Dave => AccountId32::from([4u8; 32]), + TestAccount::Eve => AccountId32::from([5u8; 32]), + TestAccount::PrecompileAddress => AccountId32::from(PRECOMPILE_ADDRESS_BYTES), + _ => AccountId32::from([0u8; 32]), + } + } +} + +impl From for sp_core::sr25519::Public { + fn from(x: TestAccount) -> Self { + match x { + TestAccount::Alex => sr25519Public::from_raw([1u8; 32]), + TestAccount::Bobo => sr25519Public::from_raw([2u8; 32]), + TestAccount::Charlie => sr25519Public::from_raw([3u8; 32]), + TestAccount::Dave => sr25519Public::from_raw([4u8; 32]), + TestAccount::Eve => sr25519Public::from_raw([5u8; 32]), + TestAccount::PrecompileAddress => sr25519Public::from_raw(PRECOMPILE_ADDRESS_BYTES), + _ => sr25519Public::from_raw([0u8; 32]), + } + } +} + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Balances: pallet_balances, + Evm: pallet_evm, + Ethereum: pallet_ethereum, + Timestamp: pallet_timestamp, + Assets: pallet_assets, + MultiAssetDelegation: pallet_multi_asset_delegation, + } +); + +parameter_types! { + pub const SS58Prefix: u8 = 42; + pub static ExistentialDeposit: Balance = 1; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type SS58Prefix = (); + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type RuntimeCall = RuntimeCall; + type Hash = sp_core::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = (); + type DbWeight = (); + type BlockLength = (); + type BlockWeights = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_balances::Config for Runtime { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = (); + type FreezeIdentifier = (); + type MaxFreezes = (); +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = u64; + type AssetId = AssetId; + type AssetIdParameter = u128; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type WeightInfo = (); + type CallbackHandle = (); + type Extra = (); + type RemoveItemsLimit = ConstU32<5>; +} + +pub struct MockServiceManager; + +impl ServiceManager for MockServiceManager { + fn get_active_blueprints_count(_account: &AccountId) -> usize { + // we dont care + Default::default() + } + + fn get_active_services_count(_account: &AccountId) -> usize { + // we dont care + Default::default() + } + + fn can_exit(_account: &AccountId) -> bool { + // Mock logic to determine if the given account can exit + true + } + + fn get_blueprints_by_operator(_account: &AccountId) -> Vec { + // we dont care + Default::default() + } +} + +pub struct PalletEVMGasWeightMapping; + +impl EvmGasWeightMapping for PalletEVMGasWeightMapping { + fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { + pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) + } + + fn weight_to_gas(weight: Weight) -> u64 { + pallet_evm::FixedGasWeightMapping::::weight_to_gas(weight) + } +} + +pub struct PalletEVMAddressMapping; + +impl EvmAddressMapping for PalletEVMAddressMapping { + fn into_account_id(address: H160) -> AccountId { + use pallet_evm::AddressMapping; + ::AddressMapping::into_account_id(address) + } + + fn into_address(account_id: AccountId) -> H160 { + account_id.using_encoded(|b| { + let mut addr = [0u8; 20]; + addr.copy_from_slice(&b[0..20]); + H160(addr) + }) + } +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaxLocks: u32 = 50; + pub const MinOperatorBondAmount: u64 = 10_000; + pub const BondDuration: u32 = 10; + pub PID: PalletId = PalletId(*b"PotStake"); + pub SlashedAmountRecipient : AccountId = TestAccount::Alex.into(); + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxOperatorBlueprints : u32 = 50; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxWithdrawRequests: u32 = 5; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxUnstakeRequests: u32 = 5; + #[derive(PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub const MaxDelegations: u32 = 50; +} + +impl pallet_multi_asset_delegation::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type MinOperatorBondAmount = MinOperatorBondAmount; + type BondDuration = BondDuration; + type ServiceManager = MockServiceManager; + type LeaveOperatorsDelay = ConstU32<10>; + type EvmRunner = MockedEvmRunner; + type EvmAddressMapping = PalletEVMAddressMapping; + type EvmGasWeightMapping = PalletEVMGasWeightMapping; + type OperatorBondLessDelay = ConstU32<1>; + type LeaveDelegatorsDelay = ConstU32<1>; + type DelegationBondLessDelay = ConstU32<5>; + type MinDelegateAmount = ConstU64<100>; + type Fungibles = Assets; + type AssetId = AssetId; + type VaultId = AssetId; + type ForceOrigin = frame_system::EnsureRoot; + type MaxDelegatorBlueprints = MaxDelegatorBlueprints; + type MaxOperatorBlueprints = MaxOperatorBlueprints; + type MaxWithdrawRequests = MaxWithdrawRequests; + type MaxUnstakeRequests = MaxUnstakeRequests; + type MaxDelegations = MaxDelegations; + type SlashedAmountRecipient = SlashedAmountRecipient; + type PalletId = PID; + type WeightInfo = (); +} + +/// Build test externalities, prepopulated with data for testing democracy precompiles +#[derive(Default)] +pub struct ExtBuilder { + /// Endowed accounts with balances + balances: Vec<(AccountId, Balance)>, +} + +impl ExtBuilder { + /// Build the test externalities for use in tests + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self + .balances + .iter() + .chain( + [ + (TestAccount::Alex.into(), 1_000_000), + (TestAccount::Bobo.into(), 1_000_000), + (TestAccount::Charlie.into(), 1_000_000), + (MultiAssetDelegation::pallet_account(), 100), /* give pallet some ED so + * it can receive tokens */ + ] + .iter(), + ) + .cloned() + .collect(), + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| { + System::set_block_number(1); + }); + ext + } +} diff --git a/precompiles/rewards/src/mock_evm.rs b/precompiles/rewards/src/mock_evm.rs new file mode 100644 index 00000000..958342ea --- /dev/null +++ b/precompiles/rewards/src/mock_evm.rs @@ -0,0 +1,331 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use crate::{ + mock::{AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp}, + MultiAssetDelegationPrecompile, MultiAssetDelegationPrecompileCall, +}; +use fp_evm::FeeCalculator; +use frame_support::{ + parameter_types, + traits::{Currency, FindAuthor, OnUnbalanced}, + weights::Weight, + PalletId, +}; +use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; +use pallet_evm::{EnsureAddressNever, EnsureAddressOrigin, OnChargeEVMTransaction}; +use precompile_utils::precompile_set::{AddressU64, PrecompileAt, PrecompileSetBuilder}; +use sp_core::{keccak_256, ConstU32, H160, H256, U256}; +use sp_runtime::{ + traits::{DispatchInfoOf, Dispatchable}, + transaction_validity::{TransactionValidity, TransactionValidityError}, + ConsensusEngineId, +}; +use tangle_primitives::services::EvmRunner; + +pub type Precompiles = + PrecompileSetBuilder, MultiAssetDelegationPrecompile>,)>; + +pub type PCall = MultiAssetDelegationPrecompileCall; + +parameter_types! { + pub const MinimumPeriod: u64 = 6000 / 2; +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + (1.into(), Weight::zero()) + } +} + +pub struct EnsureAddressAlways; +impl EnsureAddressOrigin for EnsureAddressAlways { + type Success = (); + + fn try_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } + + fn ensure_address_origin( + _address: &H160, + _origin: OuterOrigin, + ) -> Result { + Ok(()) + } +} + +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(address_build(0).address) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub const TransactionByteFee: u64 = 1; + pub const ChainId: u64 = 42; + pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); + pub PrecompilesValue: Precompiles = Precompiles::new(); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); +} + +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(_fees_then_tips: impl Iterator) { + // whatever + } +} +pub struct FreeEVMExecution; + +impl OnChargeEVMTransaction for FreeEVMExecution { + type LiquidityInfo = (); + + fn withdraw_fee( + _who: &H160, + _fee: U256, + ) -> Result> { + Ok(()) + } + + fn correct_and_deposit_fee( + _who: &H160, + _corrected_fee: U256, + _base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + already_withdrawn + } + + fn pay_priority_fee(_tip: Self::LiquidityInfo) {} +} + +/// Type alias for negative imbalance during fees +type RuntimeNegativeImbalance = + ::AccountId>>::NegativeImbalance; + +/// See: [`pallet_evm::EVMCurrencyAdapter`] +pub struct CustomEVMCurrencyAdapter; + +impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { + type LiquidityInfo = Option; + + fn withdraw_fee( + who: &H160, + fee: U256, + ) -> Result> { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet services account free to use + if who == &pallet_multi_asset_delegation_address { + return Ok(None); + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::withdraw_fee(who, fee) + } + + fn correct_and_deposit_fee( + who: &H160, + corrected_fee: U256, + base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + let pallet_multi_asset_delegation_address = + pallet_multi_asset_delegation::Pallet::::pallet_evm_account(); + // Make pallet services account free to use + if who == &pallet_multi_asset_delegation_address { + return already_withdrawn; + } + // fallback to the default implementation + as OnChargeEVMTransaction< + Runtime, + >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) + } + + fn pay_priority_fee(tip: Self::LiquidityInfo) { + as OnChargeEVMTransaction< + Runtime, + >>::pay_priority_fee(tip) + } +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = EthereumBlockHashMapping; + type CallOrigin = EnsureAddressAlways; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = crate::mock::TestAccount; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = ChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = CustomEVMCurrencyAdapter; + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, + _ => None, + } + } +} + +pub struct MockedEvmRunner; + +impl EvmRunner for MockedEvmRunner { + type Error = pallet_evm::Error; + + fn call( + source: sp_core::H160, + target: sp_core::H160, + input: Vec, + value: sp_core::U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result> { + let max_fee_per_gas = FixedGasPrice::min_gas_price().0; + let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); + let nonce = None; + let access_list = Default::default(); + let weight_limit = None; + let proof_size_base_cost = None; + <::Runner as pallet_evm::Runner>::call( + source, + target, + input, + value, + gas_limit, + Some(max_fee_per_gas), + Some(max_priority_fee_per_gas), + nonce, + access_list, + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + ::config(), + ) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) + } +} + +pub struct AccountInfo { + pub address: H160, +} + +pub fn address_build(seed: u8) -> AccountInfo { + let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); + let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); + let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; + let address = H160::from(H256::from(keccak_256(public_key))); + + AccountInfo { address } +} diff --git a/precompiles/rewards/src/tests.rs b/precompiles/rewards/src/tests.rs new file mode 100644 index 00000000..a2fdac39 --- /dev/null +++ b/precompiles/rewards/src/tests.rs @@ -0,0 +1,499 @@ +use crate::{mock::*, mock_evm::*, U256}; +use frame_support::{assert_ok, traits::Currency}; +use pallet_multi_asset_delegation::{types::OperatorStatus, CurrentRound, Delegators, Operators}; +use precompile_utils::testing::*; +use sp_core::H160; +use tangle_primitives::services::Asset; + +// Helper function for creating and minting tokens +pub fn create_and_mint_tokens( + asset_id: u128, + recipient: ::AccountId, + amount: Balance, +) { + assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient, false, 1)); + assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient), asset_id, recipient, amount)); +} + +#[test] +fn test_selector_less_than_four_bytes_reverts() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test(Alice, Precompile1, vec![1u8, 2, 3]) + .execute_reverts(|output| output == b"Tried to read selector out of bounds"); + }); +} + +#[test] +fn test_unimplemented_selector_reverts() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test(Alice, Precompile1, vec![1u8, 2, 3, 4]) + .execute_reverts(|output| output == b"Unknown selector"); + }); +} + +#[test] +fn test_join_operators() { + ExtBuilder::default().build().execute_with(|| { + let account = sp_core::sr25519::Public::from(TestAccount::Alex); + let initial_balance = Balances::free_balance(account); + assert!(Operators::::get(account).is_none()); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::join_operators { bond_amount: U256::from(10_000) }, + ) + .execute_returns(()); + + assert!(Operators::::get(account).is_some()); + let expected_balance = initial_balance - 10_000; + assert_eq!(Balances::free_balance(account), expected_balance); + }); +} + +#[test] +fn test_join_operators_insufficient_balance() { + ExtBuilder::default().build().execute_with(|| { + let account = sp_core::sr25519::Public::from(TestAccount::Eve); + Balances::make_free_balance_be(&account, 500); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Eve, + H160::from_low_u64_be(1), + PCall::join_operators { bond_amount: U256::from(10_000) }, + ) + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); + + assert_eq!(Balances::free_balance(account), 500); + }); +} + +#[test] +fn test_delegate_assets_invalid_operator() { + ExtBuilder::default().build().execute_with(|| { + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + + Balances::make_free_balance_be(&delegator_account, 500); + create_and_mint_tokens(1, delegator_account, 500); + + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: sp_core::sr25519::Public::from(TestAccount::Eve).into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [2, 0, 0, 0], message: Some(\"NotAnOperator\") })"); + + assert_eq!(Balances::free_balance(delegator_account), 500); + }); +} + +#[test] +fn test_delegate_assets() { + ExtBuilder::default().build().execute_with(|| { + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + + Balances::make_free_balance_be(&operator_account, 20_000); + Balances::make_free_balance_be(&delegator_account, 500); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator_account), + Asset::Custom(1), + 200, + Some(TestAccount::Alex.into()) + )); + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change when delegating + }); +} + +#[test] +fn test_delegate_assets_insufficient_balance() { + ExtBuilder::default().build().execute_with(|| { + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Eve); + + Balances::make_free_balance_be(&operator_account, 20_000); + Balances::make_free_balance_be(&delegator_account, 500); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Eve, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(300), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [15, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); + + assert_eq!(Balances::free_balance(delegator_account), 500); + }); +} + +#[test] +fn test_schedule_withdraw() { + ExtBuilder::default().build().execute_with(|| { + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + + Balances::make_free_balance_be(&operator_account, 20_000); + Balances::make_free_balance_be(&delegator_account, 500); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert!(Delegators::::get(delegator_account).is_some()); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); + assert!(!metadata.withdraw_requests.is_empty()); + + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change + }); +} + +#[test] +fn test_execute_withdraw() { + ExtBuilder::default().build().execute_with(|| { + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + + Balances::make_free_balance_be(&operator_account, 20_000); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, + ) + .execute_returns(()); + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert!(Delegators::::get(delegator_account).is_some()); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); + assert!(!metadata.withdraw_requests.is_empty()); + + >::put(3); + + PrecompilesValue::get() + .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); + assert!(metadata.withdraw_requests.is_empty()); + + assert_eq!(Assets::balance(1, delegator_account), 500 - 100); // deposited 200, withdrew 100 + }); +} + +#[test] +fn test_execute_withdraw_before_due() { + ExtBuilder::default().build().execute_with(|| { + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + + Balances::make_free_balance_be(&delegator_account, 10_000); + Balances::make_free_balance_be(&operator_account, 20_000); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, + ) + .execute_returns(()); + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert!(Delegators::::get(delegator_account).is_some()); + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // delegate should not change balance + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); + assert!(!metadata.withdraw_requests.is_empty()); + + PrecompilesValue::get() + .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) + .execute_returns(()); // should not fail + + // not expired so should not change balance + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); + }); +} + +#[test] +fn test_cancel_withdraw() { + ExtBuilder::default().build().execute_with(|| { + let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + + Balances::make_free_balance_be(&operator_account, 20_000); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + create_and_mint_tokens(1, delegator_account, 500); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::deposit { + asset_id: U256::from(1), + amount: U256::from(200), + token_address: Default::default(), + }, + ) + .execute_returns(()); + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::delegate { + operator: operator_account.into(), + asset_id: U256::from(1), + amount: U256::from(100), + blueprint_selection: Default::default(), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + assert!(Delegators::::get(delegator_account).is_some()); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::schedule_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); + assert!(!metadata.withdraw_requests.is_empty()); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alex, + H160::from_low_u64_be(1), + PCall::cancel_withdraw { + asset_id: U256::from(1), + amount: U256::from(100), + token_address: Default::default(), + }, + ) + .execute_returns(()); + + let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); + assert!(metadata.deposits.contains_key(&Asset::Custom(1))); + assert!(metadata.withdraw_requests.is_empty()); + + assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change + }); +} + +#[test] +fn test_operator_go_offline_and_online() { + ExtBuilder::default().build().execute_with(|| { + let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); + + Balances::make_free_balance_be(&operator_account, 20_000); + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator_account), + 10_000 + )); + + PrecompilesValue::get() + .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_offline {}) + .execute_returns(()); + + assert!( + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Inactive + ); + + PrecompilesValue::get() + .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_online {}) + .execute_returns(()); + + assert!( + MultiAssetDelegation::operator_info(operator_account).unwrap().status + == OperatorStatus::Active + ); + + assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); + }); +} diff --git a/primitives/src/traits/mod.rs b/primitives/src/traits/mod.rs index 04e6a277..0fb9c6b9 100644 --- a/primitives/src/traits/mod.rs +++ b/primitives/src/traits/mod.rs @@ -1,11 +1,11 @@ pub mod assets; pub mod data_provider; pub mod multi_asset_delegation; -pub mod services; pub mod rewards; +pub mod services; pub use assets::*; pub use data_provider::*; pub use multi_asset_delegation::*; +pub use rewards::*; pub use services::*; -pub use rewards::*; \ No newline at end of file diff --git a/primitives/src/traits/rewards.rs b/primitives/src/traits/rewards.rs index e69de29b..e7fe182c 100644 --- a/primitives/src/traits/rewards.rs +++ b/primitives/src/traits/rewards.rs @@ -0,0 +1,119 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . + +use crate::services::Asset; +use frame_support::traits::Currency; +use frame_system::pallet_prelude::BlockNumberFor; +use sp_runtime::traits::Zero; + +/// Trait for managing rewards in the Tangle network. +/// This trait allows other pallets to record and query rewards. +pub trait RewardsManager { + /// Record a delegation deposit reward. + /// This is used by the multi-asset-delegation pallet to record rewards from delegations. + /// + /// Parameters: + /// - `account_id`: The account receiving the reward + /// - `asset`: The asset being delegated + /// - `amount`: The amount of the reward + /// - `lock_multiplier`: The multiplier for the lock period (e.g., 1 for 1 month, 3 for 3 months) + fn record_delegation_reward( + account_id: &AccountId, + asset: Asset, + amount: Balance, + lock_multiplier: u32, + ) -> Result<(), &'static str>; + + /// Record a service payment reward. + /// This is used by the services pallet to record rewards from service payments. + /// + /// Parameters: + /// - `account_id`: The account receiving the reward + /// - `asset`: The asset used for payment + /// - `amount`: The amount of the reward + fn record_service_reward( + account_id: &AccountId, + asset: Asset, + amount: Balance, + ) -> Result<(), &'static str>; + + /// Query the total rewards for an account and asset. + /// Returns a tuple of (delegation_rewards, service_rewards). + /// + /// Parameters: + /// - `account_id`: The account to query + /// - `asset`: The asset to query + fn query_rewards( + account_id: &AccountId, + asset: Asset, + ) -> Result<(Balance, Balance), &'static str>; + + /// Query only the delegation rewards for an account and asset. + fn query_delegation_rewards( + account_id: &AccountId, + asset: Asset, + ) -> Result; + + /// Query only the service rewards for an account and asset. + fn query_service_rewards( + account_id: &AccountId, + asset: Asset, + ) -> Result; +} + +impl + RewardsManager for () +where + Balance: Zero, +{ + fn record_delegation_reward( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + _lock_multiplier: u32, + ) -> Result<(), &'static str> { + Ok(()) + } + + fn record_service_reward( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + ) -> Result<(), &'static str> { + Ok(()) + } + + fn query_rewards( + _account_id: &AccountId, + _asset: Asset, + ) -> Result<(Balance, Balance), &'static str> { + Ok((Balance::zero(), Balance::zero())) + } + + fn query_delegation_rewards( + _account_id: &AccountId, + _asset: Asset, + ) -> Result { + Ok(Balance::zero()) + } + + fn query_service_rewards( + _account_id: &AccountId, + _asset: Asset, + ) -> Result { + Ok(Balance::zero()) + } +} From 5e332e9b6b5c35953e224bc71386d18de43d3b49 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:07:03 +0530 Subject: [PATCH 44/63] more cleanup and tests --- .../src/functions/delegate.rs | 30 ++++ pallets/multi-asset-delegation/src/lib.rs | 5 + .../src/tests/delegate.rs | 27 ++- .../src/tests/operator.rs | 2 + .../src/tests/session_manager.rs | 9 +- pallets/multi-asset-delegation/src/types.rs | 3 + .../src/types/delegator.rs | 29 +++- pallets/rewards/src/functions.rs | 106 +++--------- pallets/rewards/src/impls.rs | 128 +++++--------- pallets/rewards/src/lib.rs | 70 ++------ pallets/rewards/src/traits.rs | 156 ------------------ pallets/rewards/src/types.rs | 76 +-------- primitives/src/types.rs | 1 + primitives/src/types/rewards.rs | 104 ++++++++++++ 14 files changed, 281 insertions(+), 465 deletions(-) delete mode 100644 pallets/rewards/src/traits.rs create mode 100644 primitives/src/types/rewards.rs diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 779c6fe0..5170288b 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -20,10 +20,13 @@ use frame_support::{ pallet_prelude::DispatchResult, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; +use frame_system::pallet_prelude::BlockNumberFor; +use tangle_primitives::types::rewards::LockMultiplier; use sp_runtime::{ traits::{CheckedSub, Zero}, DispatchError, Percent, }; +use frame_support::BoundedVec; use sp_std::vec::Vec; use tangle_primitives::{ services::{Asset, EvmAddressMapping}, @@ -51,6 +54,7 @@ impl Pallet { asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, + lock_multiplier: Option, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; @@ -74,12 +78,28 @@ impl Pallet { { delegation.amount += amount; } else { + let now = frame_system::Pallet::::block_number(); + let now_as_u32 : u32 = now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved + let locks = if let Some(lock_multiplier) = lock_multiplier { + let expiry_block : BlockNumberFor = lock_multiplier.expiry_block_number::(now_as_u32).try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; + let bounded_vec = BoundedVec::try_from(vec![LockInfo { + amount, + lock_multiplier, + expiry_block + }]) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + Some(bounded_vec) + } else { + None + }; + // Create the new delegation let new_delegation = BondInfoDelegator { operator: operator.clone(), amount, asset_id, blueprint_selection, + locks }; // Create a mutable copy of delegations @@ -166,6 +186,15 @@ impl Pallet { let delegation = &mut metadata.delegations[delegation_index]; ensure!(delegation.amount >= amount, Error::::InsufficientBalance); + // ensure the locks are not violated + let now = frame_system::Pallet::::block_number(); + if let Some(locks) = &delegation.locks { + // lets filter only active locks + let active_locks = locks.iter().filter(|lock| lock.expiry_block > now).collect::>(); + let total_locks = active_locks.iter().fold(0_u32.into(), |acc, lock| acc + lock.amount); + ensure!(delegation.amount >= total_locks, Error::::LockViolation); + } + delegation.amount -= amount; // Create the unstake request @@ -340,6 +369,7 @@ impl Pallet { amount: unstake_request.amount, asset_id: unstake_request.asset_id, blueprint_selection: unstake_request.blueprint_selection, + locks: Default::default(), // should be able to unstake only if locks didnt exist }) .map_err(|_| Error::::MaxDelegationsExceeded)?; } diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 0618411c..1720880f 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -80,6 +80,7 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; + use tangle_primitives::types::rewards::LockMultiplier; use frame_support::{ pallet_prelude::*, traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, @@ -430,6 +431,8 @@ pub mod pallet { EVMAbiEncode, /// EVM decode error EVMAbiDecode, + /// Cannot unstake with locks + LockViolation } /// Hooks for the pallet. @@ -607,6 +610,7 @@ pub mod pallet { asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, + lock_multiplier: Option ) -> DispatchResult { let who = ensure_signed(origin)?; Self::process_delegate( @@ -615,6 +619,7 @@ pub mod pallet { asset_id, amount, blueprint_selection, + lock_multiplier )?; Self::deposit_event(Event::Delegated { who, operator, asset_id, amount }); Ok(()) diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 92a7316d..82b4507a 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -49,7 +49,8 @@ fn delegate_should_work() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); // Assert @@ -100,7 +101,8 @@ fn schedule_delegator_unstake_should_work() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -153,7 +155,8 @@ fn execute_delegator_unstake_should_work() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), @@ -205,7 +208,8 @@ fn cancel_delegator_unstake_should_work() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -279,7 +283,8 @@ fn cancel_delegator_unstake_should_update_already_existing() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -358,7 +363,8 @@ fn delegate_should_fail_if_not_enough_balance() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None ), Error::::InsufficientBalance ); @@ -429,7 +435,8 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); assert_noop!( @@ -487,7 +494,8 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { operator.clone(), asset_id.clone(), amount, - Default::default() + Default::default(), + None )); // Assert first delegation @@ -514,7 +522,8 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { operator.clone(), asset_id.clone(), additional_amount, - Default::default() + Default::default(), + None )); // Assert updated delegation diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index cbe18c5f..79bb2291 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -652,6 +652,7 @@ fn slash_operator_success() { asset_id, delegator_stake, Fixed(vec![blueprint_id].try_into().unwrap()), + None, )); // Slash 50% of stakes @@ -748,6 +749,7 @@ fn slash_delegator_fixed_blueprint_not_selected() { Asset::Custom(1), 5_000, Fixed(vec![2].try_into().unwrap()), + None )); // Try to slash with unselected blueprint diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 7174d5f5..c79d7a80 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -50,7 +50,8 @@ fn handle_round_change_should_work() { operator.clone(), asset_id, amount, - Default::default() + Default::default(), + None )); assert_ok!(Pallet::::handle_round_change()); @@ -106,7 +107,8 @@ fn handle_round_change_with_unstake_should_work() { operator1.clone(), asset_id, amount1, - Default::default() + Default::default(), + None )); assert_ok!(MultiAssetDelegation::deposit( @@ -120,7 +122,8 @@ fn handle_round_change_with_unstake_should_work() { operator2.clone(), asset_id, amount2, - Default::default() + Default::default(), + None )); // Delegator1 schedules unstake diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index a1b0cb4d..6b4b7029 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -21,6 +21,7 @@ use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::RoundIndex; +use frame_system::pallet_prelude::BlockNumberFor; pub mod delegator; pub mod operator; @@ -56,4 +57,6 @@ pub type DelegatorMetadataOf = DelegatorMetadata< ::MaxDelegations, ::MaxUnstakeRequests, ::MaxDelegatorBlueprints, + BlockNumberFor, + ::MaxDelegations, >; diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 774b8f46..04dba2cb 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -17,6 +17,7 @@ use super::*; use frame_support::{pallet_prelude::Get, BoundedVec}; use tangle_primitives::{services::Asset, BlueprintId}; +use tangle_primitives::types::rewards::LockMultiplier; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -79,6 +80,8 @@ pub struct DelegatorMetadata< MaxDelegations: Get, MaxUnstakeRequests: Get, MaxBlueprints: Get, + BlockNumber, + MaxLocks: Get, > { /// A map of deposited assets and their respective amounts. pub deposits: BTreeMap, Balance>, @@ -86,7 +89,7 @@ pub struct DelegatorMetadata< pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. pub delegations: - BoundedVec, MaxDelegations>, + BoundedVec, MaxDelegations>, /// A vector of requests to reduce the bonded amount. pub delegator_unstake_requests: BoundedVec, MaxUnstakeRequests>, @@ -102,6 +105,8 @@ impl< MaxDelegations: Get, MaxUnstakeRequests: Get, MaxBlueprints: Get, + BlockNumber, + MaxLocks: Get, > Default for DelegatorMetadata< AccountId, @@ -111,6 +116,8 @@ impl< MaxDelegations, MaxUnstakeRequests, MaxBlueprints, + BlockNumber, + MaxLocks, > { fn default() -> Self { @@ -132,6 +139,8 @@ impl< MaxDelegations: Get, MaxUnstakeRequests: Get, MaxBlueprints: Get, + BlockNumber, + MaxLocks: Get, > DelegatorMetadata< AccountId, @@ -141,6 +150,8 @@ impl< MaxDelegations, MaxUnstakeRequests, MaxBlueprints, + BlockNumber, + MaxLocks, > { /// Returns a reference to the vector of withdraw requests. @@ -151,7 +162,7 @@ impl< /// Returns a reference to the list of delegations. pub fn get_delegations( &self, - ) -> &Vec> { + ) -> &Vec> { &self.delegations } @@ -187,7 +198,7 @@ impl< pub fn calculate_delegation_by_operator( &self, operator: AccountId, - ) -> Vec<&BondInfoDelegator> + ) -> Vec<&BondInfoDelegator> where AccountId: Eq + PartialEq, { @@ -206,7 +217,7 @@ pub struct Deposit { /// Represents a stake between a delegator and an operator. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct BondInfoDelegator> +pub struct BondInfoDelegator, BlockNumber, MaxLocks: Get> { /// The account ID of the operator. pub operator: AccountId, @@ -216,4 +227,14 @@ pub struct BondInfoDelegator, /// The blueprint selection mode for this delegator. pub blueprint_selection: DelegatorBlueprintSelection, + /// The locks associated with this delegation. + pub locks: Option, MaxLocks>>, +} + +/// Struct to store the lock info +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] +pub struct LockInfo { + pub amount: Balance, + pub lock_multiplier: LockMultiplier, + pub expiry_block: BlockNumber, } diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 9134b2b6..2ddb13d1 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -31,85 +31,29 @@ pub fn calculate_user_score( asset: Asset, rewards: &UserRewardsOf, ) -> u128 { - let base_score = match asset { - Asset::Native => { - // For TNT, include both restaking and boost rewards - let restaking_score = rewards - .restaking_rewards - .saturating_add(rewards.service_rewards) - .saturated_into::(); - - // Apply lock multiplier to boost rewards - let boost_score = rewards - .boost_rewards - .amount - .saturated_into::() - .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); - - restaking_score.saturating_add(boost_score) - }, - _ => { - // For non-TNT assets, only consider service rewards - rewards.service_rewards.saturated_into::() - }, - }; - - base_score -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{BoostInfo, LockMultiplier, UserRewards}; - use sp_runtime::traits::Zero; - - // Helper function to create UserRewards with specific values - fn create_user_rewards( - restaking: u128, - boost_amount: u128, - boost_multiplier: LockMultiplier, - service: u128, - ) -> UserRewardsOf { - UserRewards { - restaking_rewards: restaking.saturated_into(), - boost_rewards: BoostInfo { - amount: boost_amount.saturated_into(), - multiplier: boost_multiplier, - expiry: Zero::zero(), - }, - service_rewards: service.saturated_into(), - } - } - - #[test] - fn test_calculate_user_score_tnt() { - // Test TNT asset with different lock multipliers - let rewards = create_user_rewards::( - 1000, // restaking rewards - 500, // boost amount - LockMultiplier::ThreeMonths, // 3x multiplier - 200, // service rewards - ); - - let score = calculate_user_score::(Asset::Native, &rewards); - - // Expected: 1000 (restaking) + 200 (service) + (500 * 3) (boosted) = 2700 - assert_eq!(score, 2700); - } - - #[test] - fn test_calculate_user_score_other_asset() { - // Test non-TNT asset - let rewards = create_user_rewards::( - 1000, // restaking rewards - 500, // boost amount - LockMultiplier::SixMonths, // 6x multiplier (should not affect non-TNT) - 200, // service rewards - ); - - let score = calculate_user_score::(Asset::Evm(1), &rewards); - - // Expected: only service rewards are counted - assert_eq!(score, 200); - } + // let base_score = match asset { + // Asset::Native => { + // // For TNT, include both restaking and boost rewards + // let restaking_score = rewards + // .restaking_rewards + // .saturating_add(rewards.service_rewards) + // .saturated_into::(); + + // // Apply lock multiplier to boost rewards + // let boost_score = rewards + // .boost_rewards + // .amount + // .saturated_into::() + // .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); + + // restaking_score.saturating_add(boost_score) + // }, + // _ => { + // // For non-TNT assets, only consider service rewards + // rewards.service_rewards.saturated_into::() + // }, + // }; + + // base_score + todo!(); } diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index 9960198e..5c6ae16c 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -14,97 +14,51 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate::{Config, Pallet, UserRewards, UserRewardsOf, BoostInfo, LockMultiplier}; +use crate::BalanceOf; +use crate::{Config, Pallet, UserRewards, UserRewardsOf}; use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; -use sp_runtime::traits::{Zero, Saturating}; -use tangle_primitives::{ - services::Asset, - traits::rewards::RewardsManager, -}; +use sp_runtime::traits::{Saturating, Zero}; +use tangle_primitives::{services::Asset, traits::rewards::RewardsManager}; -impl RewardsManager> for Pallet { - fn record_delegation_reward( - account_id: &T::AccountId, - asset: Asset, - amount: T::Balance, - lock_multiplier: u32, - ) -> Result<(), &'static str> { - // Check if asset is whitelisted - if !Self::is_asset_whitelisted(asset) { - return Err("Asset not whitelisted"); - } +impl RewardsManager, BlockNumberFor> + for Pallet +{ + fn record_delegation_reward( + account_id: &T::AccountId, + asset: Asset, + amount: BalanceOf, + lock_multiplier: u32, + ) -> Result<(), &'static str> { + Ok(()) + } - // Get current rewards or create new if none exist - let mut rewards = Self::user_rewards(account_id, asset); + fn record_service_reward( + account_id: &T::AccountId, + asset: Asset, + amount: BalanceOf, + ) -> Result<(), &'static str> { + Ok(()) + } - // Convert lock_multiplier to LockMultiplier enum - let multiplier = match lock_multiplier { - 1 => LockMultiplier::OneMonth, - 2 => LockMultiplier::TwoMonths, - 3 => LockMultiplier::ThreeMonths, - 6 => LockMultiplier::SixMonths, - _ => return Err("Invalid lock multiplier"), - }; + fn query_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result<(BalanceOf, BalanceOf), &'static str> { + todo!() + } - // Update boost rewards - rewards.boost_rewards = BoostInfo { - amount: rewards.boost_rewards.amount.saturating_add(amount), - multiplier, - expiry: frame_system::Pallet::::block_number().saturating_add( - BlockNumberFor::::from(30u32 * lock_multiplier as u32) - ), - }; + fn query_delegation_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result, &'static str> { + todo!() + } - // Store updated rewards - >::insert(account_id, asset, rewards); - - Ok(()) - } - - fn record_service_reward( - account_id: &T::AccountId, - asset: Asset, - amount: T::Balance, - ) -> Result<(), &'static str> { - // Check if asset is whitelisted - if !Self::is_asset_whitelisted(asset) { - return Err("Asset not whitelisted"); - } - - // Get current rewards or create new if none exist - let mut rewards = Self::user_rewards(account_id, asset); - - // Update service rewards - rewards.service_rewards = rewards.service_rewards.saturating_add(amount); - - // Store updated rewards - >::insert(account_id, asset, rewards); - - Ok(()) - } - - fn query_rewards( - account_id: &T::AccountId, - asset: Asset, - ) -> Result<(T::Balance, T::Balance), &'static str> { - let rewards = Self::user_rewards(account_id, asset); - Ok((rewards.boost_rewards.amount, rewards.service_rewards)) - } - - fn query_delegation_rewards( - account_id: &T::AccountId, - asset: Asset, - ) -> Result { - let rewards = Self::user_rewards(account_id, asset); - Ok(rewards.boost_rewards.amount) - } - - fn query_service_rewards( - account_id: &T::AccountId, - asset: Asset, - ) -> Result { - let rewards = Self::user_rewards(account_id, asset); - Ok(rewards.service_rewards) - } -} \ No newline at end of file + fn query_service_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result, &'static str> { + todo!() + } +} diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index ddb4bc83..e6dd8667 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -44,6 +44,7 @@ pub mod types; pub use types::*; pub mod functions; pub use functions::*; +pub mod impls; /// The pallet's account ID. #[frame_support::pallet] @@ -74,6 +75,9 @@ pub mod pallet { /// The pallet's account ID. type PalletId: Get; + /// The maximum amount of rewards that can be claimed per asset per user. + type MaxUniqueServiceRewards: Get + MaxEncodedLen + TypeInfo; + /// The origin that can manage reward assets type ForceOrigin: EnsureOrigin; } @@ -95,6 +99,16 @@ pub mod pallet { ValueQuery, >; + #[pallet::storage] + #[pallet::getter(fn asset_rewards)] + pub type AssetRewards = StorageMap< + _, + Blake2_128Concat, + Asset, + u128, + ValueQuery, + >; + /// Stores the whitelisted assets that can be used for rewards #[pallet::storage] #[pallet::getter(fn allowed_reward_assets)] @@ -157,62 +171,6 @@ pub mod pallet { reward_type: RewardType, ) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - - let mut amount = BalanceOf::::zero(); - - // TODO : Implement helper function to get this value out - // UserRewards::::mutate(who.clone(), asset, |rewards| { - // amount = match reward_type { - // RewardType::Restaking => std::mem::take(&mut rewards.restaking_rewards), - // RewardType::Boost => std::mem::take(&mut rewards.boost_rewards), - // RewardType::Service => std::mem::take(&mut rewards.service_rewards), - // }; - // }); - - ensure!(!amount.is_zero(), Error::::NoRewardsAvailable); - - let pallet_account = Self::account_id(); - ensure!( - T::Currency::free_balance(&pallet_account) >= amount, - Error::::InsufficientRewardsBalance - ); - - T::Currency::transfer( - &pallet_account, - &who, - amount, - frame_support::traits::ExistenceRequirement::KeepAlive, - )?; - - Self::deposit_event(Event::RewardsClaimed { account: who, asset, amount, reward_type }); - - Ok(()) - } - - /// Add an asset to the whitelist of allowed reward assets - #[pallet::weight(10_000)] - pub fn whitelist_asset(origin: OriginFor, asset: Asset) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; - - ensure!(!AllowedRewardAssets::::get(&asset), Error::::AssetAlreadyWhitelisted); - - AllowedRewardAssets::::insert(asset, true); - - Self::deposit_event(Event::AssetWhitelisted { asset }); - Ok(()) - } - - /// Remove an asset from the whitelist - #[pallet::weight(10_000)] - pub fn remove_asset(origin: OriginFor, asset: Asset) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; - - ensure!(AllowedRewardAssets::::get(&asset), Error::::AssetNotWhitelisted); - - AllowedRewardAssets::::remove(asset); - - Self::deposit_event(Event::AssetRemoved { asset }); Ok(()) } } diff --git a/pallets/rewards/src/traits.rs b/pallets/rewards/src/traits.rs deleted file mode 100644 index d497dc0d..00000000 --- a/pallets/rewards/src/traits.rs +++ /dev/null @@ -1,156 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::types::{BalanceOf, LockMultiplier, OperatorStatus}; -use sp_runtime::{traits::Zero, Percent}; -use sp_std::prelude::*; -use tangle_primitives::{ - services::Asset, traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex, -}; - -/// Trait for handling reward operations -pub trait RewardsHandler { - /// Record rewards for a specific user and asset - fn record_rewards( - beneficiary: AccountId, - asset: Asset, - amount: Balance, - reward_type: RewardType, - boost_multiplier: Option, - boost_expiry: Option<::BlockNumber>, - ) -> DispatchResult; - - /// Record a deposit for a specific account and asset with a lock multiplier - fn record_deposit( - account_id: AccountId, - asset_id: AssetId, - amount: Balance, - lock_multiplier: LockMultiplier, - ) -> DispatchResult; - - /// Query the deposit for a specific account and asset - fn query_deposit(account_id: AccountId, asset_id: AssetId) -> Balance; - - /// Record a service payment for a specific account and asset - fn record_service_payment( - account_id: AccountId, - asset_id: AssetId, - amount: Balance, - ) -> DispatchResult; - - /// Check if an asset is whitelisted for rewards - fn is_asset_whitelisted(asset: Asset) -> bool; -} - -impl RewardsHandler> for crate::Pallet { - fn record_rewards( - beneficiary: T::AccountId, - asset: Asset, - amount: BalanceOf, - reward_type: RewardType, - boost_multiplier: Option, - boost_expiry: Option, - ) -> DispatchResult { - // Check if asset is whitelisted - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - - // Update rewards storage - UserRewards::::mutate(beneficiary.clone(), asset, |rewards| { - match reward_type { - RewardType::Restaking => { - rewards.restaking_rewards = rewards.restaking_rewards.saturating_add(amount); - }, - RewardType::Boost => { - if let (Some(multiplier), Some(expiry)) = (boost_multiplier, boost_expiry) { - rewards.boost_rewards = BoostInfo { - amount: rewards.boost_rewards.amount.saturating_add(amount), - multiplier, - expiry, - }; - } - }, - RewardType::Service => { - rewards.service_rewards = rewards.service_rewards.saturating_add(amount); - }, - } - }); - - // Emit event - Self::deposit_event(Event::RewardsAdded { - account: beneficiary, - asset, - amount, - reward_type, - boost_multiplier, - boost_expiry, - }); - - Ok(()) - } - - fn record_deposit( - account_id: T::AccountId, - asset_id: T::AssetId, - amount: BalanceOf, - lock_multiplier: LockMultiplier, - ) -> DispatchResult { - let asset = Asset::new(asset_id); - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - - UserRewards::::mutate(account_id.clone(), asset, |rewards| { - rewards.restaking_rewards = rewards.restaking_rewards.saturating_add(amount); - }); - - Self::deposit_event(Event::DepositRecorded { - account: account_id, - asset, - amount, - lock_multiplier, - }); - - Ok(()) - } - - fn query_deposit(account_id: T::AccountId, asset_id: T::AssetId) -> BalanceOf { - let asset = Asset::new(asset_id); - UserRewards::::get(account_id, asset).restaking_rewards - } - - fn record_service_payment( - account_id: T::AccountId, - asset_id: T::AssetId, - amount: BalanceOf, - ) -> DispatchResult { - let asset = Asset::new(asset_id); - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - - UserRewards::::mutate(account_id.clone(), asset, |rewards| { - rewards.service_rewards = rewards.service_rewards.saturating_add(amount); - }); - - Self::deposit_event(Event::ServicePaymentRecorded { - account: account_id, - asset, - amount, - }); - - Ok(()) - } - - fn is_asset_whitelisted(asset: Asset) -> bool { - AllowedRewardAssets::::get(&asset) - } -} diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index f3adb918..b6300e06 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -21,77 +21,15 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; +use tangle_primitives::types::rewards::UserRewards; use tangle_primitives::{services::Asset, types::RoundIndex}; -/// Represents different types of rewards a user can earn -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] -pub struct UserRewards { - /// Rewards earned from restaking (in TNT) - pub restaking_rewards: Balance, - /// Boost rewards information - pub boost_rewards: BoostInfo, - /// Service rewards in their respective assets - pub service_rewards: Balance, -} - -pub type UserRewardsOf = UserRewards, BlockNumberFor>; - -/// Information about a user's boost rewards -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] -pub struct BoostInfo { - /// Amount of boost rewards - pub amount: Balance, - /// Multiplier for the boost (e.g. OneMonth = 1x, TwoMonths = 2x) - pub multiplier: LockMultiplier, - /// Block number when the boost expires - pub expiry: BlockNumber, -} - -impl Default for BoostInfo { - fn default() -> Self { - Self { - amount: Balance::default(), - multiplier: LockMultiplier::OneMonth, - expiry: BlockNumber::default(), - } - } -} - -impl Default for UserRewards { - fn default() -> Self { - Self { - restaking_rewards: Balance::default(), - boost_rewards: BoostInfo::default(), - service_rewards: Balance::default(), - } - } -} +pub type UserRewardsOf = UserRewards< + BalanceOf, + BlockNumberFor, + ::AssetId, + ::MaxUniqueServiceRewards, +>; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - -/// Lock multiplier for rewards, representing months of lock period -#[derive(Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] -pub enum LockMultiplier { - /// One month lock period (1x multiplier) - OneMonth = 1, - /// Two months lock period (2x multiplier) - TwoMonths = 2, - /// Three months lock period (3x multiplier) - ThreeMonths = 3, - /// Six months lock period (6x multiplier) - SixMonths = 6, -} - -impl Default for LockMultiplier { - fn default() -> Self { - Self::OneMonth - } -} - -impl LockMultiplier { - /// Get the multiplier value - pub fn value(&self) -> u32 { - *self as u32 - } -} diff --git a/primitives/src/types.rs b/primitives/src/types.rs index 50cf21ac..a78d88ea 100644 --- a/primitives/src/types.rs +++ b/primitives/src/types.rs @@ -15,6 +15,7 @@ // use super::*; pub mod ordered_set; +pub mod rewards; use frame_support::pallet_prelude::*; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; diff --git a/primitives/src/types/rewards.rs b/primitives/src/types/rewards.rs new file mode 100644 index 00000000..e2154d2e --- /dev/null +++ b/primitives/src/types/rewards.rs @@ -0,0 +1,104 @@ +use super::*; +use crate::services::Asset; +use frame_system::pallet_prelude::BlockNumberFor; +use frame_system::Config; +use sp_runtime::Saturating; + +/// Represents different types of rewards a user can earn +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct UserRewards> { + /// Rewards earned from restaking (in TNT) + pub restaking_rewards: Balance, + /// Boost rewards information + pub boost_rewards: BoostInfo, + /// Service rewards in their respective assets + pub service_rewards: BoundedVec, MaxServiceRewards>, +} + +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct UserRestakeUpdate { + pub asset: Asset, + pub amount: Balance, + pub multiplier: LockMultiplier, +} + +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct ServiceRewards { + asset_id: Asset, + amount: Balance, +} + +/// Information about a user's boost rewards +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct BoostInfo { + /// Amount of boost rewards + pub amount: Balance, + /// Multiplier for the boost (e.g. OneMonth = 1x, TwoMonths = 2x) + pub multiplier: LockMultiplier, + /// Block number when the boost expires + pub expiry: BlockNumber, +} + +impl Default for BoostInfo { + fn default() -> Self { + Self { + amount: Balance::default(), + multiplier: LockMultiplier::OneMonth, + expiry: BlockNumber::default(), + } + } +} + +impl> Default + for UserRewards +{ + fn default() -> Self { + Self { + restaking_rewards: Balance::default(), + boost_rewards: BoostInfo::default(), + service_rewards: BoundedVec::default(), + } + } +} + +/// Lock multiplier for rewards, representing months of lock period +#[derive(Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub enum LockMultiplier { + /// One month lock period (1x multiplier) + OneMonth = 1, + /// Two months lock period (2x multiplier) + TwoMonths = 2, + /// Three months lock period (3x multiplier) + ThreeMonths = 3, + /// Six months lock period (6x multiplier) + SixMonths = 6, +} + +impl Default for LockMultiplier { + fn default() -> Self { + Self::OneMonth + } +} + +impl LockMultiplier { + /// Get the multiplier value + pub fn value(&self) -> u32 { + *self as u32 + } + + /// Get the block number for each multiplier + pub fn get_blocks(&self) -> u32 { + // assuming block time of 6 seconds + match self { + LockMultiplier::OneMonth => 432000, + LockMultiplier::TwoMonths => 864000, + LockMultiplier::ThreeMonths => 1296000, + LockMultiplier::SixMonths => 2592000 + } + } + + /// Calculate the expiry block number based on the current block number and multiplier + pub fn expiry_block_number(&self, current_block: u32) -> u32 { + current_block.saturating_add(self.get_blocks()) + } +} From c7c3ddf0a49b7270690f630169f8ec6a0b3f1680 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:02:32 +0530 Subject: [PATCH 45/63] cleanup clippy --- pallets/multi-asset-delegation/fuzzer/call.rs | 12 +- .../src/functions/delegate.rs | 54 ++++++-- pallets/multi-asset-delegation/src/lib.rs | 8 +- .../src/tests/delegate.rs | 116 ++++++++++++++++++ pallets/multi-asset-delegation/src/types.rs | 6 +- .../src/types/delegator.rs | 23 ++-- .../src/types/operator.rs | 55 +++++++-- pallets/rewards/src/lib.rs | 9 +- .../multi-asset-delegation/fuzzer/call.rs | 1 + precompiles/multi-asset-delegation/src/lib.rs | 14 ++- primitives/src/types/rewards.rs | 30 ++--- 11 files changed, 273 insertions(+), 55 deletions(-) diff --git a/pallets/multi-asset-delegation/fuzzer/call.rs b/pallets/multi-asset-delegation/fuzzer/call.rs index ecc81fc0..8e5ef8f6 100644 --- a/pallets/multi-asset-delegation/fuzzer/call.rs +++ b/pallets/multi-asset-delegation/fuzzer/call.rs @@ -247,7 +247,17 @@ fn random_calls( }; [ join_operators_call(&mut rng, operator_origin.clone(), &operator), - (mad::Call::delegate { operator, asset_id, amount, blueprint_selection }, origin), + ( + mad::Call::delegate { + operator, + asset_id, + amount, + blueprint_selection, + lock_multiplier: None, + }, + origin, + ), + // TODO : Add fuzzing with lock_multiplier ] .to_vec() }, diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 5170288b..0d508ff9 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,19 +15,20 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; +use frame_support::BoundedVec; use frame_support::{ ensure, pallet_prelude::DispatchResult, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; use frame_system::pallet_prelude::BlockNumberFor; -use tangle_primitives::types::rewards::LockMultiplier; use sp_runtime::{ traits::{CheckedSub, Zero}, DispatchError, Percent, }; -use frame_support::BoundedVec; +use sp_std::vec; use sp_std::vec::Vec; +use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{ services::{Asset, EvmAddressMapping}, BlueprintId, @@ -79,13 +80,17 @@ impl Pallet { delegation.amount += amount; } else { let now = frame_system::Pallet::::block_number(); - let now_as_u32 : u32 = now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved + let now_as_u32: u32 = + now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved let locks = if let Some(lock_multiplier) = lock_multiplier { - let expiry_block : BlockNumberFor = lock_multiplier.expiry_block_number::(now_as_u32).try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; + let expiry_block: BlockNumberFor = lock_multiplier + .expiry_block_number::(now_as_u32) + .try_into() + .map_err(|_| Error::::MaxDelegationsExceeded)?; let bounded_vec = BoundedVec::try_from(vec![LockInfo { amount, lock_multiplier, - expiry_block + expiry_block, }]) .map_err(|_| Error::::MaxDelegationsExceeded)?; Some(bounded_vec) @@ -99,7 +104,7 @@ impl Pallet { amount, asset_id, blueprint_selection, - locks + locks, }; // Create a mutable copy of delegations @@ -122,7 +127,25 @@ impl Pallet { ); // Create and push the new delegation bond - let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; + let now = frame_system::Pallet::::block_number(); + let now_as_u32: u32 = + now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved + let locks = if let Some(lock_multiplier) = lock_multiplier { + let expiry_block: BlockNumberFor = lock_multiplier + .expiry_block_number::(now_as_u32) + .try_into() + .map_err(|_| Error::::MaxDelegationsExceeded)?; + let bounded_vec = BoundedVec::try_from(vec![LockInfo { + amount, + lock_multiplier, + expiry_block, + }]) + .map_err(|_| Error::::MaxDelegationsExceeded)?; + Some(bounded_vec) + } else { + None + }; + let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id, locks }; let mut delegations = operator_metadata.delegations.clone(); @@ -190,9 +213,13 @@ impl Pallet { let now = frame_system::Pallet::::block_number(); if let Some(locks) = &delegation.locks { // lets filter only active locks - let active_locks = locks.iter().filter(|lock| lock.expiry_block > now).collect::>(); - let total_locks = active_locks.iter().fold(0_u32.into(), |acc, lock| acc + lock.amount); - ensure!(delegation.amount >= total_locks, Error::::LockViolation); + let active_locks = + locks.iter().filter(|lock| lock.expiry_block > now).collect::>(); + let total_locks = + active_locks.iter().fold(0_u32.into(), |acc, lock| acc + lock.amount); + if total_locks != Zero::zero() { + ensure!(amount < total_locks, Error::::LockViolation); + } } delegation.amount -= amount; @@ -341,7 +368,12 @@ impl Pallet { delegation.amount += amount; } else { delegations - .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) + .try_push(DelegatorBond { + delegator: who.clone(), + amount, + asset_id, + locks: Default::default(), + }) .map_err(|_| Error::::MaxDelegationsExceeded)?; // Increase the delegation count only when a new delegation is added diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 1720880f..62b52c9c 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -80,7 +80,6 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; - use tangle_primitives::types::rewards::LockMultiplier; use frame_support::{ pallet_prelude::*, traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, @@ -91,6 +90,7 @@ pub mod pallet { use sp_core::H160; use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; + use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex}; /// Configure the pallet by specifying the parameters and types on which it depends. @@ -432,7 +432,7 @@ pub mod pallet { /// EVM decode error EVMAbiDecode, /// Cannot unstake with locks - LockViolation + LockViolation, } /// Hooks for the pallet. @@ -610,7 +610,7 @@ pub mod pallet { asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, - lock_multiplier: Option + lock_multiplier: Option, ) -> DispatchResult { let who = ensure_signed(origin)?; Self::process_delegate( @@ -619,7 +619,7 @@ pub mod pallet { asset_id, amount, blueprint_selection, - lock_multiplier + lock_multiplier, )?; Self::deposit_event(Event::Delegated { who, operator, asset_id, amount }); Ok(()) diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 82b4507a..19fb849b 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -19,6 +19,7 @@ use crate::{CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; use sp_keyring::AccountKeyring::{Alice, Bob}; use tangle_primitives::services::Asset; +use tangle_primitives::types::rewards::LockMultiplier; #[test] fn delegate_should_work() { @@ -546,3 +547,118 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_operator_delegation.asset_id, asset_id); }); } + +#[test] +fn delegate_should_work_with_lock_multiplier() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + create_and_mint_tokens(VDOT, who.clone(), amount); + + // Deposit first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default(), + Some(LockMultiplier::default()) + )); + + // Assert + let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); + assert!(metadata.deposits.get(&asset_id).is_none()); + assert_eq!(metadata.delegations.len(), 1); + let delegation = &metadata.delegations[0]; + assert_eq!(delegation.operator, operator.clone()); + assert_eq!(delegation.amount, amount); + assert_eq!(delegation.asset_id, asset_id); + + // check the lock info + assert_eq!(delegation.locks.clone().unwrap().first().unwrap().amount, amount); + assert_eq!( + delegation.locks.clone().unwrap().first().unwrap().lock_multiplier, + LockMultiplier::default() + ); + assert_eq!(delegation.locks.clone().unwrap().first().unwrap().expiry_block, 432001); + + // Check the operator metadata + let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); + assert_eq!(operator_metadata.delegation_count, 1); + assert_eq!(operator_metadata.delegations.len(), 1); + let operator_delegation = &operator_metadata.delegations[0]; + assert_eq!(operator_delegation.delegator, who.clone()); + assert_eq!(operator_delegation.amount, amount); + assert_eq!(operator_delegation.asset_id, asset_id); + }); +} + +#[test] +fn schedule_delegator_unstake_should_work_with_lock_multiplier() { + new_test_ext().execute_with(|| { + // Arrange + let who: AccountId = Bob.into(); + let operator: AccountId = Alice.into(); + let asset_id = Asset::Custom(VDOT); + let amount = 100; + + create_and_mint_tokens(VDOT, who.clone(), amount); + + assert_ok!(MultiAssetDelegation::join_operators( + RuntimeOrigin::signed(operator.clone()), + 10_000 + )); + + // Deposit and delegate first + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(who.clone()), + asset_id.clone(), + amount, + None + )); + assert_ok!(MultiAssetDelegation::delegate( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + Default::default(), + Some(LockMultiplier::default()) + )); + + // Should not work with locks + assert_noop!( + MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + ), + Error::::LockViolation + ); + + // time travel to after lock expiry + System::set_block_number(432002); + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( + RuntimeOrigin::signed(who.clone()), + operator.clone(), + asset_id.clone(), + amount, + )); + }); +} diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index 6b4b7029..24ee507c 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -16,12 +16,12 @@ use crate::Config; use frame_support::traits::Currency; +use frame_system::pallet_prelude::BlockNumberFor; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::RoundIndex; -use frame_system::pallet_prelude::BlockNumberFor; pub mod delegator; pub mod operator; @@ -40,6 +40,8 @@ pub type OperatorMetadataOf = OperatorMetadata< ::AssetId, ::MaxDelegations, ::MaxOperatorBlueprints, + BlockNumberFor, + ::MaxDelegations, >; pub type OperatorSnapshotOf = OperatorSnapshot< @@ -47,6 +49,8 @@ pub type OperatorSnapshotOf = OperatorSnapshot< BalanceOf, ::AssetId, ::MaxDelegations, + BlockNumberFor, + ::MaxDelegations, >; pub type DelegatorMetadataOf = DelegatorMetadata< diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 04dba2cb..d72fcc7b 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -16,8 +16,8 @@ use super::*; use frame_support::{pallet_prelude::Get, BoundedVec}; -use tangle_primitives::{services::Asset, BlueprintId}; use tangle_primitives::types::rewards::LockMultiplier; +use tangle_primitives::{services::Asset, BlueprintId}; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -88,8 +88,10 @@ pub struct DelegatorMetadata< /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. - pub delegations: - BoundedVec, MaxDelegations>, + pub delegations: BoundedVec< + BondInfoDelegator, + MaxDelegations, + >, /// A vector of requests to reduce the bonded amount. pub delegator_unstake_requests: BoundedVec, MaxUnstakeRequests>, @@ -162,7 +164,8 @@ impl< /// Returns a reference to the list of delegations. pub fn get_delegations( &self, - ) -> &Vec> { + ) -> &Vec> + { &self.delegations } @@ -217,8 +220,14 @@ pub struct Deposit { /// Represents a stake between a delegator and an operator. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct BondInfoDelegator, BlockNumber, MaxLocks: Get> -{ +pub struct BondInfoDelegator< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxBlueprints: Get, + BlockNumber, + MaxLocks: Get, +> { /// The account ID of the operator. pub operator: AccountId, /// The amount bonded. @@ -231,7 +240,7 @@ pub struct BondInfoDelegator, MaxLocks>>, } -/// Struct to store the lock info +/// Struct to store the lock info #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] pub struct LockInfo { pub amount: Balance, diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index e0e7ca27..35466a3a 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -20,18 +20,33 @@ use tangle_primitives::services::Asset; /// A snapshot of the operator state at the start of the round. #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct OperatorSnapshot> -{ +pub struct OperatorSnapshot< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxDelegations: Get, + BlockNumber, + MaxLocks: Get, +> { /// The total value locked by the operator. pub stake: Balance, /// The rewardable delegations. This list is a subset of total delegators, where certain /// delegators are adjusted based on their scheduled status. - pub delegations: BoundedVec, MaxDelegations>, + pub delegations: BoundedVec< + DelegatorBond, + MaxDelegations, + >, } -impl> - OperatorSnapshot +impl< + AccountId, + Balance, + AssetId: Encode + Decode, + MaxDelegations: Get, + BlockNumber, + MaxLocks: Get, + > OperatorSnapshot where AssetId: PartialEq + Ord + Copy, Balance: Default + core::ops::AddAssign + Copy, @@ -89,6 +104,8 @@ pub struct OperatorMetadata< AssetId: Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, + BlockNumber, + MaxLocks: Get, > { /// The operator's self-stake amount. pub stake: Balance, @@ -98,7 +115,10 @@ pub struct OperatorMetadata< /// any given time. pub request: Option>, /// A list of all current delegations. - pub delegations: BoundedVec, MaxDelegations>, + pub delegations: BoundedVec< + DelegatorBond, + MaxDelegations, + >, /// The current status of the operator. pub status: OperatorStatus, /// The set of blueprint IDs this operator works with. @@ -111,7 +131,18 @@ impl< AssetId: Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, - > Default for OperatorMetadata + BlockNumber, + MaxLocks: Get, + > Default + for OperatorMetadata< + AccountId, + Balance, + AssetId, + MaxDelegations, + MaxBlueprints, + BlockNumber, + MaxLocks, + > where Balance: Default, { @@ -129,11 +160,19 @@ where /// Represents a stake for an operator #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond { +pub struct DelegatorBond< + AccountId, + Balance, + AssetId: Encode + Decode, + BlockNumber, + MaxLocks: Get, +> { /// The account ID of the delegator. pub delegator: AccountId, /// The amount bonded. pub amount: Balance, /// The ID of the bonded asset. pub asset_id: Asset, + /// The locks associated with this delegation. + pub locks: Option, MaxLocks>>, } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index e6dd8667..da6c7689 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -101,13 +101,8 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn asset_rewards)] - pub type AssetRewards = StorageMap< - _, - Blake2_128Concat, - Asset, - u128, - ValueQuery, - >; + pub type AssetRewards = + StorageMap<_, Blake2_128Concat, Asset, u128, ValueQuery>; /// Stores the whitelisted assets that can be used for rewards #[pallet::storage] diff --git a/precompiles/multi-asset-delegation/fuzzer/call.rs b/precompiles/multi-asset-delegation/fuzzer/call.rs index 34fe1cb3..b5116c4e 100644 --- a/precompiles/multi-asset-delegation/fuzzer/call.rs +++ b/precompiles/multi-asset-delegation/fuzzer/call.rs @@ -224,6 +224,7 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator, + lock_multiplier: u8, ) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -331,6 +333,15 @@ where (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; + let lock_multiplier = match lock_multiplier { + 0 => None, + 1 => Some(LockMultiplier::OneMonth), + 2 => Some(LockMultiplier::TwoMonths), + 3 => Some(LockMultiplier::ThreeMonths), + 4 => Some(LockMultiplier::SixMonths), + _ => return Err(RevertReason::custom("Invalid lock multiplier").into()), + }; + RuntimeHelper::::try_dispatch( handle, Some(who).into(), @@ -345,6 +356,7 @@ where RevertReason::custom("Too many blueprint ids for fixed selection") })?, ), + lock_multiplier, }, )?; diff --git a/primitives/src/types/rewards.rs b/primitives/src/types/rewards.rs index e2154d2e..3ed16f1d 100644 --- a/primitives/src/types/rewards.rs +++ b/primitives/src/types/rewards.rs @@ -19,7 +19,7 @@ pub struct UserRewards { pub asset: Asset, pub amount: Balance, - pub multiplier: LockMultiplier, + pub multiplier: LockMultiplier, } #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] @@ -86,19 +86,19 @@ impl LockMultiplier { *self as u32 } - /// Get the block number for each multiplier - pub fn get_blocks(&self) -> u32 { - // assuming block time of 6 seconds - match self { - LockMultiplier::OneMonth => 432000, - LockMultiplier::TwoMonths => 864000, - LockMultiplier::ThreeMonths => 1296000, - LockMultiplier::SixMonths => 2592000 - } - } + /// Get the block number for each multiplier + pub fn get_blocks(&self) -> u32 { + // assuming block time of 6 seconds + match self { + LockMultiplier::OneMonth => 432000, + LockMultiplier::TwoMonths => 864000, + LockMultiplier::ThreeMonths => 1296000, + LockMultiplier::SixMonths => 2592000, + } + } - /// Calculate the expiry block number based on the current block number and multiplier - pub fn expiry_block_number(&self, current_block: u32) -> u32 { - current_block.saturating_add(self.get_blocks()) - } + /// Calculate the expiry block number based on the current block number and multiplier + pub fn expiry_block_number(&self, current_block: u32) -> u32 { + current_block.saturating_add(self.get_blocks()) + } } From 4293c9084802eb36091f64984c5f0c778f12550e Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:25:30 +0530 Subject: [PATCH 46/63] add back apy calc --- pallets/rewards/fuzzer/call.rs | 671 ++++++++----------------------- pallets/rewards/src/functions.rs | 170 ++++++-- pallets/rewards/src/impls.rs | 1 + pallets/rewards/src/lib.rs | 140 ++++++- precompiles/rewards/src/lib.rs | 589 +++++++++------------------ precompiles/rewards/src/tests.rs | 667 +++++++++--------------------- 6 files changed, 811 insertions(+), 1427 deletions(-) diff --git a/pallets/rewards/fuzzer/call.rs b/pallets/rewards/fuzzer/call.rs index ecc81fc0..1e530ff3 100644 --- a/pallets/rewards/fuzzer/call.rs +++ b/pallets/rewards/fuzzer/call.rs @@ -15,549 +15,212 @@ // along with Tangle. If not, see . //! # Running -//! Running this fuzzer can be done with `cargo hfuzz run mad-fuzzer`. `honggfuzz` CLI +//! Running this fuzzer can be done with `cargo hfuzz run rewards-fuzzer`. `honggfuzz` CLI //! options can be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. //! //! # Debugging a panic //! Once a panic is found, it can be debugged with -//! `cargo hfuzz run-debug mad-fuzzer hfuzz_workspace/mad-fuzzer/*.fuzz`. +//! `cargo hfuzz run-debug rewards-fuzzer hfuzz_workspace/rewards-fuzzer/*.fuzz`. use frame_support::{ - dispatch::PostDispatchInfo, - traits::{Currency, Get, GetCallName, Hooks, UnfilteredDispatchable}, + dispatch::PostDispatchInfo, + traits::{Currency, Get, GetCallName, Hooks, UnfilteredDispatchable}, }; use frame_system::ensure_signed_or_root; use honggfuzz::fuzz; -use pallet_multi_asset_delegation::{mock::*, pallet as mad, types::*}; +use pallet_rewards::{mock::*, pallet as rewards, types::*, RewardType}; use rand::{seq::SliceRandom, Rng}; use sp_runtime::{ - traits::{Scale, Zero}, - Percent, + traits::{Scale, Zero}, + Percent, }; +use tangle_primitives::{services::Asset, types::rewards::LockMultiplier}; const MAX_ED_MULTIPLE: Balance = 10_000; const MIN_ED_MULTIPLE: Balance = 10; fn random_account_id(rng: &mut R) -> AccountId { - rng.gen::<[u8; 32]>().into() + rng.gen::<[u8; 32]>().into() } /// Grab random accounts. fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, AccountId) { - let acc = random_account_id(rng); - (RuntimeOrigin::signed(acc.clone()), acc) + let acc = random_account_id(rng); + (RuntimeOrigin::signed(acc.clone()), acc) } fn random_ed_multiple(rng: &mut R) -> Balance { - let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); - ExistentialDeposit::get() * multiple + let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); + ExistentialDeposit::get() * multiple } fn random_asset(rng: &mut R) -> Asset { - let asset_id = rng.gen_range(1..u128::MAX); - let is_evm = rng.gen_bool(0.5); - if is_evm { - let evm_address = rng.gen::<[u8; 20]>().into(); - Asset::Erc20(evm_address) - } else { - Asset::Custom(asset_id) - } + let asset_id = rng.gen_range(1..u128::MAX); + let is_evm = rng.gen_bool(0.5); + if is_evm { + let evm_address = rng.gen::<[u8; 20]>().into(); + Asset::Erc20(evm_address) + } else { + Asset::Custom(asset_id) + } } -fn fund_account(rng: &mut R, account: &AccountId) { - let target_amount = random_ed_multiple(rng); - if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(account)) { - let _ = Balances::deposit_creating(account, top_up); - } - assert!(Balances::free_balance(account) >= target_amount); +fn random_lock_multiplier(rng: &mut R) -> LockMultiplier { + let multipliers = [ + LockMultiplier::OneMonth, + LockMultiplier::TwoMonths, + LockMultiplier::ThreeMonths, + LockMultiplier::SixMonths, + ]; + *multipliers.choose(rng).unwrap() } -/// Join operators call. -fn join_operators_call( - rng: &mut R, - origin: RuntimeOrigin, - who: &AccountId, -) -> (mad::Call, RuntimeOrigin) { - let minimum_bond = <::MinOperatorBondAmount as Get>::get(); - let multiplier = rng.gen_range(1..50u128); - let _ = Balances::deposit_creating(who, minimum_bond.mul(multiplier)); - let bond_amount = minimum_bond.mul(multiplier); - (mad::Call::join_operators { bond_amount }, origin) +fn random_reward_type(rng: &mut R) -> RewardType { + let reward_types = [ + RewardType::Boost, + RewardType::Service, + RewardType::Restaking, + ]; + *reward_types.choose(rng).unwrap() } -fn random_calls( - mut rng: &mut R, -) -> impl IntoIterator, RuntimeOrigin)> { - let op = as GetCallName>::get_call_names() - .choose(rng) - .cloned() - .unwrap(); - - match op { - "join_operators" => { - // join_operators - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [join_operators_call(&mut rng, origin, &who)].to_vec() - }, - "schedule_leave_operators" => { - // Schedule leave operators - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::schedule_leave_operators {}, origin), - ] - .to_vec() - }, - "cancel_leave_operators" => { - // Cancel leave operators - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::cancel_leave_operators {}, origin), - ] - .to_vec() - }, - "execute_leave_operators" => { - // Execute leave operators - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::execute_leave_operators {}, origin), - ] - .to_vec() - }, - "operator_bond_more" => { - // Operator bond more - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let additional_bond = random_ed_multiple(&mut rng); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::operator_bond_more { additional_bond }, origin), - ] - .to_vec() - }, - "schedule_operator_unstake" => { - // Schedule operator unstake - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let unstake_amount = random_ed_multiple(&mut rng); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::schedule_operator_unstake { unstake_amount }, origin), - ] - .to_vec() - }, - "execute_operator_unstake" => { - // Execute operator unstake - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::execute_operator_unstake {}, origin), - ] - .to_vec() - }, - "cancel_operator_unstake" => { - // Cancel operator unstake - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::cancel_operator_unstake {}, origin), - ] - .to_vec() - }, - "go_offline" => { - // Go offline - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [ - join_operators_call(&mut rng, origin.clone(), &who), - (mad::Call::go_offline {}, origin), - ] - .to_vec() - }, - "go_online" => { - // Go online - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [join_operators_call(&mut rng, origin.clone(), &who), (mad::Call::go_online {}, origin)] - .to_vec() - }, - "deposit" => { - // Deposit - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - let evm_address = - if rng.gen_bool(0.5) { Some(rng.gen::<[u8; 20]>().into()) } else { None }; - [(mad::Call::deposit { asset_id, amount, evm_address }, origin)].to_vec() - }, - "schedule_withdraw" => { - // Schedule withdraw - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - [(mad::Call::schedule_withdraw { asset_id, amount }, origin)].to_vec() - }, - "execute_withdraw" => { - // Execute withdraw - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let evm_address = - if rng.gen_bool(0.5) { Some(rng.gen::<[u8; 20]>().into()) } else { None }; - [(mad::Call::execute_withdraw { evm_address }, origin)].to_vec() - }, - "cancel_withdraw" => { - // Cancel withdraw - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - [(mad::Call::cancel_withdraw { asset_id, amount }, origin)].to_vec() - }, - "delegate" => { - // Delegate - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let (operator_origin, operator) = random_signed_origin(&mut rng); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - let blueprint_selection = { - let all = rng.gen_bool(0.5); - if all { - DelegatorBlueprintSelection::All - } else { - let count = rng.gen_range(1..MaxDelegatorBlueprints::get()); - DelegatorBlueprintSelection::Fixed( - (0..count) - .map(|_| rng.gen::()) - .collect::>() - .try_into() - .unwrap(), - ) - } - }; - [ - join_operators_call(&mut rng, operator_origin.clone(), &operator), - (mad::Call::delegate { operator, asset_id, amount, blueprint_selection }, origin), - ] - .to_vec() - }, - "schedule_delegator_unstake" => { - // Schedule delegator unstakes - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let (operator_origin, operator) = random_signed_origin(&mut rng); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - [ - join_operators_call(&mut rng, operator_origin.clone(), &operator), - (mad::Call::schedule_delegator_unstake { operator, asset_id, amount }, origin), - ] - .to_vec() - }, - "execute_delegator_unstake" => { - // Execute delegator unstake - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [(mad::Call::execute_delegator_unstake {}, origin)].to_vec() - }, - "cancel_delegator_unstake" => { - // Cancel delegator unstake - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - let (operator_origin, operator) = random_signed_origin(&mut rng); - let asset_id = random_asset(&mut rng); - let amount = random_ed_multiple(&mut rng); - [ - join_operators_call(&mut rng, operator_origin.clone(), &operator), - (mad::Call::cancel_delegator_unstake { operator, asset_id, amount }, origin), - ] - .to_vec() - }, - "set_incentive_apy_and_cap" => { - // Set incentive APY and cap - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let vault_id = rng.gen(); - let apy = Percent::from_percent(rng.gen_range(0..100)); - let cap = rng.gen_range(0..Balance::MAX); - [(mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap }, origin)].to_vec() - }, - "whitelist_blueprint_for_rewards" => { - // Whitelist blueprint for rewards - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::whitelist_blueprint_for_rewards { blueprint_id }, origin)].to_vec() - }, - "manage_asset_in_vault" => { - // Manage asset in vault - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let asset_id = random_asset(&mut rng); - let vault_id = rng.gen(); - let action = if rng.gen() { AssetAction::Add } else { AssetAction::Remove }; - [(mad::Call::manage_asset_in_vault { asset_id, vault_id, action }, origin)].to_vec() - }, - "add_blueprint_id" => { - // Add blueprint ID - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::add_blueprint_id { blueprint_id }, origin)].to_vec() - }, - "remove_blueprint_id" => { - // Remove blueprint ID - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::remove_blueprint_id { blueprint_id }, origin)].to_vec() - }, - _ => { - unimplemented!("unknown call name: {}", op) - }, - } +fn fund_account(rng: &mut R, account: &AccountId) { + let target_amount = random_ed_multiple(rng); + if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(account)) { + let _ = Balances::deposit_creating(account, top_up); + } + assert!(Balances::free_balance(account) >= target_amount); } -fn main() { - sp_tracing::try_init_simple(); - let mut ext = sp_io::TestExternalities::new_empty(); - let mut block_number = 1; - loop { - fuzz!(|seed: [u8; 32]| { - use ::rand::{rngs::SmallRng, SeedableRng}; - let mut rng = SmallRng::from_seed(seed); - - ext.execute_with(|| { - System::set_block_number(block_number); - Session::on_initialize(block_number); - Staking::on_initialize(block_number); +/// Initialize an asset with random APY and capacity +fn init_asset_call( + rng: &mut R, + origin: RuntimeOrigin, +) -> (rewards::Call, RuntimeOrigin) { + let asset = random_asset(rng); + let apy = rng.gen_range(1..10000); // 0.01% to 100% + let capacity = random_ed_multiple(rng); + + (rewards::Call::whitelist_asset { asset }, origin.clone()); + ( + rewards::Call::set_asset_apy { + asset: asset.clone(), + apy_basis_points: apy, + }, + origin.clone(), + ); + ( + rewards::Call::set_asset_capacity { + asset, + capacity, + }, + origin, + ) +} - for (call, origin) in random_calls(&mut rng) { - let outcome = call.clone().dispatch_bypass_filter(origin.clone()); - sp_tracing::trace!(?call, ?origin, ?outcome, "fuzzed call"); +/// Claim rewards call +fn claim_rewards_call( + rng: &mut R, + origin: RuntimeOrigin, +) -> (rewards::Call, RuntimeOrigin) { + let asset = random_asset(rng); + let reward_type = random_reward_type(rng); + ( + rewards::Call::claim_rewards { + asset, + reward_type, + }, + origin, + ) +} - // execute sanity checks at a fixed interval, possibly on every block. - if let Ok(out) = outcome { - sp_tracing::info!("running sanity checks.."); - do_sanity_checks(call.clone(), origin.clone(), out); - } - } +fn random_calls( + mut rng: &mut R, +) -> impl IntoIterator, RuntimeOrigin)> { + let op = as GetCallName>::get_call_names() + .choose(rng) + .cloned() + .unwrap(); + + match op { + "whitelist_asset" | "set_asset_apy" | "set_asset_capacity" => { + let origin = RuntimeOrigin::root(); + [init_asset_call(&mut rng, origin)].to_vec() + } + "claim_rewards" => { + let (origin, who) = random_signed_origin(&mut rng); + fund_account(&mut rng, &who); + [claim_rewards_call(&mut rng, origin)].to_vec() + } + _ => vec![], + } +} - System::reset_events(); - block_number += 1; - }); - }) - } +fn main() { + loop { + fuzz!(|data: &[u8]| { + let mut rng = rand::rngs::SmallRng::from_slice(data).unwrap(); + let calls = random_calls(&mut rng); + + new_test_ext().execute_with(|| { + // Run to block 1 to initialize + System::set_block_number(1); + Rewards::on_initialize(1); + + for (call, origin) in calls { + let _ = call.dispatch_bypass_filter(origin.clone()); + System::assert_last_event(Event::Rewards(rewards::Event::RewardsClaimed { + account: who, + asset, + amount, + reward_type, + })); + } + }); + }); + } } /// Perform sanity checks on the state after a call is executed successfully. -#[allow(unused)] -fn do_sanity_checks(call: mad::Call, origin: RuntimeOrigin, outcome: PostDispatchInfo) { - let caller = match ensure_signed_or_root(origin).unwrap() { - Some(signer) => signer, - None => - /*Root */ - { - [0u8; 32].into() - }, - }; - match call { - mad::Call::join_operators { bond_amount } => { - assert!(mad::Operators::::contains_key(&caller), "operator not found"); - assert_eq!( - MultiAssetDelegation::operator_info(&caller).unwrap_or_default().stake, - bond_amount - ); - assert!( - Balances::reserved_balance(&caller).ge(&bond_amount), - "bond amount not reserved" - ); - }, - mad::Call::schedule_leave_operators {} => { - assert!(mad::Operators::::contains_key(&caller), "operator not found"); - let current_round = mad::CurrentRound::::get(); - let leaving_time = - <::LeaveOperatorsDelay as Get>::get() + current_round; - assert_eq!( - mad::Operators::::get(&caller).unwrap_or_default().status, - OperatorStatus::Leaving(leaving_time) - ); - }, - mad::Call::cancel_leave_operators {} => { - assert_eq!( - mad::Operators::::get(&caller).unwrap_or_default().status, - OperatorStatus::Active - ); - }, - mad::Call::execute_leave_operators {} => { - assert!(!mad::Operators::::contains_key(&caller), "operator not removed"); - assert!(Balances::reserved_balance(&caller).is_zero(), "bond amount not unreserved"); - }, - mad::Call::operator_bond_more { additional_bond } => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - assert!(info.stake.ge(&additional_bond), "bond amount not increased"); - assert!( - Balances::reserved_balance(&caller).ge(&additional_bond), - "bond amount not reserved" - ); - }, - mad::Call::schedule_operator_unstake { unstake_amount } => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - let current_round = MultiAssetDelegation::current_round(); - let unstake_request = - OperatorBondLessRequest { amount: unstake_amount, request_time: current_round }; - assert_eq!(info.request, Some(unstake_request), "unstake request not set"); - }, - mad::Call::execute_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - // reserved balance should be reduced and equal to the stake - assert!( - Balances::reserved_balance(&caller).eq(&info.stake), - "reserved balance not equal to stake" - ); - }, - mad::Call::cancel_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - }, - mad::Call::go_offline {} => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Inactive, "status not set to inactive"); - }, - mad::Call::go_online {} => { - let info = MultiAssetDelegation::operator_info(&caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Active, "status not set to active"); - }, - mad::Call::deposit { asset_id, amount, .. } => { - match asset_id { - Asset::Custom(id) => { - let pallet_balance = - Assets::balance(id, MultiAssetDelegation::pallet_account()); - assert!(pallet_balance.ge(&amount), "pallet balance not enough"); - }, - Asset::Erc20(token) => { - let pallet_balance = MultiAssetDelegation::query_erc20_balance_of( - token, - MultiAssetDelegation::pallet_evm_account(), - ) - .unwrap_or_default() - .0; - assert!(pallet_balance.ge(&amount.into()), "pallet balance not enough"); - }, - }; - - assert_eq!( - MultiAssetDelegation::delegators(&caller) - .unwrap_or_default() - .calculate_delegation_by_asset(asset_id), - amount - ); - }, - mad::Call::schedule_withdraw { asset_id, amount } => { - let round = MultiAssetDelegation::current_round(); - assert!( - MultiAssetDelegation::delegators(&caller) - .unwrap_or_default() - .get_withdraw_requests() - .contains(&WithdrawRequest { asset_id, amount, requested_round: round }), - "withdraw request not found" - ); - }, - mad::Call::execute_withdraw { .. } => { - assert!( - MultiAssetDelegation::delegators(&caller) - .unwrap_or_default() - .get_withdraw_requests() - .is_empty(), - "withdraw requests not removed" - ); - }, - mad::Call::cancel_withdraw { asset_id, amount } => { - let round = MultiAssetDelegation::current_round(); - assert!( - !MultiAssetDelegation::delegators(&caller) - .unwrap_or_default() - .get_withdraw_requests() - .contains(&WithdrawRequest { asset_id, amount, requested_round: round }), - "withdraw request not removed" - ); - }, - mad::Call::delegate { operator, asset_id, amount, .. } => { - let delegator = MultiAssetDelegation::delegators(&caller).unwrap_or_default(); - let operator_info = MultiAssetDelegation::operator_info(&operator).unwrap_or_default(); - assert!( - delegator - .calculate_delegation_by_operator(operator) - .iter() - .find_map(|x| { - if x.asset_id == asset_id { - Some(x.amount) - } else { - None - } - }) - .ge(&Some(amount)), - "delegation amount not set" - ); - assert!( - operator_info - .delegations - .iter() - .find_map(|x| { - if x.delegator == caller && x.asset_id == asset_id { - Some(x.amount) - } else { - None - } - }) - .ge(&Some(amount)), - "delegator not added to operator" - ); - }, - mad::Call::schedule_delegator_unstake { operator, asset_id, amount } => {}, - mad::Call::execute_delegator_unstake {} => {}, - mad::Call::cancel_delegator_unstake { operator, asset_id, amount } => {}, - mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap } => {}, - mad::Call::whitelist_blueprint_for_rewards { blueprint_id } => {}, - mad::Call::manage_asset_in_vault { vault_id, asset_id, action } => {}, - mad::Call::add_blueprint_id { blueprint_id } => {}, - mad::Call::remove_blueprint_id { blueprint_id } => {}, - other => unimplemented!("sanity checks for call: {other:?} not implemented"), - } +fn do_sanity_checks( + call: rewards::Call, + origin: RuntimeOrigin, + outcome: PostDispatchInfo, +) { + match call { + rewards::Call::claim_rewards { asset, reward_type } => { + // Verify the asset is whitelisted + assert!(Rewards::is_asset_whitelisted(asset)); + + // Get the account that made the call + let who = ensure_signed_or_root(origin).unwrap(); + + // Get user rewards + let rewards = Rewards::user_rewards(&who, asset); + + // Verify rewards were properly reset after claiming + match reward_type { + RewardType::Boost => { + // For boost rewards, verify expiry was updated + assert_eq!( + rewards.boost_rewards.expiry, + System::block_number(), + ); + } + RewardType::Service => { + // Verify service rewards were reset + assert!(rewards.service_rewards.is_zero()); + } + RewardType::Restaking => { + // Verify restaking rewards were reset + assert!(rewards.restaking_rewards.is_zero()); + } + } + + // Verify total score is updated correctly + let user_score = rewards::functions::calculate_user_score::(asset, &rewards); + assert!(Rewards::total_asset_score(asset) >= user_score); + } + _ => {} + } } diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 2ddb13d1..9b6b8bae 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -14,46 +14,142 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate::{Config, UserRewardsOf}; +use crate::{BalanceOf, Config, Pallet, UserRewardsOf}; use frame_support::traits::Currency; -use sp_runtime::{traits::Zero, Saturating}; -use tangle_primitives::services::Asset; - -/// Calculate a user's score based on their staked assets and lock multipliers. -/// Score is calculated as follows: -/// - For TNT assets: -/// - Base score = staked amount -/// - Multiplier based on lock period (1x to 6x) -/// - For other assets: -/// - Base score = staked amount -/// - No additional multiplier +use sp_runtime::{ + traits::{Saturating, Zero}, + Percent, +}; +use tangle_primitives::{services::Asset, types::rewards::LockMultiplier}; + +/// Calculate the score for a user's rewards based on their lock period and amount pub fn calculate_user_score( asset: Asset, rewards: &UserRewardsOf, ) -> u128 { - // let base_score = match asset { - // Asset::Native => { - // // For TNT, include both restaking and boost rewards - // let restaking_score = rewards - // .restaking_rewards - // .saturating_add(rewards.service_rewards) - // .saturated_into::(); - - // // Apply lock multiplier to boost rewards - // let boost_score = rewards - // .boost_rewards - // .amount - // .saturated_into::() - // .saturating_mul(rewards.boost_rewards.multiplier.value() as u128); - - // restaking_score.saturating_add(boost_score) - // }, - // _ => { - // // For non-TNT assets, only consider service rewards - // rewards.service_rewards.saturated_into::() - // }, - // }; - - // base_score - todo!(); + // Get the lock multiplier in months (1, 2, 3, or 6) + let lock_period = match rewards.boost_rewards.multiplier { + LockMultiplier::OneMonth => 1, + LockMultiplier::TwoMonths => 2, + LockMultiplier::ThreeMonths => 3, + LockMultiplier::SixMonths => 6, + }; + + // Convert amount to u128 for calculation + let amount: u128 = rewards.boost_rewards.amount.saturated_into(); + + // Score = amount * lock_period + amount.saturating_mul(lock_period as u128) +} + +/// Calculate the APY distribution for a given asset and score +pub fn calculate_apy_distribution( + asset: Asset, + user_score: u128, +) -> Percent { + let total_score = >::get(asset); + if total_score.is_zero() { + return Percent::zero(); + } + + let total_deposited = >::get(asset); + let capacity = >::get(asset); + let apy_basis_points = >::get(asset); + + // Convert capacity and total_deposited to u128 for calculation + let capacity: u128 = capacity.saturated_into(); + let total_deposited: u128 = total_deposited.saturated_into(); + + if capacity.is_zero() { + return Percent::zero(); + } + + // Calculate pro-rata score distribution + let score_ratio = Percent::from_rational(user_score, total_score); + + // Calculate capacity utilization + let capacity_ratio = Percent::from_rational(total_deposited, capacity); + + // Calculate final APY + // APY = base_apy * (score/total_score) * (total_deposited/capacity) + let base_apy = Percent::from_percent(apy_basis_points as u8); + base_apy.saturating_mul(score_ratio).saturating_mul(capacity_ratio) +} + +/// Update the total score for an asset +pub fn update_total_score(asset: Asset, old_score: u128, new_score: u128) { + let current_total = >::get(asset); + let new_total = current_total.saturating_sub(old_score).saturating_add(new_score); + >::insert(asset, new_total); +} + +/// Update the total deposited amount for an asset +pub fn update_total_deposited( + asset: Asset, + amount: BalanceOf, + is_deposit: bool, +) { + let current_total = >::get(asset); + let new_total = if is_deposit { + current_total.saturating_add(amount) + } else { + current_total.saturating_sub(amount) + }; + >::insert(asset, new_total); +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{mock::*, BoostInfo, UserRewards}; + use frame_support::assert_ok; + use sp_runtime::traits::Zero; + + fn setup_test_asset() { + // Set up WETH with 1% APY and 1000 WETH capacity + assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), Asset::Custom(1))); + AssetApy::::insert(Asset::Custom(1), 100); // 1% = 100 basis points + AssetCapacity::::insert(Asset::Custom(1), 1000u128); + } + + fn create_user_rewards(amount: u128, multiplier: LockMultiplier) -> UserRewardsOf { + UserRewards { + restaking_rewards: Zero::zero(), + service_rewards: Zero::zero(), + boost_rewards: BoostInfo { + amount: amount.saturated_into(), + multiplier, + expiry: Zero::zero(), + }, + } + } + + #[test] + fn test_score_calculation() { + new_test_ext().execute_with(|| { + setup_test_asset(); + + // Test 10 WETH locked for 12 months + let rewards = create_user_rewards(10, LockMultiplier::SixMonths); + let score = calculate_user_score::(Asset::Custom(1), &rewards); + assert_eq!(score, 60); // 10 * 6 months = 60 + }); + } + + #[test] + fn test_apy_distribution() { + new_test_ext().execute_with(|| { + setup_test_asset(); + + // Set up total score and deposits + TotalAssetScore::::insert(Asset::Custom(1), 1000); // Total score of 1000 + TotalDeposited::::insert(Asset::Custom(1), 500); // 500 WETH deposited + + // Test APY calculation for a user with score 60 + let apy = calculate_apy_distribution::(Asset::Custom(1), 60); + + // Expected APY = 1% * (60/1000) * (500/1000) = 0.03% + assert_eq!(apy.deconstruct(), 3); // 0.03% = 3 basis points + }); + } } diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index 5c6ae16c..0f4653f7 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -38,6 +38,7 @@ impl RewardsManager, BlockNumb asset: Asset, amount: BalanceOf, ) -> Result<(), &'static str> { + // TODO : Handle service rewards later Ok(()) } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index da6c7689..bb5120eb 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -110,8 +110,23 @@ pub mod pallet { pub type AllowedRewardAssets = StorageMap<_, Blake2_128Concat, Asset, bool, ValueQuery>; - type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + /// Stores the APY percentage for each asset (in basis points, e.g. 100 = 1%) + #[pallet::storage] + #[pallet::getter(fn asset_apy)] + pub type AssetApy = + StorageMap<_, Blake2_128Concat, Asset, u32, ValueQuery>; + + /// Stores the maximum capacity for each asset + #[pallet::storage] + #[pallet::getter(fn asset_capacity)] + pub type AssetCapacity = + StorageMap<_, Blake2_128Concat, Asset, BalanceOf, ValueQuery>; + + /// Stores the total score for each asset + #[pallet::storage] + #[pallet::getter(fn total_asset_score)] + pub type TotalAssetScore = + StorageMap<_, Blake2_128Concat, Asset, u128, ValueQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -134,6 +149,10 @@ pub mod pallet { AssetWhitelisted { asset: Asset }, /// Asset has been removed from whitelist AssetRemoved { asset: Asset }, + /// Asset rewards have been updated + AssetRewardsUpdated { asset: Asset, total_score: u128, users_updated: u32 }, + /// Asset APY has been updated + AssetApyUpdated { asset: Asset, apy_basis_points: u32 }, } /// Type of reward being added or claimed @@ -154,6 +173,8 @@ pub mod pallet { AssetNotWhitelisted, /// Asset is already whitelisted AssetAlreadyWhitelisted, + /// Invalid APY value + InvalidAPY, } #[pallet::call] @@ -166,6 +187,121 @@ pub mod pallet { reward_type: RewardType, ) -> DispatchResult { let who = ensure_signed(origin)?; + + // Ensure the asset is whitelisted + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); + + // Get user rewards snapshot + let rewards = Self::user_rewards(&who, asset); + + // Calculate user's score based on their stake and lock period + let user_score = functions::calculate_user_score::(asset, &rewards); + + // Calculate APY distribution based on user's score + let apy = functions::calculate_apy_distribution::(asset, user_score); + + // Calculate reward amount based on APY and elapsed time + let reward_amount = match reward_type { + RewardType::Boost => { + // For boost rewards, calculate based on locked amount and APY + let locked_amount = rewards.boost_rewards.amount; + let elapsed_time = frame_system::Pallet::::block_number() + .saturating_sub(rewards.boost_rewards.expiry); + + // Convert APY to per-block rate (assuming 6 second blocks) + // APY / (blocks per year) = reward rate per block + // blocks per year = (365 * 24 * 60 * 60) / 6 = 5,256,000 + let blocks_per_year = T::BlocksPerYear::get(); + let reward_rate = apy.mul_floor(locked_amount) / blocks_per_year.into(); + + reward_rate.saturating_mul(elapsed_time.into()) + }, + RewardType::Service => { + // For service rewards, use the accumulated service rewards + rewards.service_rewards + }, + RewardType::Restaking => { + // For restaking rewards, use the accumulated restaking rewards + rewards.restaking_rewards + }, + }; + + // Ensure there are rewards to claim + ensure!(!reward_amount.is_zero(), Error::::NoRewardsAvailable); + + // Transfer rewards to user + // Note: This assumes the pallet account has sufficient balance + let pallet_account = Self::account_id(); + T::Currency::transfer( + &pallet_account, + &who, + reward_amount, + frame_support::traits::ExistenceRequirement::KeepAlive, + )?; + + // Reset the claimed reward type + match reward_type { + RewardType::Boost => { + // For boost rewards, update the expiry to current block + Self::update_user_rewards( + &who, + asset, + UserRewards { + boost_rewards: BoostInfo { + expiry: frame_system::Pallet::::block_number(), + ..rewards.boost_rewards + }, + ..rewards + }, + ); + }, + RewardType::Service => { + // Reset service rewards to zero + Self::update_user_rewards( + &who, + asset, + UserRewards { service_rewards: Zero::zero(), ..rewards }, + ); + }, + RewardType::Restaking => { + // Reset restaking rewards to zero + Self::update_user_rewards( + &who, + asset, + UserRewards { restaking_rewards: Zero::zero(), ..rewards }, + ); + }, + } + + // Emit event + Self::deposit_event(Event::RewardsClaimed { + account: who, + asset, + amount: reward_amount, + reward_type, + }); + + Ok(()) + } + + /// Update APY for an asset + #[pallet::call_index(6)] + #[pallet::weight(10_000)] + pub fn update_asset_apy( + origin: OriginFor, + asset: Asset, + apy_basis_points: u32, + ) -> DispatchResult { + ensure_root(origin)?; + ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); + ensure!(apy_basis_points <= 10000, Error::::InvalidAPY); // Max 100% + + // Update APY + AssetApy::::insert(asset, apy_basis_points); + + // Emit event + Self::deposit_event(Event::AssetApyUpdated { asset, apy_basis_points }); + Ok(()) } } diff --git a/precompiles/rewards/src/lib.rs b/precompiles/rewards/src/lib.rs index 05100dc9..69b5f38e 100644 --- a/precompiles/rewards/src/lib.rs +++ b/precompiles/rewards/src/lib.rs @@ -1,7 +1,6 @@ // This file is part of Tangle. // Copyright (C) 2022-2024 Tangle Foundation. // -// This file is part of pallet-evm-precompile-multi-asset-delegation package. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,425 +13,217 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! This file contains the implementation of the MultiAssetDelegationPrecompile struct which -//! provides an interface between the EVM and the native MultiAssetDelegation pallet of the runtime. -//! It allows EVM contracts to call functions of the MultiAssetDelegation pallet, in order to enable -//! EVM accounts to interact with the delegation system. -//! -//! The MultiAssetDelegationPrecompile struct implements core methods that correspond to the -//! functions of the MultiAssetDelegation pallet. These methods can be called from EVM contracts. -//! They include functions to join as an operator, delegate assets, withdraw assets, etc. -//! -//! Each method records the gas cost for the operation, performs the requested operation, and -//! returns the result in a format that can be used by the EVM. -//! -//! The MultiAssetDelegationPrecompile struct is generic over the Runtime type, which is the type of -//! the runtime that includes the MultiAssetDelegation pallet. This allows the precompile to work -//! with any runtime that includes the MultiAssetDelegation pallet and meets the other trait bounds -//! required by the precompile. - #![cfg_attr(not(feature = "std"), no_std)] #[cfg(any(test, feature = "fuzzing"))] pub mod mock; -#[cfg(any(test, feature = "fuzzing"))] -pub mod mock_evm; #[cfg(test)] mod tests; use fp_evm::PrecompileHandle; use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - traits::Currency, + dispatch::{GetDispatchInfo, PostDispatchInfo}, + traits::Currency, }; use pallet_evm::AddressMapping; -use pallet_multi_asset_delegation::types::DelegatorBlueprintSelection; use precompile_utils::prelude::*; -use sp_core::{H160, H256, U256}; +use sp_core::{H160, U256}; use sp_runtime::traits::Dispatchable; use sp_std::{marker::PhantomData, vec::Vec}; -use tangle_primitives::{services::Asset, types::WrappedAccountId32}; +use tangle_primitives::{ + services::Asset, + types::{rewards::{LockMultiplier, RewardType}, WrappedAccountId32}, +}; type BalanceOf = - <::Currency as Currency< - ::AccountId, - >>::Balance; + <::Currency as Currency< + ::AccountId, + >>::Balance; -type AssetIdOf = ::AssetId; +type AssetIdOf = ::AssetId; -pub struct MultiAssetDelegationPrecompile(PhantomData); +pub struct RewardsPrecompile(PhantomData); #[precompile_utils::precompile] -impl MultiAssetDelegationPrecompile +impl RewardsPrecompile where - Runtime: pallet_multi_asset_delegation::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, - BalanceOf: TryFrom + Into + solidity::Codec, - AssetIdOf: TryFrom + Into + From, - Runtime::AccountId: From, + Runtime: pallet_rewards::Config + pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, + ::RuntimeOrigin: From>, + Runtime::RuntimeCall: From>, + BalanceOf: TryFrom + Into + solidity::Codec, + AssetIdOf: TryFrom + Into + From, + Runtime::AccountId: From, { - #[precompile::public("joinOperators(uint256)")] - fn join_operators(handle: &mut impl PrecompileHandle, bond_amount: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let bond_amount: BalanceOf = - bond_amount.try_into().map_err(|_| revert("Invalid bond amount"))?; - let call = pallet_multi_asset_delegation::Call::::join_operators { bond_amount }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("scheduleLeaveOperators()")] - fn schedule_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::schedule_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("cancelLeaveOperators()")] - fn cancel_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::cancel_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeLeaveOperators()")] - fn execute_leave_operators(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_leave_operators {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("operatorBondMore(uint256)")] - fn operator_bond_more(handle: &mut impl PrecompileHandle, additional_bond: U256) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let additional_bond: BalanceOf = - additional_bond.try_into().map_err(|_| revert("Invalid bond amount"))?; - let call = - pallet_multi_asset_delegation::Call::::operator_bond_more { additional_bond }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeWithdraw()")] - fn execute_withdraw(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_withdraw { - evm_address: Some(handle.context().caller), - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("scheduleOperatorUnstake(uint256)")] - fn schedule_operator_unstake( - handle: &mut impl PrecompileHandle, - unstake_amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let unstake_amount: BalanceOf = - unstake_amount.try_into().map_err(|_| revert("Invalid unstake amount"))?; - let call = pallet_multi_asset_delegation::Call::::schedule_operator_unstake { - unstake_amount, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("executeOperatorUnstake()")] - fn execute_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_operator_unstake {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("cancelOperatorUnstake()")] - fn cancel_operator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::cancel_operator_unstake {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("goOffline()")] - fn go_offline(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::go_offline {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("goOnline()")] - fn go_online(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::go_online {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("deposit(uint256,address,uint256)")] - fn deposit( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::deposit { - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - evm_address: Some(caller), - }, - )?; - - Ok(()) - } - - #[precompile::public("scheduleWithdraw(uint256,address,uint256)")] - fn schedule_withdraw( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::schedule_withdraw { - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - }, - )?; - - Ok(()) - } - - #[precompile::public("cancelWithdraw(uint256,address,uint256)")] - fn cancel_withdraw( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::cancel_withdraw { - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - }, - )?; - - Ok(()) - } - - #[precompile::public("delegate(bytes32,uint256,address,uint256,uint64[])")] - fn delegate( - handle: &mut impl PrecompileHandle, - operator: H256, - asset_id: U256, - token_address: Address, - amount: U256, - blueprint_selection: Vec, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - let operator = - Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::delegate { - operator, - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - blueprint_selection: DelegatorBlueprintSelection::Fixed( - blueprint_selection.try_into().map_err(|_| { - RevertReason::custom("Too many blueprint ids for fixed selection") - })?, - ), - }, - )?; - - Ok(()) - } - - #[precompile::public("scheduleDelegatorUnstake(bytes32,uint256,address,uint256)")] - fn schedule_delegator_unstake( - handle: &mut impl PrecompileHandle, - operator: H256, - asset_id: U256, - token_address: Address, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - let operator = - Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::schedule_delegator_unstake { - operator, - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - }, - )?; - - Ok(()) - } - - #[precompile::public("executeDelegatorUnstake()")] - fn execute_delegator_unstake(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = pallet_multi_asset_delegation::Call::::execute_delegator_unstake {}; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } - - #[precompile::public("cancelDelegatorUnstake(bytes32,uint256,address,uint256)")] - fn cancel_delegator_unstake( - handle: &mut impl PrecompileHandle, - operator: H256, - asset_id: U256, - token_address: Address, - amount: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - let operator = - Runtime::AddressMapping::into_account_id(H160::from_slice(&operator.0[12..])); - - let (deposit_asset, amount) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_multi_asset_delegation::Call::::cancel_delegator_unstake { - operator, - asset_id: deposit_asset, - amount: amount - .try_into() - .map_err(|_| RevertReason::value_is_too_large("amount"))?, - }, - )?; + /// Set APY for an asset (admin only) + #[precompile::public("setAssetApy(uint256,address,uint256)")] + fn set_asset_apy( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + apy_basis_points: U256, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let asset = if token_address == Address::zero() { + Asset::Custom( + asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, + ) + } else { + Asset::Erc20(token_address.into()) + }; + + let apy: u32 = apy_basis_points + .try_into() + .map_err(|_| revert("Invalid APY basis points"))?; + + let call = pallet_rewards::Call::::set_asset_apy { + asset, + apy_basis_points: apy, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + Ok(()) + } + + /// Claim rewards for a specific asset and reward type + #[precompile::public("claimRewards(uint256,address,uint8)")] + fn claim_rewards( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + reward_type: u8, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let asset = if token_address == Address::zero() { + Asset::Custom( + asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, + ) + } else { + Asset::Erc20(token_address.into()) + }; + + let reward_type = match reward_type { + 0 => RewardType::Boost, + 1 => RewardType::Service, + 2 => RewardType::Restaking, + _ => return Err(revert("Invalid reward type")), + }; + + let call = pallet_rewards::Call::::claim_rewards { + asset, + reward_type, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + Ok(()) + } + + /// Get user's reward info for an asset + #[precompile::public("getUserRewards(address,uint256,address)")] + fn get_user_rewards( + handle: &mut impl PrecompileHandle, + user: Address, + asset_id: U256, + token_address: Address, + ) -> EvmResult<(U256, U256, U256, U256)> { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let user = Runtime::AddressMapping::into_account_id(user.into()); + let asset = if token_address == Address::zero() { + Asset::Custom( + asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, + ) + } else { + Asset::Erc20(token_address.into()) + }; + + let rewards = pallet_rewards::Pallet::::user_rewards(&user, asset); + + Ok(( + rewards.boost_rewards.amount.into(), + rewards.boost_rewards.expiry.into(), + rewards.service_rewards.into(), + rewards.restaking_rewards.into(), + )) + } + + /// Get asset APY and capacity + #[precompile::public("getAssetInfo(uint256,address)")] + fn get_asset_info( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + ) -> EvmResult<(U256, U256)> { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let asset = if token_address == Address::zero() { + Asset::Custom( + asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, + ) + } else { + Asset::Erc20(token_address.into()) + }; + + let apy = pallet_rewards::Pallet::::asset_apy(asset); + let capacity = pallet_rewards::Pallet::::asset_capacity(asset); + + Ok((apy.into(), capacity.into())) + } + + /// Update APY for an asset (admin only) + #[precompile::public("updateAssetApy(uint256,address,uint32)")] + fn update_asset_apy( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + apy_basis_points: u32, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let asset = if token_address == Address::zero() { + Asset::Custom( + asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, + ) + } else { + Asset::Erc20(token_address.into()) + }; + + let call = pallet_rewards::Call::::update_asset_apy { + asset, + apy_basis_points, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + Ok(()) + } +} - Ok(()) - } +#[cfg(test)] +mod test { + use super::*; + use mock::*; + use precompile_utils::testing::*; + use sp_core::H160; + + fn precompiles() -> TestPrecompileSet { + PrecompilesValue::get() + } + + #[test] + fn test_solidity_interface_has_all_function_selectors_documented() { + for file in ["Rewards.sol"] { + precompiles() + .process_selectors(file, |fn_selector, fn_signature| { + assert!( + DOCUMENTED_FUNCTIONS.contains(&fn_selector), + "documented_functions must contain {fn_selector:?} ({fn_signature})", + ); + }); + } + } } diff --git a/precompiles/rewards/src/tests.rs b/precompiles/rewards/src/tests.rs index a2fdac39..3682c881 100644 --- a/precompiles/rewards/src/tests.rs +++ b/precompiles/rewards/src/tests.rs @@ -1,499 +1,196 @@ -use crate::{mock::*, mock_evm::*, U256}; -use frame_support::{assert_ok, traits::Currency}; -use pallet_multi_asset_delegation::{types::OperatorStatus, CurrentRound, Delegators, Operators}; +use super::*; +use frame_support::assert_ok; +use mock::*; use precompile_utils::testing::*; -use sp_core::H160; +use sp_core::{H160, U256}; +use sp_runtime::traits::Zero; use tangle_primitives::services::Asset; -// Helper function for creating and minting tokens -pub fn create_and_mint_tokens( - asset_id: u128, - recipient: ::AccountId, - amount: Balance, -) { - assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, recipient, false, 1)); - assert_ok!(Assets::mint(RuntimeOrigin::signed(recipient), asset_id, recipient, amount)); -} - -#[test] -fn test_selector_less_than_four_bytes_reverts() { - ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test(Alice, Precompile1, vec![1u8, 2, 3]) - .execute_reverts(|output| output == b"Tried to read selector out of bounds"); - }); -} - -#[test] -fn test_unimplemented_selector_reverts() { - ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test(Alice, Precompile1, vec![1u8, 2, 3, 4]) - .execute_reverts(|output| output == b"Unknown selector"); - }); -} - -#[test] -fn test_join_operators() { - ExtBuilder::default().build().execute_with(|| { - let account = sp_core::sr25519::Public::from(TestAccount::Alex); - let initial_balance = Balances::free_balance(account); - assert!(Operators::::get(account).is_none()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::join_operators { bond_amount: U256::from(10_000) }, - ) - .execute_returns(()); - - assert!(Operators::::get(account).is_some()); - let expected_balance = initial_balance - 10_000; - assert_eq!(Balances::free_balance(account), expected_balance); - }); -} - -#[test] -fn test_join_operators_insufficient_balance() { - ExtBuilder::default().build().execute_with(|| { - let account = sp_core::sr25519::Public::from(TestAccount::Eve); - Balances::make_free_balance_be(&account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Eve, - H160::from_low_u64_be(1), - PCall::join_operators { bond_amount: U256::from(10_000) }, - ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); - - assert_eq!(Balances::free_balance(account), 500); - }); -} - -#[test] -fn test_delegate_assets_invalid_operator() { - ExtBuilder::default().build().execute_with(|| { - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - - Balances::make_free_balance_be(&delegator_account, 500); - create_and_mint_tokens(1, delegator_account, 500); - - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: sp_core::sr25519::Public::from(TestAccount::Eve).into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [2, 0, 0, 0], message: Some(\"NotAnOperator\") })"); - - assert_eq!(Balances::free_balance(delegator_account), 500); - }); -} - -#[test] -fn test_delegate_assets() { - ExtBuilder::default().build().execute_with(|| { - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - - Balances::make_free_balance_be(&operator_account, 20_000); - Balances::make_free_balance_be(&delegator_account, 500); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator_account), - Asset::Custom(1), - 200, - Some(TestAccount::Alex.into()) - )); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change when delegating - }); -} - -#[test] -fn test_delegate_assets_insufficient_balance() { - ExtBuilder::default().build().execute_with(|| { - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Eve); - - Balances::make_free_balance_be(&operator_account, 20_000); - Balances::make_free_balance_be(&delegator_account, 500); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Eve, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(300), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_reverts(|output| output == b"Dispatched call failed with error: Module(ModuleError { index: 6, error: [15, 0, 0, 0], message: Some(\"InsufficientBalance\") })"); - - assert_eq!(Balances::free_balance(delegator_account), 500); - }); -} - -#[test] -fn test_schedule_withdraw() { - ExtBuilder::default().build().execute_with(|| { - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - - Balances::make_free_balance_be(&operator_account, 20_000); - Balances::make_free_balance_be(&delegator_account, 500); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::deposit { - asset_id: U256::from(1), - amount: U256::from(200), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert!(Delegators::::get(delegator_account).is_some()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::schedule_withdraw { - asset_id: U256::from(1), - amount: U256::from(100), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change - }); -} - #[test] -fn test_execute_withdraw() { - ExtBuilder::default().build().execute_with(|| { - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - - Balances::make_free_balance_be(&operator_account, 20_000); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::deposit { - asset_id: U256::from(1), - amount: U256::from(200), - token_address: Default::default(), - }, - ) - .execute_returns(()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert!(Delegators::::get(delegator_account).is_some()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::schedule_withdraw { - asset_id: U256::from(1), - amount: U256::from(100), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - - >::put(3); - - PrecompilesValue::get() - .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(metadata.withdraw_requests.is_empty()); - - assert_eq!(Assets::balance(1, delegator_account), 500 - 100); // deposited 200, withdrew 100 - }); +fn test_whitelist_asset() { + ExtBuilder::default().build().execute_with(|| { + let precompiles = precompiles(); + + // Test native asset + let asset_id = U256::from(1); + let token_address = Address::zero(); + + let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) + .write(asset_id) + .write(token_address) + .build(); + + let caller = H160::from_low_u64_be(1); + let context = Context { + address: Default::default(), + caller, + apparent_value: U256::zero(), + }; + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Test ERC20 asset + let token_address = Address(H160::from_low_u64_be(2)); + let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) + .write(U256::zero()) + .write(token_address) + .build(); + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + }); } #[test] -fn test_execute_withdraw_before_due() { - ExtBuilder::default().build().execute_with(|| { - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - - Balances::make_free_balance_be(&delegator_account, 10_000); - Balances::make_free_balance_be(&operator_account, 20_000); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::deposit { - asset_id: U256::from(1), - amount: U256::from(200), - token_address: Default::default(), - }, - ) - .execute_returns(()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert!(Delegators::::get(delegator_account).is_some()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // delegate should not change balance - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::schedule_withdraw { - asset_id: U256::from(1), - amount: U256::from(100), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - - PrecompilesValue::get() - .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) - .execute_returns(()); // should not fail - - // not expired so should not change balance - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); - }); +fn test_set_asset_apy() { + ExtBuilder::default().build().execute_with(|| { + let precompiles = precompiles(); + + // Whitelist asset first + let asset_id = U256::from(1); + let token_address = Address::zero(); + let apy = 500u32; // 5% APY + + // Whitelist the asset + let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) + .write(asset_id) + .write(token_address) + .build(); + + let caller = H160::from_low_u64_be(1); + let context = Context { + address: Default::default(), + caller, + apparent_value: U256::zero(), + }; + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Set APY + let input = EvmDataWriter::new_with_selector(Action::SetAssetApy) + .write(asset_id) + .write(token_address) + .write(apy) + .build(); + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Verify APY was set + let input = EvmDataWriter::new_with_selector(Action::GetAssetInfo) + .write(asset_id) + .write(token_address) + .build(); + + let mut handle = MockHandle::new(context, input); + let result = precompiles.execute(&mut handle).unwrap(); + let (actual_apy, _) = EvmDataReader::new(&result) + .read::<(U256, U256)>() + .unwrap(); + assert_eq!(actual_apy, apy.into()); + }); } #[test] -fn test_cancel_withdraw() { - ExtBuilder::default().build().execute_with(|| { - let delegator_account = sp_core::sr25519::Public::from(TestAccount::Alex); - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - - Balances::make_free_balance_be(&operator_account, 20_000); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - create_and_mint_tokens(1, delegator_account, 500); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::deposit { - asset_id: U256::from(1), - amount: U256::from(200), - token_address: Default::default(), - }, - ) - .execute_returns(()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::delegate { - operator: operator_account.into(), - asset_id: U256::from(1), - amount: U256::from(100), - blueprint_selection: Default::default(), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - assert!(Delegators::::get(delegator_account).is_some()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::schedule_withdraw { - asset_id: U256::from(1), - amount: U256::from(100), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alex, - H160::from_low_u64_be(1), - PCall::cancel_withdraw { - asset_id: U256::from(1), - amount: U256::from(100), - token_address: Default::default(), - }, - ) - .execute_returns(()); - - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert!(metadata.deposits.contains_key(&Asset::Custom(1))); - assert!(metadata.withdraw_requests.is_empty()); - - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change - }); +fn test_update_asset_apy() { + ExtBuilder::default().build().execute_with(|| { + let precompiles = precompiles(); + + // Whitelist asset first + let asset_id = U256::from(1); + let token_address = Address::zero(); + let initial_apy = 500u32; // 5% APY + let updated_apy = 1000u32; // 10% APY + + // Whitelist the asset + let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) + .write(asset_id) + .write(token_address) + .build(); + + let caller = H160::from_low_u64_be(1); + let context = Context { + address: Default::default(), + caller, + apparent_value: U256::zero(), + }; + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Set initial APY + let input = EvmDataWriter::new_with_selector(Action::SetAssetApy) + .write(asset_id) + .write(token_address) + .write(initial_apy) + .build(); + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Update APY + let input = EvmDataWriter::new_with_selector(Action::UpdateAssetApy) + .write(asset_id) + .write(token_address) + .write(updated_apy) + .build(); + + let mut handle = MockHandle::new(context, input); + assert_ok!(precompiles.execute(&mut handle)); + + // Verify APY was updated + let input = EvmDataWriter::new_with_selector(Action::GetAssetInfo) + .write(asset_id) + .write(token_address) + .build(); + + let mut handle = MockHandle::new(context, input); + let result = precompiles.execute(&mut handle).unwrap(); + let (actual_apy, _) = EvmDataReader::new(&result) + .read::<(U256, U256)>() + .unwrap(); + assert_eq!(actual_apy, updated_apy.into()); + }); } #[test] -fn test_operator_go_offline_and_online() { - ExtBuilder::default().build().execute_with(|| { - let operator_account = sp_core::sr25519::Public::from(TestAccount::Bobo); - - Balances::make_free_balance_be(&operator_account, 20_000); - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator_account), - 10_000 - )); - - PrecompilesValue::get() - .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_offline {}) - .execute_returns(()); - - assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Inactive - ); - - PrecompilesValue::get() - .prepare_test(TestAccount::Bobo, H160::from_low_u64_be(1), PCall::go_online {}) - .execute_returns(()); - - assert!( - MultiAssetDelegation::operator_info(operator_account).unwrap().status - == OperatorStatus::Active - ); - - assert_eq!(Balances::free_balance(operator_account), 20_000 - 10_000); - }); +fn test_get_user_rewards() { + ExtBuilder::default().build().execute_with(|| { + let precompiles = precompiles(); + + // Setup test data + let user = Address(H160::from_low_u64_be(2)); + let asset_id = U256::from(1); + let token_address = Address::zero(); + + // Query rewards + let input = EvmDataWriter::new_with_selector(Action::GetUserRewards) + .write(user) + .write(asset_id) + .write(token_address) + .build(); + + let context = Context { + address: Default::default(), + caller: H160::from_low_u64_be(1), + apparent_value: U256::zero(), + }; + + let mut handle = MockHandle::new(context, input); + let result = precompiles.execute(&mut handle).unwrap(); + + // Parse result + let (boost_amount, boost_expiry, service_rewards, restaking_rewards) = + EvmDataReader::new(&result) + .read::<(U256, U256, U256, U256)>() + .unwrap(); + + // Initially all rewards should be zero + assert!(boost_amount.is_zero()); + assert!(boost_expiry.is_zero()); + assert!(service_rewards.is_zero()); + assert!(restaking_rewards.is_zero()); + }); } From 4bb3ebebc46dc654eb06e884bed9b6cab6d0ecb5 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:57:54 +0530 Subject: [PATCH 47/63] refactor and simplify --- .../src/functions/delegate.rs | 122 +++++----------- .../src/functions/deposit.rs | 38 ++--- pallets/multi-asset-delegation/src/lib.rs | 5 +- pallets/multi-asset-delegation/src/types.rs | 4 - .../src/types/delegator.rs | 133 ++++++++++++++++-- .../src/types/operator.rs | 57 ++------ runtime/testnet/src/lib.rs | 1 + 7 files changed, 186 insertions(+), 174 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 0d508ff9..1bd675cf 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -15,20 +15,16 @@ // along with Tangle. If not, see . use super::*; use crate::{types::*, Pallet}; -use frame_support::BoundedVec; use frame_support::{ ensure, pallet_prelude::DispatchResult, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; -use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::{ traits::{CheckedSub, Zero}, DispatchError, Percent, }; -use sp_std::vec; use sp_std::vec::Vec; -use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{ services::{Asset, EvmAddressMapping}, BlueprintId, @@ -55,21 +51,16 @@ impl Pallet { asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, - lock_multiplier: Option, ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; // Ensure enough deposited balance - let balance = + let user_deposit = metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; - ensure!(*balance >= amount, Error::::InsufficientBalance); - // Reduce the balance in deposits - *balance = balance.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; - if *balance == Zero::zero() { - metadata.deposits.remove(&asset_id); - } + // update the user deposit + user_deposit.increase_delegated_amount(amount).map_err(|_| Error::::InsufficientBalance)?; // Check if the delegation exists and update it, otherwise create a new delegation if let Some(delegation) = metadata @@ -79,32 +70,12 @@ impl Pallet { { delegation.amount += amount; } else { - let now = frame_system::Pallet::::block_number(); - let now_as_u32: u32 = - now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved - let locks = if let Some(lock_multiplier) = lock_multiplier { - let expiry_block: BlockNumberFor = lock_multiplier - .expiry_block_number::(now_as_u32) - .try_into() - .map_err(|_| Error::::MaxDelegationsExceeded)?; - let bounded_vec = BoundedVec::try_from(vec![LockInfo { - amount, - lock_multiplier, - expiry_block, - }]) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - Some(bounded_vec) - } else { - None - }; - // Create the new delegation let new_delegation = BondInfoDelegator { operator: operator.clone(), amount, asset_id, blueprint_selection, - locks, }; // Create a mutable copy of delegations @@ -127,25 +98,7 @@ impl Pallet { ); // Create and push the new delegation bond - let now = frame_system::Pallet::::block_number(); - let now_as_u32: u32 = - now.try_into().map_err(|_| Error::::MaxDelegationsExceeded)?; // TODO : Can be improved - let locks = if let Some(lock_multiplier) = lock_multiplier { - let expiry_block: BlockNumberFor = lock_multiplier - .expiry_block_number::(now_as_u32) - .try_into() - .map_err(|_| Error::::MaxDelegationsExceeded)?; - let bounded_vec = BoundedVec::try_from(vec![LockInfo { - amount, - lock_multiplier, - expiry_block, - }]) - .map_err(|_| Error::::MaxDelegationsExceeded)?; - Some(bounded_vec) - } else { - None - }; - let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id, locks }; + let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id }; let mut delegations = operator_metadata.delegations.clone(); @@ -209,19 +162,6 @@ impl Pallet { let delegation = &mut metadata.delegations[delegation_index]; ensure!(delegation.amount >= amount, Error::::InsufficientBalance); - // ensure the locks are not violated - let now = frame_system::Pallet::::block_number(); - if let Some(locks) = &delegation.locks { - // lets filter only active locks - let active_locks = - locks.iter().filter(|lock| lock.expiry_block > now).collect::>(); - let total_locks = - active_locks.iter().fold(0_u32.into(), |acc, lock| acc + lock.amount); - if total_locks != Zero::zero() { - ensure!(amount < total_locks, Error::::LockViolation); - } - } - delegation.amount -= amount; // Create the unstake request @@ -293,28 +233,36 @@ impl Pallet { ensure!(!metadata.delegator_unstake_requests.is_empty(), Error::::NoBondLessRequest); let current_round = Self::current_round(); + let delay = T::DelegationBondLessDelay::get(); + + // First, collect all ready requests and process them + let ready_requests: Vec<_> = metadata + .delegator_unstake_requests + .iter() + .filter(|request| current_round >= delay + request.requested_round) + .cloned() + .collect(); + + // If no requests are ready, return an error + ensure!(!ready_requests.is_empty(), Error::::BondLessNotReady); + + // Process each ready request + for request in ready_requests.iter() { + let deposit_record = metadata + .deposits + .get_mut(&request.asset_id) + .ok_or(Error::::InsufficientBalance)?; + + deposit_record + .decrease_delegated_amount(request.amount) + .map_err(|_| Error::::InsufficientBalance)?; + } - // Process all ready unstake requests - let mut executed_requests = Vec::new(); + // Remove the processed requests metadata.delegator_unstake_requests.retain(|request| { - let delay = T::DelegationBondLessDelay::get(); - if current_round >= delay + request.requested_round { - // Add the amount back to the delegator's deposits - metadata - .deposits - .entry(request.asset_id) - .and_modify(|e| *e += request.amount) - .or_insert(request.amount); - executed_requests.push(request.clone()); - false // Remove this request - } else { - true // Keep this request - } + current_round < delay + request.requested_round }); - // If no requests were executed, return an error - ensure!(!executed_requests.is_empty(), Error::::BondLessNotReady); - Ok(()) }) } @@ -368,12 +316,7 @@ impl Pallet { delegation.amount += amount; } else { delegations - .try_push(DelegatorBond { - delegator: who.clone(), - amount, - asset_id, - locks: Default::default(), - }) + .try_push(DelegatorBond { delegator: who.clone(), amount, asset_id }) .map_err(|_| Error::::MaxDelegationsExceeded)?; // Increase the delegation count only when a new delegation is added @@ -401,7 +344,6 @@ impl Pallet { amount: unstake_request.amount, asset_id: unstake_request.asset_id, blueprint_selection: unstake_request.blueprint_selection, - locks: Default::default(), // should be able to unstake only if locks didnt exist }) .map_err(|_| Error::::MaxDelegationsExceeded)?; } @@ -490,4 +432,4 @@ impl Pallet { Ok(()) }) } -} +} \ No newline at end of file diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index cedb9642..a1125cc3 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -21,6 +21,7 @@ use frame_support::{ sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; +use tangle_primitives::types::rewards::LockMultiplier; use sp_core::H160; use tangle_primitives::services::{Asset, EvmAddressMapping}; @@ -89,22 +90,24 @@ impl Pallet { asset_id: Asset, amount: BalanceOf, evm_address: Option, + lock_multiplier: Option, ) -> DispatchResult { ensure!(amount >= T::MinDelegateAmount::get(), Error::::BondTooLow); // Transfer the amount to the pallet account Self::handle_transfer_to_pallet(&who, asset_id, amount, evm_address)?; + let now = >::block_number(); + // Update storage Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { let metadata = maybe_metadata.get_or_insert_with(Default::default); // Handle checked addition first to avoid ? operator in closure if let Some(existing) = metadata.deposits.get(&asset_id) { - let new_amount = - existing.checked_add(&amount).ok_or(Error::::DepositOverflow)?; - metadata.deposits.insert(asset_id, new_amount); + existing.increase_deposited_amount(amount, lock_multiplier, now); } else { - metadata.deposits.insert(asset_id, amount); + let new_deposit = Deposit::new(amount, lock_multiplier, now); + metadata.deposits.insert(asset_id, new_deposit); } Ok(()) })?; @@ -132,16 +135,12 @@ impl Pallet { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + let now = >::block_number(); + // Ensure there is enough deposited balance - let balance = + let deposit = metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; - ensure!(*balance >= amount, Error::::InsufficientBalance); - - // Reduce the balance in deposits - *balance -= amount; - if *balance == Zero::zero() { - metadata.deposits.remove(&asset_id); - } + deposit.decrease_deposited_amount(amount, now).map_err(|_| Error::::InsufficientBalance)?; // Create the unstake request let current_round = Self::current_round(); @@ -244,6 +243,7 @@ impl Pallet { ) -> DispatchResult { Delegators::::try_mutate(&who, |maybe_metadata| { let metadata = maybe_metadata.as_mut().ok_or(Error::::NotDelegator)?; + let now = >::block_number(); // Find and remove the matching withdraw request let request_index = metadata @@ -255,11 +255,15 @@ impl Pallet { let withdraw_request = metadata.withdraw_requests.remove(request_index); // Add the amount back to the delegator's deposits - metadata - .deposits - .entry(asset_id) - .and_modify(|e| *e += withdraw_request.amount) - .or_insert(withdraw_request.amount); + if let Some(deposit) = metadata.deposits.get_mut(&withdraw_request.asset_id) { + deposit.increase_deposited_amount(withdraw_request.amount, None, now) + .map_err(|_| Error::::InsufficientBalance)?; + } else { + // we are only able to withdraw from existing deposits without any locks + // so when we add back, add it without any locks + let new_deposit = Deposit::new(withdraw_request.amount, None, now); + metadata.deposits.insert(withdraw_request.asset_id, new_deposit); + } // Update the status if no more delegations exist if metadata.delegations.is_empty() { diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 62b52c9c..aa5d6f19 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -556,9 +556,10 @@ pub mod pallet { asset_id: Asset, amount: BalanceOf, evm_address: Option, + lock_multiplier: Option, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::process_deposit(who.clone(), asset_id, amount, evm_address)?; + Self::process_deposit(who.clone(), asset_id, amount, evm_address, lock_multiplier)?; Self::deposit_event(Event::Deposited { who, amount, asset_id }); Ok(()) } @@ -610,7 +611,6 @@ pub mod pallet { asset_id: Asset, amount: BalanceOf, blueprint_selection: DelegatorBlueprintSelection, - lock_multiplier: Option, ) -> DispatchResult { let who = ensure_signed(origin)?; Self::process_delegate( @@ -619,7 +619,6 @@ pub mod pallet { asset_id, amount, blueprint_selection, - lock_multiplier, )?; Self::deposit_event(Event::Delegated { who, operator, asset_id, amount }); Ok(()) diff --git a/pallets/multi-asset-delegation/src/types.rs b/pallets/multi-asset-delegation/src/types.rs index 24ee507c..e5d740b9 100644 --- a/pallets/multi-asset-delegation/src/types.rs +++ b/pallets/multi-asset-delegation/src/types.rs @@ -40,8 +40,6 @@ pub type OperatorMetadataOf = OperatorMetadata< ::AssetId, ::MaxDelegations, ::MaxOperatorBlueprints, - BlockNumberFor, - ::MaxDelegations, >; pub type OperatorSnapshotOf = OperatorSnapshot< @@ -49,8 +47,6 @@ pub type OperatorSnapshotOf = OperatorSnapshot< BalanceOf, ::AssetId, ::MaxDelegations, - BlockNumberFor, - ::MaxDelegations, >; pub type DelegatorMetadataOf = DelegatorMetadata< diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index d72fcc7b..3c632a6d 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -15,9 +15,12 @@ // along with Tangle. If not, see . use super::*; +use frame_support::ensure; +use sp_runtime::traits::Zero; use frame_support::{pallet_prelude::Get, BoundedVec}; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, BlueprintId}; +use sp_std::fmt::Debug; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -84,12 +87,12 @@ pub struct DelegatorMetadata< MaxLocks: Get, > { /// A map of deposited assets and their respective amounts. - pub deposits: BTreeMap, Balance>, + pub deposits: BTreeMap, Deposit>, /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. pub delegations: BoundedVec< - BondInfoDelegator, + BondInfoDelegator, MaxDelegations, >, /// A vector of requests to reduce the bonded amount. @@ -164,7 +167,7 @@ impl< /// Returns a reference to the list of delegations. pub fn get_delegations( &self, - ) -> &Vec> + ) -> &Vec> { &self.delegations } @@ -201,7 +204,7 @@ impl< pub fn calculate_delegation_by_operator( &self, operator: AccountId, - ) -> Vec<&BondInfoDelegator> + ) -> Vec<&BondInfoDelegator> where AccountId: Eq + PartialEq, { @@ -211,11 +214,121 @@ impl< /// Represents a deposit of a specific asset. #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct Deposit { - /// The amount of the asset deposited. +pub struct Deposit> { + /// The total amount deposited by the user (includes both delegated and non-delegated). pub amount: Balance, - /// The ID of the deposited asset. - pub asset_id: Asset, + /// The total delegated amount by the user (this can never be greater than `amount`). + pub delegated_amount: Balance, + /// The locks associated with this deposit. + pub locks: Option, MaxLocks>>, +} + +impl + sp_std::cmp::PartialOrd, MaxLocks: Get> Deposit { + pub fn new(amount: Balance, lock_multiplier: Option, current_block_number: BlockNumber) -> Self { + let locks = lock_multiplier.map(|multiplier| { + let expiry_block = current_block_number.saturating_add(multiplier.get_blocks().into()); + BoundedVec::try_from(vec![LockInfo { + amount, + expiry_block, + lock_multiplier: multiplier, + }]).expect("This should not happen since only one lock exists!") + }); + + Deposit { + amount, + delegated_amount: Default::default(), + locks, + } + } + + pub fn get_amount(&self) -> Balance { + self.amount.clone() + } + + pub fn increase_delegated_amount(&mut self, amount_to_increase: Balance) -> Result<(), &'static str> { + // sanity check that the proposed amount when added to the current delegated amount is not greater than the total amount + let new_delegated_amount = self.delegated_amount.saturating_add(amount_to_increase); + if new_delegated_amount > self.amount { + return Err("delegated amount cannot be greater than total amount"); + } + + // increase the delegated amount + self.delegated_amount = new_delegated_amount; + + Ok(()) + } + + pub fn decrease_delegated_amount(&mut self, amount_to_decrease: Balance) -> Result<(), &'static str> { + // sanity check that the delegated amount is actually greater than the amount to decrease + if self.delegated_amount < amount_to_decrease { + return Err("delegated amount cannot be less than amount to decrease"); + } + + // decrease the delegated amount + self.delegated_amount = self.delegated_amount.saturating_sub(amount_to_decrease); + Ok(()) + } + + pub fn increase_deposited_amount(&mut self, amount_to_increase: Balance, lock_multiplier: Option, current_block_number: BlockNumber) -> Result<(), &'static str> { + // Update the total amount first + self.amount = self.amount.saturating_add(amount_to_increase); + + // If there's a lock multiplier, add a new lock + if let Some(multiplier) = lock_multiplier { + let lock_blocks = multiplier.get_blocks(); + let expiry_block = current_block_number.saturating_add(lock_blocks.into()); + + let new_lock = LockInfo { + amount: amount_to_increase, + expiry_block, + lock_multiplier: multiplier, + }; + + // Initialize locks if None or push to existing locks + if let Some(locks) = &mut self.locks { + locks.try_push(new_lock).map_err(|_| "Failed to push new lock - exceeded MaxLocks bound")?; + } else { + self.locks = Some(BoundedVec::try_from(vec![new_lock]) + .expect("This should not happen since only one lock exists!")); + } + } + + Ok(()) + } + + pub fn decrease_deposited_amount( + &mut self, + amount_to_decrease: Balance, + current_block_number: BlockNumber, + ) -> Result<(), &'static str> { + // Remove expired locks and get total locked amount + let total_locked = self + .locks + .as_mut() + .filter(|locks| { + locks.retain(|lock| lock.expiry_block > current_block_number); + true + }) + .map_or(Zero::zero(), |locks| { + locks.iter().map(|lock| lock.amount.clone()).sum() + }); + + // Calculate free amount and check if decrease is possible + let free_amount = self.amount.saturating_sub(total_locked); + ensure!( + free_amount >= amount_to_decrease, + "total free amount cannot be lesser than amount to decrease" + ); + + // Update amount and ensure it covers delegations + self.amount = self.amount.saturating_sub(amount_to_decrease); + ensure!( + self.amount >= self.delegated_amount, + "delegated amount cannot be greater than total amount" + ); + + Ok(()) + } } /// Represents a stake between a delegator and an operator. @@ -225,8 +338,6 @@ pub struct BondInfoDelegator< Balance, AssetId: Encode + Decode, MaxBlueprints: Get, - BlockNumber, - MaxLocks: Get, > { /// The account ID of the operator. pub operator: AccountId, @@ -236,8 +347,6 @@ pub struct BondInfoDelegator< pub asset_id: Asset, /// The blueprint selection mode for this delegator. pub blueprint_selection: DelegatorBlueprintSelection, - /// The locks associated with this delegation. - pub locks: Option, MaxLocks>>, } /// Struct to store the lock info diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 35466a3a..8daebea5 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -20,33 +20,18 @@ use tangle_primitives::services::Asset; /// A snapshot of the operator state at the start of the round. #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct OperatorSnapshot< - AccountId, - Balance, - AssetId: Encode + Decode, - MaxDelegations: Get, - BlockNumber, - MaxLocks: Get, -> { +pub struct OperatorSnapshot> +{ /// The total value locked by the operator. pub stake: Balance, /// The rewardable delegations. This list is a subset of total delegators, where certain /// delegators are adjusted based on their scheduled status. - pub delegations: BoundedVec< - DelegatorBond, - MaxDelegations, - >, + pub delegations: BoundedVec, MaxDelegations>, } -impl< - AccountId, - Balance, - AssetId: Encode + Decode, - MaxDelegations: Get, - BlockNumber, - MaxLocks: Get, - > OperatorSnapshot +impl> + OperatorSnapshot where AssetId: PartialEq + Ord + Copy, Balance: Default + core::ops::AddAssign + Copy, @@ -104,8 +89,6 @@ pub struct OperatorMetadata< AssetId: Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, - BlockNumber, - MaxLocks: Get, > { /// The operator's self-stake amount. pub stake: Balance, @@ -115,10 +98,7 @@ pub struct OperatorMetadata< /// any given time. pub request: Option>, /// A list of all current delegations. - pub delegations: BoundedVec< - DelegatorBond, - MaxDelegations, - >, + pub delegations: BoundedVec, MaxDelegations>, /// The current status of the operator. pub status: OperatorStatus, /// The set of blueprint IDs this operator works with. @@ -131,18 +111,7 @@ impl< AssetId: Encode + Decode, MaxDelegations: Get, MaxBlueprints: Get, - BlockNumber, - MaxLocks: Get, - > Default - for OperatorMetadata< - AccountId, - Balance, - AssetId, - MaxDelegations, - MaxBlueprints, - BlockNumber, - MaxLocks, - > + > Default for OperatorMetadata where Balance: Default, { @@ -160,19 +129,11 @@ where /// Represents a stake for an operator #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct DelegatorBond< - AccountId, - Balance, - AssetId: Encode + Decode, - BlockNumber, - MaxLocks: Get, -> { +pub struct DelegatorBond { /// The account ID of the delegator. pub delegator: AccountId, /// The amount bonded. pub amount: Balance, /// The ID of the bonded asset. pub asset_id: Asset, - /// The locks associated with this delegation. - pub locks: Option, MaxLocks>>, -} +} \ No newline at end of file diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 26cbee64..05fb2e97 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -261,6 +261,7 @@ parameter_types! { impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; + #[] type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; type WeightInfo = (); From 99926e58970c5ce0616e00cc09ef8b3aba1db977 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:06:12 +0530 Subject: [PATCH 48/63] refactoring --- .../src/functions/delegate.rs | 14 +- .../src/functions/deposit.rs | 18 ++- .../src/types/delegator.rs | 129 +++++++++--------- .../src/types/operator.rs | 2 +- runtime/testnet/src/lib.rs | 1 - 5 files changed, 84 insertions(+), 80 deletions(-) diff --git a/pallets/multi-asset-delegation/src/functions/delegate.rs b/pallets/multi-asset-delegation/src/functions/delegate.rs index 1bd675cf..36c05f8c 100644 --- a/pallets/multi-asset-delegation/src/functions/delegate.rs +++ b/pallets/multi-asset-delegation/src/functions/delegate.rs @@ -60,7 +60,9 @@ impl Pallet { metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; // update the user deposit - user_deposit.increase_delegated_amount(amount).map_err(|_| Error::::InsufficientBalance)?; + user_deposit + .increase_delegated_amount(amount) + .map_err(|_| Error::::InsufficientBalance)?; // Check if the delegation exists and update it, otherwise create a new delegation if let Some(delegation) = metadata @@ -252,16 +254,16 @@ impl Pallet { .deposits .get_mut(&request.asset_id) .ok_or(Error::::InsufficientBalance)?; - + deposit_record .decrease_delegated_amount(request.amount) .map_err(|_| Error::::InsufficientBalance)?; } // Remove the processed requests - metadata.delegator_unstake_requests.retain(|request| { - current_round < delay + request.requested_round - }); + metadata + .delegator_unstake_requests + .retain(|request| current_round < delay + request.requested_round); Ok(()) }) @@ -432,4 +434,4 @@ impl Pallet { Ok(()) }) } -} \ No newline at end of file +} diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index a1125cc3..13280448 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -21,9 +21,9 @@ use frame_support::{ sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; -use tangle_primitives::types::rewards::LockMultiplier; use sp_core::H160; use tangle_primitives::services::{Asset, EvmAddressMapping}; +use tangle_primitives::types::rewards::LockMultiplier; impl Pallet { /// Returns the account ID of the pallet. @@ -102,10 +102,13 @@ impl Pallet { // Update storage Delegators::::try_mutate(&who, |maybe_metadata| -> DispatchResult { let metadata = maybe_metadata.get_or_insert_with(Default::default); - // Handle checked addition first to avoid ? operator in closure - if let Some(existing) = metadata.deposits.get(&asset_id) { - existing.increase_deposited_amount(amount, lock_multiplier, now); + // If there's an existing deposit, increase it + if let Some(existing) = metadata.deposits.get_mut(&asset_id) { + existing + .increase_deposited_amount(amount, lock_multiplier, now) + .map_err(|_| Error::::InsufficientBalance)?; } else { + // Create a new deposit if none exists let new_deposit = Deposit::new(amount, lock_multiplier, now); metadata.deposits.insert(asset_id, new_deposit); } @@ -140,7 +143,9 @@ impl Pallet { // Ensure there is enough deposited balance let deposit = metadata.deposits.get_mut(&asset_id).ok_or(Error::::InsufficientBalance)?; - deposit.decrease_deposited_amount(amount, now).map_err(|_| Error::::InsufficientBalance)?; + deposit + .decrease_deposited_amount(amount, now) + .map_err(|_| Error::::InsufficientBalance)?; // Create the unstake request let current_round = Self::current_round(); @@ -256,7 +261,8 @@ impl Pallet { // Add the amount back to the delegator's deposits if let Some(deposit) = metadata.deposits.get_mut(&withdraw_request.asset_id) { - deposit.increase_deposited_amount(withdraw_request.amount, None, now) + deposit + .increase_deposited_amount(withdraw_request.amount, None, now) .map_err(|_| Error::::InsufficientBalance)?; } else { // we are only able to withdraw from existing deposits without any locks diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 3c632a6d..1d36ea57 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -16,11 +16,11 @@ use super::*; use frame_support::ensure; -use sp_runtime::traits::Zero; use frame_support::{pallet_prelude::Get, BoundedVec}; +use sp_runtime::traits::Zero; +use sp_std::fmt::Debug; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, BlueprintId}; -use sp_std::fmt::Debug; /// Represents how a delegator selects which blueprints to work with. #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Eq)] @@ -91,10 +91,8 @@ pub struct DelegatorMetadata< /// A vector of withdraw requests. pub withdraw_requests: BoundedVec, MaxWithdrawRequests>, /// A list of all current delegations. - pub delegations: BoundedVec< - BondInfoDelegator, - MaxDelegations, - >, + pub delegations: + BoundedVec, MaxDelegations>, /// A vector of requests to reduce the bonded amount. pub delegator_unstake_requests: BoundedVec, MaxUnstakeRequests>, @@ -167,8 +165,7 @@ impl< /// Returns a reference to the list of delegations. pub fn get_delegations( &self, - ) -> &Vec> - { + ) -> &Vec> { &self.delegations } @@ -223,73 +220,84 @@ pub struct Deposit> { pub locks: Option, MaxLocks>>, } -impl + sp_std::cmp::PartialOrd, MaxLocks: Get> Deposit { - pub fn new(amount: Balance, lock_multiplier: Option, current_block_number: BlockNumber) -> Self { +impl< + Balance: Debug + Default + Clone + sp_runtime::Saturating + sp_std::cmp::PartialOrd + From, + BlockNumber: Debug + sp_runtime::Saturating + std::convert::From + sp_std::cmp::PartialOrd, + MaxLocks: Get, + > Deposit +{ + pub fn new( + amount: Balance, + lock_multiplier: Option, + current_block_number: BlockNumber, + ) -> Self { let locks = lock_multiplier.map(|multiplier| { let expiry_block = current_block_number.saturating_add(multiplier.get_blocks().into()); BoundedVec::try_from(vec![LockInfo { - amount, + amount: amount.clone(), expiry_block, lock_multiplier: multiplier, - }]).expect("This should not happen since only one lock exists!") + }]) + .expect("This should not happen since only one lock exists!") }); - Deposit { - amount, - delegated_amount: Default::default(), - locks, - } + Deposit { amount, delegated_amount: Balance::default(), locks } } - pub fn get_amount(&self) -> Balance { + pub fn get_total_amount(&self) -> Balance { self.amount.clone() } - pub fn increase_delegated_amount(&mut self, amount_to_increase: Balance) -> Result<(), &'static str> { + pub fn increase_delegated_amount( + &mut self, + amount_to_increase: Balance, + ) -> Result<(), &'static str> { // sanity check that the proposed amount when added to the current delegated amount is not greater than the total amount - let new_delegated_amount = self.delegated_amount.saturating_add(amount_to_increase); - if new_delegated_amount > self.amount { - return Err("delegated amount cannot be greater than total amount"); - } - - // increase the delegated amount + let new_delegated_amount = + self.delegated_amount.clone().saturating_add(amount_to_increase.clone()); + ensure!( + new_delegated_amount <= self.amount, + "delegated amount cannot be greater than total amount" + ); self.delegated_amount = new_delegated_amount; - Ok(()) } - pub fn decrease_delegated_amount(&mut self, amount_to_decrease: Balance) -> Result<(), &'static str> { - // sanity check that the delegated amount is actually greater than the amount to decrease - if self.delegated_amount < amount_to_decrease { - return Err("delegated amount cannot be less than amount to decrease"); - } - - // decrease the delegated amount - self.delegated_amount = self.delegated_amount.saturating_sub(amount_to_decrease); + pub fn decrease_delegated_amount( + &mut self, + amount_to_decrease: Balance, + ) -> Result<(), &'static str> { + self.delegated_amount = self.delegated_amount.clone().saturating_sub(amount_to_decrease); Ok(()) } - pub fn increase_deposited_amount(&mut self, amount_to_increase: Balance, lock_multiplier: Option, current_block_number: BlockNumber) -> Result<(), &'static str> { + pub fn increase_deposited_amount( + &mut self, + amount_to_increase: Balance, + lock_multiplier: Option, + current_block_number: BlockNumber, + ) -> Result<(), &'static str> { // Update the total amount first - self.amount = self.amount.saturating_add(amount_to_increase); + self.amount = self.amount.clone().saturating_add(amount_to_increase.clone()); // If there's a lock multiplier, add a new lock if let Some(multiplier) = lock_multiplier { let lock_blocks = multiplier.get_blocks(); let expiry_block = current_block_number.saturating_add(lock_blocks.into()); - - let new_lock = LockInfo { - amount: amount_to_increase, - expiry_block, - lock_multiplier: multiplier, - }; + + let new_lock = + LockInfo { amount: amount_to_increase, expiry_block, lock_multiplier: multiplier }; // Initialize locks if None or push to existing locks if let Some(locks) = &mut self.locks { - locks.try_push(new_lock).map_err(|_| "Failed to push new lock - exceeded MaxLocks bound")?; + locks + .try_push(new_lock) + .map_err(|_| "Failed to push new lock - exceeded MaxLocks bound")?; } else { - self.locks = Some(BoundedVec::try_from(vec![new_lock]) - .expect("This should not happen since only one lock exists!")); + self.locks = Some( + BoundedVec::try_from(vec![new_lock]) + .expect("This should not happen since only one lock exists!"), + ); } } @@ -301,27 +309,20 @@ impl Result<(), &'static str> { - // Remove expired locks and get total locked amount - let total_locked = self - .locks - .as_mut() - .filter(|locks| { - locks.retain(|lock| lock.expiry_block > current_block_number); - true - }) - .map_or(Zero::zero(), |locks| { - locks.iter().map(|lock| lock.amount.clone()).sum() - }); + let total_locked = self.locks.as_ref().map_or(Balance::from(0_u32), |locks| { + locks + .iter() + .filter(|lock| lock.expiry_block > current_block_number) + .fold(Balance::from(0_u32), |acc, lock| acc.saturating_add(lock.amount.clone())) + }); - // Calculate free amount and check if decrease is possible - let free_amount = self.amount.saturating_sub(total_locked); + let free_amount = self.amount.clone().saturating_sub(total_locked); ensure!( free_amount >= amount_to_decrease, "total free amount cannot be lesser than amount to decrease" ); - // Update amount and ensure it covers delegations - self.amount = self.amount.saturating_sub(amount_to_decrease); + self.amount = self.amount.clone().saturating_sub(amount_to_decrease); ensure!( self.amount >= self.delegated_amount, "delegated amount cannot be greater than total amount" @@ -333,12 +334,8 @@ impl, -> { +pub struct BondInfoDelegator> +{ /// The account ID of the operator. pub operator: AccountId, /// The amount bonded. diff --git a/pallets/multi-asset-delegation/src/types/operator.rs b/pallets/multi-asset-delegation/src/types/operator.rs index 8daebea5..e0e7ca27 100644 --- a/pallets/multi-asset-delegation/src/types/operator.rs +++ b/pallets/multi-asset-delegation/src/types/operator.rs @@ -136,4 +136,4 @@ pub struct DelegatorBond { pub amount: Balance, /// The ID of the bonded asset. pub asset_id: Asset, -} \ No newline at end of file +} diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 05fb2e97..26cbee64 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -261,7 +261,6 @@ parameter_types! { impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; - #[] type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; type WeightInfo = (); From 17c818a540896df8b75ae2bac9d14114b6a7a7cd Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:50:02 +0530 Subject: [PATCH 49/63] refactoring test limits --- .../src/tests/delegate.rs | 143 +------ .../src/tests/deposit.rs | 185 ++++++++- .../src/tests/operator.rs | 2 + .../src/tests/session_manager.rs | 3 - pallets/rewards/src/tests.rs | 377 ++++++++++++++++++ 5 files changed, 571 insertions(+), 139 deletions(-) diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 19fb849b..04cb2af6 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -42,7 +42,8 @@ fn delegate_should_work() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, - None + None, + None, )); assert_ok!(MultiAssetDelegation::delegate( @@ -51,7 +52,6 @@ fn delegate_should_work() { asset_id.clone(), amount, Default::default(), - None )); // Assert @@ -95,6 +95,7 @@ fn schedule_delegator_unstake_should_work() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); assert_ok!(MultiAssetDelegation::delegate( @@ -103,7 +104,6 @@ fn schedule_delegator_unstake_should_work() { asset_id.clone(), amount, Default::default(), - None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -149,6 +149,7 @@ fn execute_delegator_unstake_should_work() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); assert_ok!(MultiAssetDelegation::delegate( @@ -157,8 +158,8 @@ fn execute_delegator_unstake_should_work() { asset_id.clone(), amount, Default::default(), - None )); + assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( RuntimeOrigin::signed(who.clone()), operator.clone(), @@ -177,7 +178,10 @@ fn execute_delegator_unstake_should_work() { let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); assert!(metadata.delegator_unstake_requests.is_empty()); assert!(metadata.deposits.get(&asset_id).is_some()); - assert_eq!(metadata.deposits.get(&asset_id).unwrap(), &amount); + let deposit = metadata.deposits.get(&asset_id).unwrap(); + assert_eq!(deposit.amount, amount); + assert_eq!(deposit.delegated_amount, 0); + assert_eq!(deposit.locks.unwrap().len(), 1); }); } @@ -202,6 +206,7 @@ fn cancel_delegator_unstake_should_work() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); assert_ok!(MultiAssetDelegation::delegate( @@ -210,7 +215,6 @@ fn cancel_delegator_unstake_should_work() { asset_id.clone(), amount, Default::default(), - None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -277,6 +281,7 @@ fn cancel_delegator_unstake_should_update_already_existing() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); assert_ok!(MultiAssetDelegation::delegate( @@ -285,7 +290,6 @@ fn cancel_delegator_unstake_should_update_already_existing() { asset_id.clone(), amount, Default::default(), - None )); assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( @@ -355,6 +359,7 @@ fn delegate_should_fail_if_not_enough_balance() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount - 20, + None, None )); @@ -365,7 +370,6 @@ fn delegate_should_fail_if_not_enough_balance() { asset_id.clone(), amount, Default::default(), - None ), Error::::InsufficientBalance ); @@ -393,6 +397,7 @@ fn schedule_delegator_unstake_should_fail_if_no_delegation() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); @@ -429,6 +434,7 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount, + None, None )); assert_ok!(MultiAssetDelegation::delegate( @@ -437,7 +443,6 @@ fn execute_delegator_unstake_should_fail_if_not_ready() { asset_id.clone(), amount, Default::default(), - None )); assert_noop!( @@ -486,6 +491,7 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { RuntimeOrigin::signed(who.clone()), asset_id.clone(), amount + additional_amount, + None, None )); @@ -496,7 +502,6 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { asset_id.clone(), amount, Default::default(), - None )); // Assert first delegation @@ -524,7 +529,6 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { asset_id.clone(), additional_amount, Default::default(), - None )); // Assert updated delegation @@ -546,119 +550,4 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_operator_delegation.amount, amount + additional_amount); assert_eq!(updated_operator_delegation.asset_id, asset_id); }); -} - -#[test] -fn delegate_should_work_with_lock_multiplier() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - create_and_mint_tokens(VDOT, who.clone(), amount); - - // Deposit first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default(), - Some(LockMultiplier::default()) - )); - - // Assert - let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.deposits.get(&asset_id).is_none()); - assert_eq!(metadata.delegations.len(), 1); - let delegation = &metadata.delegations[0]; - assert_eq!(delegation.operator, operator.clone()); - assert_eq!(delegation.amount, amount); - assert_eq!(delegation.asset_id, asset_id); - - // check the lock info - assert_eq!(delegation.locks.clone().unwrap().first().unwrap().amount, amount); - assert_eq!( - delegation.locks.clone().unwrap().first().unwrap().lock_multiplier, - LockMultiplier::default() - ); - assert_eq!(delegation.locks.clone().unwrap().first().unwrap().expiry_block, 432001); - - // Check the operator metadata - let operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); - assert_eq!(operator_metadata.delegation_count, 1); - assert_eq!(operator_metadata.delegations.len(), 1); - let operator_delegation = &operator_metadata.delegations[0]; - assert_eq!(operator_delegation.delegator, who.clone()); - assert_eq!(operator_delegation.amount, amount); - assert_eq!(operator_delegation.asset_id, asset_id); - }); -} - -#[test] -fn schedule_delegator_unstake_should_work_with_lock_multiplier() { - new_test_ext().execute_with(|| { - // Arrange - let who: AccountId = Bob.into(); - let operator: AccountId = Alice.into(); - let asset_id = Asset::Custom(VDOT); - let amount = 100; - - create_and_mint_tokens(VDOT, who.clone(), amount); - - assert_ok!(MultiAssetDelegation::join_operators( - RuntimeOrigin::signed(operator.clone()), - 10_000 - )); - - // Deposit and delegate first - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(who.clone()), - asset_id.clone(), - amount, - None - )); - assert_ok!(MultiAssetDelegation::delegate( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - Default::default(), - Some(LockMultiplier::default()) - )); - - // Should not work with locks - assert_noop!( - MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - ), - Error::::LockViolation - ); - - // time travel to after lock expiry - System::set_block_number(432002); - assert_ok!(MultiAssetDelegation::schedule_delegator_unstake( - RuntimeOrigin::signed(who.clone()), - operator.clone(), - asset_id.clone(), - amount, - )); - }); -} +} \ No newline at end of file diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index d72c669e..bb8a8062 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -52,12 +52,15 @@ fn deposit_should_work_for_fungible_asset() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, + None, None )); // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + let deposit = metadata.deposits.get(&Asset::Custom(VDOT)).unwrap(); + assert_eq!(deposit.amount, amount); + assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { @@ -82,12 +85,15 @@ fn deposit_should_work_for_evm_asset() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, + None, None )); // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + let deposit = metadata.deposits.get(&Asset::Custom(VDOT)).unwrap(); + assert_eq!(deposit.amount, amount); + assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { @@ -112,12 +118,15 @@ fn multiple_deposit_should_work() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, - None + None, + None, )); // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&amount)); + let deposit = metadata.deposits.get(&Asset::Custom(VDOT)).unwrap(); + assert_eq!(deposit.amount, amount); + assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { @@ -131,12 +140,15 @@ fn multiple_deposit_should_work() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, + None, None )); // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(VDOT),), Some(&(amount * 2))); + let deposit = metadata.deposits.get(&Asset::Custom(VDOT)).unwrap(); + assert_eq!(deposit.amount, amount * 2); + assert_eq!( System::events().last().unwrap().event, RuntimeEvent::MultiAssetDelegation(crate::Event::Deposited { @@ -162,6 +174,7 @@ fn deposit_should_fail_for_insufficient_balance() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, + None, None ), ArithmeticError::Underflow @@ -183,6 +196,7 @@ fn deposit_should_fail_for_bond_too_low() { RuntimeOrigin::signed(who.clone()), Asset::Custom(VDOT), amount, + None, None ), Error::::BondTooLow @@ -205,6 +219,7 @@ fn schedule_withdraw_should_work() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); @@ -216,7 +231,8 @@ fn schedule_withdraw_should_work() { // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert_eq!(metadata.deposits.get(&asset_id), None); + let deposit = metadata.deposits.get(&asset_id).unwrap(); + assert_eq!(deposit.amount, amount); assert!(!metadata.withdraw_requests.is_empty()); let request = metadata.withdraw_requests.first().unwrap(); assert_eq!(request.asset_id, asset_id); @@ -260,6 +276,7 @@ fn schedule_withdraw_should_fail_for_insufficient_balance() { RuntimeOrigin::signed(who.clone()), asset_id, 100, + None, None )); @@ -289,6 +306,7 @@ fn schedule_withdraw_should_fail_if_withdraw_request_exists() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); @@ -316,6 +334,7 @@ fn execute_withdraw_should_work() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); assert_ok!(MultiAssetDelegation::schedule_withdraw( @@ -372,6 +391,7 @@ fn execute_withdraw_should_fail_if_no_withdraw_request() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); @@ -397,8 +417,10 @@ fn execute_withdraw_should_fail_if_withdraw_not_ready() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); + assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who.clone()), asset_id, @@ -435,8 +457,10 @@ fn cancel_withdraw_should_work() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); + assert_ok!(MultiAssetDelegation::schedule_withdraw( RuntimeOrigin::signed(who.clone()), asset_id, @@ -451,9 +475,12 @@ fn cancel_withdraw_should_work() { // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.withdraw_requests.is_empty()); - assert_eq!(metadata.deposits.get(&asset_id), Some(&amount)); - assert_eq!(metadata.status, DelegatorStatus::Active); + let deposit = metadata.deposits.get(&asset_id).unwrap(); + assert_eq!(deposit.amount, amount); + assert!(!metadata.withdraw_requests.is_empty()); + let request = metadata.withdraw_requests.first().unwrap(); + assert_eq!(request.asset_id, asset_id); + assert_eq!(request.amount, amount); // Check event System::assert_last_event(RuntimeEvent::MultiAssetDelegation( @@ -494,6 +521,7 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { RuntimeOrigin::signed(who.clone()), asset_id, amount, + None, None )); @@ -507,3 +535,142 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { ); }); } + +#[test] +fn test_deposit_over_cap_should_fail() { + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator = account("delegator", 0, SEED); + let amount = Balance::MAX; // Try to deposit maximum possible amount + + // Set a reasonable cap + let cap = 1_000_000; + assert_ok!(MultiAssetDelegation::set_deposit_cap( + RuntimeOrigin::root(), + asset_id.clone(), + cap + )); + + // Attempt to deposit over cap should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::DepositExceedsMaximum + ); + + // Verify deposit at cap succeeds + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + cap + )); + + // Additional deposit that would exceed cap should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + 1 + ), + Error::::DepositExceedsMaximum + ); + }); +} + +#[test] +fn test_deposit_with_invalid_lock_multiplier() { + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator = account("delegator", 0, SEED); + let amount = 1_000; + + // Set an invalid lock multiplier (too high) + let invalid_multiplier = u32::MAX; + assert_ok!(MultiAssetDelegation::set_lock_multiplier( + RuntimeOrigin::root(), + asset_id.clone(), + invalid_multiplier + )); + + // Deposit with extreme lock multiplier should fail due to overflow + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::ArithmeticError + ); + + // Set zero lock multiplier + assert_ok!(MultiAssetDelegation::set_lock_multiplier( + RuntimeOrigin::root(), + asset_id.clone(), + 0 + )); + + // Deposit with zero lock multiplier should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::InvalidLockMultiplier + ); + }); +} + +#[test] +fn test_deposit_with_multiple_delegators_at_cap() { + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator1 = account("delegator1", 0, SEED); + let delegator2 = account("delegator2", 1, SEED); + + // Set a cap that allows multiple deposits + let cap = 2_000; + assert_ok!(MultiAssetDelegation::set_deposit_cap( + RuntimeOrigin::root(), + asset_id.clone(), + cap + )); + + // First delegator deposits half the cap + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id.clone(), + cap / 2 + )); + + // Second delegator tries to deposit more than remaining cap + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator2.clone()), + asset_id.clone(), + (cap / 2) + 1 + ), + Error::::DepositExceedsMaximum + ); + + // Second delegator deposits exactly remaining cap + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator2.clone()), + asset_id.clone(), + cap / 2 + )); + + // Any further deposits should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id.clone(), + 1 + ), + Error::::DepositExceedsMaximum + ); + }); +} diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 79bb2291..02d8720f 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -638,6 +638,7 @@ fn slash_operator_success() { RuntimeOrigin::signed(Bob.to_account_id()), asset_id, delegator_stake, + None, None )); @@ -735,6 +736,7 @@ fn slash_delegator_fixed_blueprint_not_selected() { RuntimeOrigin::signed(Bob.to_account_id()), Asset::Custom(1), 5_000, + None, None )); diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index c79d7a80..0a5c4564 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -51,7 +51,6 @@ fn handle_round_change_should_work() { asset_id, amount, Default::default(), - None )); assert_ok!(Pallet::::handle_round_change()); @@ -108,7 +107,6 @@ fn handle_round_change_with_unstake_should_work() { asset_id, amount1, Default::default(), - None )); assert_ok!(MultiAssetDelegation::deposit( @@ -123,7 +121,6 @@ fn handle_round_change_with_unstake_should_work() { asset_id, amount2, Default::default(), - None )); // Delegator1 schedules unstake diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index c3406779..8d7b0111 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -435,3 +435,380 @@ fn test_rewards_manager_implementation() { assert_eq!(service, 75u128.into()); // 50 + 25 }); } + +#[test] +fn test_update_asset_rewards_should_fail_for_non_root() { + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + let rewards = 1_000; + + // Act & Assert + assert_noop!( + Rewards::update_asset_rewards(RuntimeOrigin::signed(who), asset_id, rewards), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn test_update_asset_apy_should_fail_for_non_root() { + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + let apy = 500; // 5% + + // Act & Assert + assert_noop!( + Rewards::update_asset_apy(RuntimeOrigin::signed(who), asset_id, apy), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn test_reward_score_calculation_with_zero_values() { + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + + // Test with zero stake + assert_eq!( + Rewards::calculate_reward_score(0, 1000, 500), + 0, + "Reward score should be 0 with zero stake" + ); + + // Test with zero rewards + assert_eq!( + Rewards::calculate_reward_score(1000, 0, 500), + 0, + "Reward score should be 0 with zero rewards" + ); + + // Test with zero APY + assert_eq!( + Rewards::calculate_reward_score(1000, 1000, 0), + 0, + "Reward score should be 0 with zero APY" + ); + }); +} + +#[test] +fn test_reward_score_calculation_with_large_values() { + new_test_ext().execute_with(|| { + // Test with maximum possible values + let max_balance = u128::MAX; + let large_apy = 10_000; // 100% + + // Should not overflow + let score = Rewards::calculate_reward_score(max_balance, max_balance, large_apy); + assert!( + score > 0, + "Reward score should not overflow with large values" + ); + }); +} + +#[test] +fn test_rewards_should_fail_with_overflow() { + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + + // Try to set rewards to maximum value + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + u128::MAX + )); + + // Try to set APY to maximum value - this should cause overflow in calculations + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + u32::MAX + )); + + // Attempting to calculate reward score with max values should return 0 to prevent overflow + let score = Rewards::calculate_reward_score(u128::MAX, u128::MAX, u32::MAX); + assert_eq!(score, 0, "Should handle potential overflow gracefully"); + }); +} + +#[test] +fn test_rewards_with_invalid_asset() { + new_test_ext().execute_with(|| { + let invalid_asset = Asset::Custom(u32::MAX); + let rewards = 1_000; + let apy = 500; + + // Should succeed but have no effect since asset doesn't exist + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + invalid_asset.clone(), + rewards + )); + + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + invalid_asset.clone(), + apy + )); + + // Verify no rewards are available for invalid asset + assert_eq!(Rewards::asset_rewards(invalid_asset.clone()), 0); + assert_eq!(Rewards::asset_apy(invalid_asset.clone()), 0); + }); +} + +#[test] +fn test_rewards_with_zero_stake() { + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let rewards = 1_000; + let apy = 500; + + // Set up rewards and APY + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + rewards + )); + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + apy + )); + + // Calculate rewards for zero stake + let reward_score = Rewards::calculate_reward_score(0, rewards, apy); + assert_eq!(reward_score, 0, "Zero stake should result in zero rewards"); + + // Verify total rewards score is zero when no stakes exist + let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); + assert_eq!(total_score, 0, "Total score should be zero when no stakes exist"); + }); +} + +#[test] +fn test_rewards_with_extreme_apy_values() { + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let stake = 1_000; + let rewards = 1_000; + + // Test extremely high APY (10000% = 100x) + let extreme_apy = 1_000_000; // 10000% + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + extreme_apy + )); + + let score = Rewards::calculate_reward_score(stake, rewards, extreme_apy); + assert!(score > 0, "Should handle extreme APY values"); + assert!(score > rewards, "High APY should result in higher rewards"); + + // Test with minimum possible APY + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + 1 + )); + + let min_score = Rewards::calculate_reward_score(stake, rewards, 1); + assert!(min_score < score, "Minimum APY should result in lower rewards"); + }); +} + +#[test] +fn test_rewards_accumulation() { + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let initial_rewards = 1_000; + let additional_rewards = 500; + + // Set initial rewards + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + initial_rewards + )); + + // Try to add more rewards - should replace, not accumulate + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + additional_rewards + )); + + assert_eq!( + Rewards::asset_rewards(asset_id.clone()), + additional_rewards, + "Rewards should be replaced, not accumulated" + ); + }); +} + +#[test] +fn test_rewards_with_multiple_assets() { + new_test_ext().execute_with(|| { + let asset1 = Asset::Custom(1); + let asset2 = Asset::Custom(2); + let rewards1 = 1_000; + let rewards2 = 2_000; + let apy1 = 500; + let apy2 = 1_000; + + // Set different rewards and APY for different assets + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset1.clone(), + rewards1 + )); + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset2.clone(), + rewards2 + )); + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset1.clone(), + apy1 + )); + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset2.clone(), + apy2 + )); + + // Verify each asset maintains its own rewards and APY + assert_eq!(Rewards::asset_rewards(asset1.clone()), rewards1); + assert_eq!(Rewards::asset_rewards(asset2.clone()), rewards2); + assert_eq!(Rewards::asset_apy(asset1.clone()), apy1); + assert_eq!(Rewards::asset_apy(asset2.clone()), apy2); + + // Verify reward scores are calculated independently + let stake = 1_000; + let score1 = Rewards::calculate_reward_score(stake, rewards1, apy1); + let score2 = Rewards::calculate_reward_score(stake, rewards2, apy2); + assert_ne!(score1, score2, "Different assets should have different reward scores"); + }); +} + +#[test] +fn test_update_asset_rewards_multiple_times() { + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let initial_rewards = 1_000; + let updated_rewards = 2_000; + + // Act - Update rewards multiple times + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + initial_rewards + )); + + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + updated_rewards + )); + + // Assert + assert_eq!( + Rewards::asset_rewards(asset_id), + updated_rewards, + "Asset rewards should be updated to latest value" + ); + }); +} + +#[test] +fn test_update_asset_apy_multiple_times() { + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let initial_apy = 500; // 5% + let updated_apy = 1_000; // 10% + + // Act - Update APY multiple times + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + initial_apy + )); + + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + updated_apy + )); + + // Assert + assert_eq!( + Rewards::asset_apy(asset_id), + updated_apy, + "Asset APY should be updated to latest value" + ); + }); +} + +#[test] +fn test_reward_distribution_with_zero_total_score() { + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let rewards = 1_000; + let apy = 500; // 5% + + // Update rewards and APY + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + rewards + )); + assert_ok!(Rewards::update_asset_apy( + RuntimeOrigin::root(), + asset_id.clone(), + apy + )); + + // With no stakes, total score should be 0 + let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); + assert_eq!(total_score, 0, "Total score should be 0 with no stakes"); + }); +} + +#[test] +fn test_reward_score_calculation_with_different_apy_ranges() { + new_test_ext().execute_with(|| { + let stake = 1_000; + let rewards = 1_000; + + // Test with different APY ranges + let apys = vec![ + 0, // 0% + 100, // 1% + 500, // 5% + 1_000, // 10% + 5_000, // 50% + 10_000, // 100% + ]; + + for apy in apys { + let score = Rewards::calculate_reward_score(stake, rewards, apy); + assert!( + score >= 0, + "Reward score should be non-negative for APY {}", + apy + ); + } + }); +} From 839a23f45b3388c7f15cd0588aee8982915ecf00 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:50:09 +0530 Subject: [PATCH 50/63] cleanup --- .../src/tests/delegate.rs | 2 +- .../src/tests/deposit.rs | 254 ++++---- pallets/rewards/src/tests.rs | 579 ++++++++---------- 3 files changed, 386 insertions(+), 449 deletions(-) diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 04cb2af6..7f60ee2f 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -550,4 +550,4 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { assert_eq!(updated_operator_delegation.amount, amount + additional_amount); assert_eq!(updated_operator_delegation.asset_id, asset_id); }); -} \ No newline at end of file +} diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index bb8a8062..33c35aab 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -538,139 +538,139 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { #[test] fn test_deposit_over_cap_should_fail() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator = account("delegator", 0, SEED); - let amount = Balance::MAX; // Try to deposit maximum possible amount - - // Set a reasonable cap - let cap = 1_000_000; - assert_ok!(MultiAssetDelegation::set_deposit_cap( - RuntimeOrigin::root(), - asset_id.clone(), - cap - )); - - // Attempt to deposit over cap should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::DepositExceedsMaximum - ); - - // Verify deposit at cap succeeds - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - cap - )); - - // Additional deposit that would exceed cap should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - 1 - ), - Error::::DepositExceedsMaximum - ); - }); + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator = account("delegator", 0, SEED); + let amount = Balance::MAX; // Try to deposit maximum possible amount + + // Set a reasonable cap + let cap = 1_000_000; + assert_ok!(MultiAssetDelegation::set_deposit_cap( + RuntimeOrigin::root(), + asset_id.clone(), + cap + )); + + // Attempt to deposit over cap should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::DepositExceedsMaximum + ); + + // Verify deposit at cap succeeds + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + cap + )); + + // Additional deposit that would exceed cap should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + 1 + ), + Error::::DepositExceedsMaximum + ); + }); } #[test] fn test_deposit_with_invalid_lock_multiplier() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator = account("delegator", 0, SEED); - let amount = 1_000; - - // Set an invalid lock multiplier (too high) - let invalid_multiplier = u32::MAX; - assert_ok!(MultiAssetDelegation::set_lock_multiplier( - RuntimeOrigin::root(), - asset_id.clone(), - invalid_multiplier - )); - - // Deposit with extreme lock multiplier should fail due to overflow - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::ArithmeticError - ); - - // Set zero lock multiplier - assert_ok!(MultiAssetDelegation::set_lock_multiplier( - RuntimeOrigin::root(), - asset_id.clone(), - 0 - )); - - // Deposit with zero lock multiplier should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::InvalidLockMultiplier - ); - }); + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator = account("delegator", 0, SEED); + let amount = 1_000; + + // Set an invalid lock multiplier (too high) + let invalid_multiplier = u32::MAX; + assert_ok!(MultiAssetDelegation::set_lock_multiplier( + RuntimeOrigin::root(), + asset_id.clone(), + invalid_multiplier + )); + + // Deposit with extreme lock multiplier should fail due to overflow + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::ArithmeticError + ); + + // Set zero lock multiplier + assert_ok!(MultiAssetDelegation::set_lock_multiplier( + RuntimeOrigin::root(), + asset_id.clone(), + 0 + )); + + // Deposit with zero lock multiplier should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator.clone()), + asset_id.clone(), + amount + ), + Error::::InvalidLockMultiplier + ); + }); } #[test] fn test_deposit_with_multiple_delegators_at_cap() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator1 = account("delegator1", 0, SEED); - let delegator2 = account("delegator2", 1, SEED); - - // Set a cap that allows multiple deposits - let cap = 2_000; - assert_ok!(MultiAssetDelegation::set_deposit_cap( - RuntimeOrigin::root(), - asset_id.clone(), - cap - )); - - // First delegator deposits half the cap - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1.clone()), - asset_id.clone(), - cap / 2 - )); - - // Second delegator tries to deposit more than remaining cap - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2.clone()), - asset_id.clone(), - (cap / 2) + 1 - ), - Error::::DepositExceedsMaximum - ); - - // Second delegator deposits exactly remaining cap - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2.clone()), - asset_id.clone(), - cap / 2 - )); - - // Any further deposits should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1.clone()), - asset_id.clone(), - 1 - ), - Error::::DepositExceedsMaximum - ); - }); + ExtBuilder::default().build().execute_with(|| { + let asset_id = Asset::Custom(1); + let delegator1 = account("delegator1", 0, SEED); + let delegator2 = account("delegator2", 1, SEED); + + // Set a cap that allows multiple deposits + let cap = 2_000; + assert_ok!(MultiAssetDelegation::set_deposit_cap( + RuntimeOrigin::root(), + asset_id.clone(), + cap + )); + + // First delegator deposits half the cap + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id.clone(), + cap / 2 + )); + + // Second delegator tries to deposit more than remaining cap + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator2.clone()), + asset_id.clone(), + (cap / 2) + 1 + ), + Error::::DepositExceedsMaximum + ); + + // Second delegator deposits exactly remaining cap + assert_ok!(MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator2.clone()), + asset_id.clone(), + cap / 2 + )); + + // Any further deposits should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id.clone(), + 1 + ), + Error::::DepositExceedsMaximum + ); + }); } diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 8d7b0111..b4854938 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -438,377 +438,314 @@ fn test_rewards_manager_implementation() { #[test] fn test_update_asset_rewards_should_fail_for_non_root() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - let rewards = 1_000; - - // Act & Assert - assert_noop!( - Rewards::update_asset_rewards(RuntimeOrigin::signed(who), asset_id, rewards), - DispatchError::BadOrigin - ); - }); + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + let rewards = 1_000; + + // Act & Assert + assert_noop!( + Rewards::update_asset_rewards(RuntimeOrigin::signed(who), asset_id, rewards), + DispatchError::BadOrigin + ); + }); } #[test] fn test_update_asset_apy_should_fail_for_non_root() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - let apy = 500; // 5% - - // Act & Assert - assert_noop!( - Rewards::update_asset_apy(RuntimeOrigin::signed(who), asset_id, apy), - DispatchError::BadOrigin - ); - }); + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + let apy = 500; // 5% + + // Act & Assert + assert_noop!( + Rewards::update_asset_apy(RuntimeOrigin::signed(who), asset_id, apy), + DispatchError::BadOrigin + ); + }); } #[test] fn test_reward_score_calculation_with_zero_values() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - - // Test with zero stake - assert_eq!( - Rewards::calculate_reward_score(0, 1000, 500), - 0, - "Reward score should be 0 with zero stake" - ); - - // Test with zero rewards - assert_eq!( - Rewards::calculate_reward_score(1000, 0, 500), - 0, - "Reward score should be 0 with zero rewards" - ); - - // Test with zero APY - assert_eq!( - Rewards::calculate_reward_score(1000, 1000, 0), - 0, - "Reward score should be 0 with zero APY" - ); - }); + new_test_ext().execute_with(|| { + // Arrange + let who = AccountId::from(Bob); + let asset_id = Asset::Custom(1); + + // Test with zero stake + assert_eq!( + Rewards::calculate_reward_score(0, 1000, 500), + 0, + "Reward score should be 0 with zero stake" + ); + + // Test with zero rewards + assert_eq!( + Rewards::calculate_reward_score(1000, 0, 500), + 0, + "Reward score should be 0 with zero rewards" + ); + + // Test with zero APY + assert_eq!( + Rewards::calculate_reward_score(1000, 1000, 0), + 0, + "Reward score should be 0 with zero APY" + ); + }); } #[test] fn test_reward_score_calculation_with_large_values() { - new_test_ext().execute_with(|| { - // Test with maximum possible values - let max_balance = u128::MAX; - let large_apy = 10_000; // 100% - - // Should not overflow - let score = Rewards::calculate_reward_score(max_balance, max_balance, large_apy); - assert!( - score > 0, - "Reward score should not overflow with large values" - ); - }); + new_test_ext().execute_with(|| { + // Test with maximum possible values + let max_balance = u128::MAX; + let large_apy = 10_000; // 100% + + // Should not overflow + let score = Rewards::calculate_reward_score(max_balance, max_balance, large_apy); + assert!(score > 0, "Reward score should not overflow with large values"); + }); } #[test] fn test_rewards_should_fail_with_overflow() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - - // Try to set rewards to maximum value - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - u128::MAX - )); - - // Try to set APY to maximum value - this should cause overflow in calculations - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - u32::MAX - )); - - // Attempting to calculate reward score with max values should return 0 to prevent overflow - let score = Rewards::calculate_reward_score(u128::MAX, u128::MAX, u32::MAX); - assert_eq!(score, 0, "Should handle potential overflow gracefully"); - }); + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + + // Try to set rewards to maximum value + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + u128::MAX + )); + + // Try to set APY to maximum value - this should cause overflow in calculations + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), u32::MAX)); + + // Attempting to calculate reward score with max values should return 0 to prevent overflow + let score = Rewards::calculate_reward_score(u128::MAX, u128::MAX, u32::MAX); + assert_eq!(score, 0, "Should handle potential overflow gracefully"); + }); } #[test] fn test_rewards_with_invalid_asset() { - new_test_ext().execute_with(|| { - let invalid_asset = Asset::Custom(u32::MAX); - let rewards = 1_000; - let apy = 500; - - // Should succeed but have no effect since asset doesn't exist - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - invalid_asset.clone(), - rewards - )); - - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - invalid_asset.clone(), - apy - )); - - // Verify no rewards are available for invalid asset - assert_eq!(Rewards::asset_rewards(invalid_asset.clone()), 0); - assert_eq!(Rewards::asset_apy(invalid_asset.clone()), 0); - }); + new_test_ext().execute_with(|| { + let invalid_asset = Asset::Custom(u32::MAX); + let rewards = 1_000; + let apy = 500; + + // Should succeed but have no effect since asset doesn't exist + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + invalid_asset.clone(), + rewards + )); + + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), invalid_asset.clone(), apy)); + + // Verify no rewards are available for invalid asset + assert_eq!(Rewards::asset_rewards(invalid_asset.clone()), 0); + assert_eq!(Rewards::asset_apy(invalid_asset.clone()), 0); + }); } #[test] fn test_rewards_with_zero_stake() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let rewards = 1_000; - let apy = 500; - - // Set up rewards and APY - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - rewards - )); - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - apy - )); - - // Calculate rewards for zero stake - let reward_score = Rewards::calculate_reward_score(0, rewards, apy); - assert_eq!(reward_score, 0, "Zero stake should result in zero rewards"); - - // Verify total rewards score is zero when no stakes exist - let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); - assert_eq!(total_score, 0, "Total score should be zero when no stakes exist"); - }); + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let rewards = 1_000; + let apy = 500; + + // Set up rewards and APY + assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset_id.clone(), rewards)); + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), apy)); + + // Calculate rewards for zero stake + let reward_score = Rewards::calculate_reward_score(0, rewards, apy); + assert_eq!(reward_score, 0, "Zero stake should result in zero rewards"); + + // Verify total rewards score is zero when no stakes exist + let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); + assert_eq!(total_score, 0, "Total score should be zero when no stakes exist"); + }); } #[test] fn test_rewards_with_extreme_apy_values() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let stake = 1_000; - let rewards = 1_000; - - // Test extremely high APY (10000% = 100x) - let extreme_apy = 1_000_000; // 10000% - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - extreme_apy - )); - - let score = Rewards::calculate_reward_score(stake, rewards, extreme_apy); - assert!(score > 0, "Should handle extreme APY values"); - assert!(score > rewards, "High APY should result in higher rewards"); - - // Test with minimum possible APY - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - 1 - )); - - let min_score = Rewards::calculate_reward_score(stake, rewards, 1); - assert!(min_score < score, "Minimum APY should result in lower rewards"); - }); + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let stake = 1_000; + let rewards = 1_000; + + // Test extremely high APY (10000% = 100x) + let extreme_apy = 1_000_000; // 10000% + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), extreme_apy)); + + let score = Rewards::calculate_reward_score(stake, rewards, extreme_apy); + assert!(score > 0, "Should handle extreme APY values"); + assert!(score > rewards, "High APY should result in higher rewards"); + + // Test with minimum possible APY + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), 1)); + + let min_score = Rewards::calculate_reward_score(stake, rewards, 1); + assert!(min_score < score, "Minimum APY should result in lower rewards"); + }); } #[test] fn test_rewards_accumulation() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let initial_rewards = 1_000; - let additional_rewards = 500; - - // Set initial rewards - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - initial_rewards - )); - - // Try to add more rewards - should replace, not accumulate - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - additional_rewards - )); - - assert_eq!( - Rewards::asset_rewards(asset_id.clone()), - additional_rewards, - "Rewards should be replaced, not accumulated" - ); - }); + new_test_ext().execute_with(|| { + let asset_id = Asset::Custom(1); + let initial_rewards = 1_000; + let additional_rewards = 500; + + // Set initial rewards + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + initial_rewards + )); + + // Try to add more rewards - should replace, not accumulate + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + additional_rewards + )); + + assert_eq!( + Rewards::asset_rewards(asset_id.clone()), + additional_rewards, + "Rewards should be replaced, not accumulated" + ); + }); } #[test] fn test_rewards_with_multiple_assets() { - new_test_ext().execute_with(|| { - let asset1 = Asset::Custom(1); - let asset2 = Asset::Custom(2); - let rewards1 = 1_000; - let rewards2 = 2_000; - let apy1 = 500; - let apy2 = 1_000; - - // Set different rewards and APY for different assets - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset1.clone(), - rewards1 - )); - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset2.clone(), - rewards2 - )); - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset1.clone(), - apy1 - )); - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset2.clone(), - apy2 - )); - - // Verify each asset maintains its own rewards and APY - assert_eq!(Rewards::asset_rewards(asset1.clone()), rewards1); - assert_eq!(Rewards::asset_rewards(asset2.clone()), rewards2); - assert_eq!(Rewards::asset_apy(asset1.clone()), apy1); - assert_eq!(Rewards::asset_apy(asset2.clone()), apy2); - - // Verify reward scores are calculated independently - let stake = 1_000; - let score1 = Rewards::calculate_reward_score(stake, rewards1, apy1); - let score2 = Rewards::calculate_reward_score(stake, rewards2, apy2); - assert_ne!(score1, score2, "Different assets should have different reward scores"); - }); + new_test_ext().execute_with(|| { + let asset1 = Asset::Custom(1); + let asset2 = Asset::Custom(2); + let rewards1 = 1_000; + let rewards2 = 2_000; + let apy1 = 500; + let apy2 = 1_000; + + // Set different rewards and APY for different assets + assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset1.clone(), rewards1)); + assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset2.clone(), rewards2)); + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset1.clone(), apy1)); + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset2.clone(), apy2)); + + // Verify each asset maintains its own rewards and APY + assert_eq!(Rewards::asset_rewards(asset1.clone()), rewards1); + assert_eq!(Rewards::asset_rewards(asset2.clone()), rewards2); + assert_eq!(Rewards::asset_apy(asset1.clone()), apy1); + assert_eq!(Rewards::asset_apy(asset2.clone()), apy2); + + // Verify reward scores are calculated independently + let stake = 1_000; + let score1 = Rewards::calculate_reward_score(stake, rewards1, apy1); + let score2 = Rewards::calculate_reward_score(stake, rewards2, apy2); + assert_ne!(score1, score2, "Different assets should have different reward scores"); + }); } #[test] fn test_update_asset_rewards_multiple_times() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let initial_rewards = 1_000; - let updated_rewards = 2_000; - - // Act - Update rewards multiple times - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - initial_rewards - )); - - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - updated_rewards - )); - - // Assert - assert_eq!( - Rewards::asset_rewards(asset_id), - updated_rewards, - "Asset rewards should be updated to latest value" - ); - }); + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let initial_rewards = 1_000; + let updated_rewards = 2_000; + + // Act - Update rewards multiple times + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + initial_rewards + )); + + assert_ok!(Rewards::update_asset_rewards( + RuntimeOrigin::root(), + asset_id.clone(), + updated_rewards + )); + + // Assert + assert_eq!( + Rewards::asset_rewards(asset_id), + updated_rewards, + "Asset rewards should be updated to latest value" + ); + }); } #[test] fn test_update_asset_apy_multiple_times() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let initial_apy = 500; // 5% - let updated_apy = 1_000; // 10% - - // Act - Update APY multiple times - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - initial_apy - )); - - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - updated_apy - )); - - // Assert - assert_eq!( - Rewards::asset_apy(asset_id), - updated_apy, - "Asset APY should be updated to latest value" - ); - }); + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let initial_apy = 500; // 5% + let updated_apy = 1_000; // 10% + + // Act - Update APY multiple times + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), initial_apy)); + + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), updated_apy)); + + // Assert + assert_eq!( + Rewards::asset_apy(asset_id), + updated_apy, + "Asset APY should be updated to latest value" + ); + }); } #[test] fn test_reward_distribution_with_zero_total_score() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let rewards = 1_000; - let apy = 500; // 5% - - // Update rewards and APY - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - rewards - )); - assert_ok!(Rewards::update_asset_apy( - RuntimeOrigin::root(), - asset_id.clone(), - apy - )); - - // With no stakes, total score should be 0 - let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); - assert_eq!(total_score, 0, "Total score should be 0 with no stakes"); - }); + new_test_ext().execute_with(|| { + // Arrange + let asset_id = Asset::Custom(1); + let rewards = 1_000; + let apy = 500; // 5% + + // Update rewards and APY + assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset_id.clone(), rewards)); + assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), apy)); + + // With no stakes, total score should be 0 + let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); + assert_eq!(total_score, 0, "Total score should be 0 with no stakes"); + }); } #[test] fn test_reward_score_calculation_with_different_apy_ranges() { - new_test_ext().execute_with(|| { - let stake = 1_000; - let rewards = 1_000; - - // Test with different APY ranges - let apys = vec![ - 0, // 0% - 100, // 1% - 500, // 5% - 1_000, // 10% - 5_000, // 50% - 10_000, // 100% - ]; - - for apy in apys { - let score = Rewards::calculate_reward_score(stake, rewards, apy); - assert!( - score >= 0, - "Reward score should be non-negative for APY {}", - apy - ); - } - }); + new_test_ext().execute_with(|| { + let stake = 1_000; + let rewards = 1_000; + + // Test with different APY ranges + let apys = vec![ + 0, // 0% + 100, // 1% + 500, // 5% + 1_000, // 10% + 5_000, // 50% + 10_000, // 100% + ]; + + for apy in apys { + let score = Rewards::calculate_reward_score(stake, rewards, apy); + assert!(score >= 0, "Reward score should be non-negative for APY {}", apy); + } + }); } From b19caef0f702f1b0542c2624c7c009dac97d73ed Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:09:55 +0530 Subject: [PATCH 51/63] update tests and benchmarks --- precompiles/rewards/Rewards.sol | 151 +++---- precompiles/rewards/fuzzer/call.rs | 656 ++++++++--------------------- 2 files changed, 240 insertions(+), 567 deletions(-) diff --git a/precompiles/rewards/Rewards.sol b/precompiles/rewards/Rewards.sol index 7bdd2f9e..624865a3 100644 --- a/precompiles/rewards/Rewards.sol +++ b/precompiles/rewards/Rewards.sol @@ -1,93 +1,72 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @dev The MultiAssetDelegation contract's address. -address constant MULTI_ASSET_DELEGATION = 0x0000000000000000000000000000000000000822; +/// @dev The Rewards contract's address. +address constant REWARDS = 0x0000000000000000000000000000000000000823; -/// @dev The MultiAssetDelegation contract's instance. -MultiAssetDelegation constant MULTI_ASSET_DELEGATION_CONTRACT = MultiAssetDelegation(MULTI_ASSET_DELEGATION); +/// @dev The Rewards contract's instance. +Rewards constant REWARDS_CONTRACT = Rewards(REWARDS); /// @author The Tangle Team -/// @title Pallet MultiAssetDelegation Interface -/// @title The interface through which solidity contracts will interact with the MultiAssetDelegation pallet -/// @custom:address 0x0000000000000000000000000000000000000822 -interface MultiAssetDelegation { - /// @dev Join as an operator with a bond amount. - /// @param bondAmount The amount to bond as an operator. - function joinOperators(uint256 bondAmount) external returns (uint8); - - /// @dev Schedule to leave as an operator. - function scheduleLeaveOperators() external returns (uint8); - - /// @dev Cancel the scheduled leave as an operator. - function cancelLeaveOperators() external returns (uint8); - - /// @dev Execute the leave as an operator. - function executeLeaveOperators() external returns (uint8); - - /// @dev Bond more as an operator. - /// @param additionalBond The additional amount to bond. - function operatorBondMore(uint256 additionalBond) external returns (uint8); - - /// @dev Schedule to unstake as an operator. - /// @param unstakeAmount The amount to unstake. - function scheduleOperatorUnstake(uint256 unstakeAmount) external returns (uint8); - - /// @dev Execute the unstake as an operator. - function executeOperatorUnstake() external returns (uint8); - - /// @dev Cancel the scheduled unstake as an operator. - function cancelOperatorUnstake() external returns (uint8); - - /// @dev Go offline as an operator. - function goOffline() external returns (uint8); - - /// @dev Go online as an operator. - function goOnline() external returns (uint8); - - /// @dev Deposit an amount of an asset. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to deposit. - function deposit(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); - - /// @dev Schedule a withdrawal of an amount of an asset. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to withdraw. - function scheduleWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); - - /// @dev Execute the scheduled withdrawal. - function executeWithdraw() external returns (uint8); - - /// @dev Cancel the scheduled withdrawal. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to cancel withdrawal. - function cancelWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); - - /// @dev Delegate an amount of an asset to an operator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to delegate. - /// @param blueprintSelection The blueprint selection. - function delegate(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount, uint64[] memory blueprintSelection) external returns (uint8); - - /// @dev Schedule an unstake of an amount of an asset as a delegator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to unstake. - function scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); - - /// @dev Execute the scheduled unstake as a delegator. - function executeDelegatorUnstake() external returns (uint8); - - /// @dev Cancel the scheduled unstake as a delegator. - /// @param operator The address of the operator. - /// @param assetId The ID of the asset (0 for ERC20). - /// @param tokenAddress The address of the ERC20 token (if assetId is 0). - /// @param amount The amount to cancel unstake. - function cancelDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); +/// @title Pallet Rewards Interface +/// @title The interface through which solidity contracts will interact with the Rewards pallet +/// @custom:address 0x0000000000000000000000000000000000000823 +interface Rewards { + /// @notice Updates the rewards for a specific asset + /// @dev Only callable by root/admin + /// @param assetId The ID of the asset + /// @param rewards The new rewards amount + /// @return uint8 Returns 0 on success + function updateAssetRewards(uint256 assetId, uint256 rewards) external returns (uint8); + + /// @notice Updates the APY for a specific asset + /// @dev Only callable by root/admin. APY is capped at 10% + /// @param assetId The ID of the asset + /// @param apy The new APY value (in basis points, e.g. 1000 = 10%) + /// @return uint8 Returns 0 on success + function updateAssetApy(uint256 assetId, uint32 apy) external returns (uint8); + + /// @notice Calculates the reward score for given parameters + /// @param stake The stake amount + /// @param rewards The rewards amount + /// @param apy The APY value + /// @return uint256 The calculated reward score + function calculateRewardScore(uint256 stake, uint256 rewards, uint32 apy) external view returns (uint256); + + /// @notice Calculates the total reward score for an asset + /// @param assetId The ID of the asset + /// @return uint256 The total reward score + function calculateTotalRewardScore(uint256 assetId) external view returns (uint256); + + /// @notice Gets the current rewards for an asset + /// @param assetId The ID of the asset + /// @return uint256 The current rewards amount + function assetRewards(uint256 assetId) external view returns (uint256); + + /// @notice Gets the current APY for an asset + /// @param assetId The ID of the asset + /// @return uint32 The current APY value + function assetApy(uint256 assetId) external view returns (uint32); + + /// @notice Sets incentive APY and cap for a vault + /// @dev Only callable by force origin. APY is capped at 10% + /// @param vaultId The ID of the vault + /// @param apy The APY value (in basis points, max 1000 = 10%) + /// @param cap The cap amount for full APY distribution + /// @return uint8 Returns 0 on success + function setIncentiveApyAndCap(uint256 vaultId, uint32 apy, uint256 cap) external returns (uint8); + + /// @notice Whitelists a blueprint for rewards + /// @dev Only callable by force origin + /// @param blueprintId The ID of the blueprint to whitelist + /// @return uint8 Returns 0 on success + function whitelistBlueprintForRewards(uint64 blueprintId) external returns (uint8); + + /// @notice Manages assets in a vault + /// @dev Only callable by authorized accounts + /// @param vaultId The ID of the vault + /// @param assetId The ID of the asset + /// @param action 0 for Add, 1 for Remove + /// @return uint8 Returns 0 on success + function manageAssetInVault(uint256 vaultId, uint256 assetId, uint8 action) external returns (uint8); } \ No newline at end of file diff --git a/precompiles/rewards/fuzzer/call.rs b/precompiles/rewards/fuzzer/call.rs index 34fe1cb3..7507d2f0 100644 --- a/precompiles/rewards/fuzzer/call.rs +++ b/precompiles/rewards/fuzzer/call.rs @@ -15,525 +15,219 @@ // along with Tangle. If not, see . //! # Running -//! Running this fuzzer can be done with `cargo hfuzz run mad-fuzzer`. `honggfuzz` CLI +//! Running this fuzzer can be done with `cargo hfuzz run rewards-fuzzer`. `honggfuzz` CLI //! options can be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. //! //! # Debugging a panic //! Once a panic is found, it can be debugged with -//! `cargo hfuzz run-debug mad-fuzzer hfuzz_workspace/mad-fuzzer/*.fuzz`. +//! `cargo hfuzz run-debug rewards-fuzzer hfuzz_workspace/rewards-fuzzer/*.fuzz`. use fp_evm::Context; use fp_evm::PrecompileSet; use frame_support::traits::{Currency, Get}; use honggfuzz::fuzz; use pallet_evm::AddressMapping; -use pallet_evm_precompile_multi_asset_delegation::{ - mock::*, mock_evm::PrecompilesValue, MultiAssetDelegationPrecompileCall as MADPrecompileCall, -}; -use pallet_multi_asset_delegation::{ - mock::{Asset, AssetId}, - pallet as mad, - types::*, +use pallet_evm_precompile_rewards::{ + mock::*, mock_evm::PrecompilesValue, RewardsPrecompileCall as RewardsCall, }; +use pallet_rewards::pallet as rewards; use precompile_utils::prelude::*; use precompile_utils::testing::*; use rand::{seq::SliceRandom, Rng}; -use sp_runtime::traits::{Scale, Zero}; +use sp_runtime::traits::{Scale, Zero, One}; +use sp_runtime::Percent; -const MAX_ED_MULTIPLE: Balance = 10_000; -const MIN_ED_MULTIPLE: Balance = 10; +const MAX_APY: u32 = 1000; // 10% in basis points +const MAX_REWARDS: u128 = u128::MAX; +const MAX_VAULT_ID: u128 = 1000; +const MAX_BLUEPRINT_ID: u64 = 1000; -type PCall = MADPrecompileCall; +type PCall = RewardsCall; fn random_address(rng: &mut R) -> Address { - Address(rng.gen::<[u8; 20]>().into()) + Address(rng.gen::<[u8; 20]>().into()) } -/// Grab random accounts. +/// Generate a random signed origin fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, Address) { - let addr = random_address(rng); - let signer = >::into_account_id(addr.0); - (RuntimeOrigin::signed(signer), addr) + let addr = random_address(rng); + let signer = >::into_account_id(addr.0); + (RuntimeOrigin::signed(signer), addr) } -fn random_ed_multiple(rng: &mut R) -> Balance { - let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); - ExistentialDeposit::get() * multiple +/// Generate a random asset ID +fn random_asset(rng: &mut R) -> u128 { + rng.gen_range(1..u128::MAX) } -fn random_asset(rng: &mut R) -> Asset { - let asset_id = rng.gen_range(1..u128::MAX); - let is_evm = rng.gen_bool(0.5); - if is_evm { - let evm_address = rng.gen::<[u8; 20]>().into(); - Asset::Erc20(evm_address) - } else { - Asset::Custom(asset_id) - } +/// Generate a random APY value (max 10%) +fn random_apy(rng: &mut R) -> u32 { + rng.gen_range(1..=MAX_APY) } -fn fund_account(rng: &mut R, address: &Address) { - let target_amount = random_ed_multiple(rng); - let signer = >::into_account_id(address.0); - if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(signer)) { - let _ = Balances::deposit_creating(&signer, top_up); - } - assert!(Balances::free_balance(signer) >= target_amount); +/// Generate random rewards amount +fn random_rewards(rng: &mut R) -> u128 { + rng.gen_range(1..MAX_REWARDS) } -/// Join operators call. -fn join_operators_call(rng: &mut R, who: &Address) -> (PCall, Address) { - let minimum_bond = <::MinOperatorBondAmount as Get>::get(); - let multiplier = rng.gen_range(1..50u64); - let who_account_id = >::into_account_id(who.0); - let _ = Balances::deposit_creating(&who_account_id, minimum_bond.mul(multiplier)); - let bond_amount = minimum_bond.mul(multiplier).into(); - (PCall::join_operators { bond_amount }, *who) +/// Generate a random vault ID +fn random_vault_id(rng: &mut R) -> u128 { + rng.gen_range(1..MAX_VAULT_ID) } -fn random_calls(mut rng: &mut R) -> impl IntoIterator { - let op = PCall::selectors().choose(rng).cloned().unwrap(); - match op { - _ if op == PCall::join_operators_selectors()[0] => { - // join_operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(&mut rng, &who)] - }, - _ if op == PCall::schedule_leave_operators_selectors()[0] => { - // Schedule leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::schedule_leave_operators {}, who)] - }, - _ if op == PCall::cancel_leave_operators_selectors()[0] => { - // Cancel leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::cancel_leave_operators {}, who)] - }, - _ if op == PCall::execute_leave_operators_selectors()[0] => { - // Execute leave operators - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::execute_leave_operators {}, who)] - }, - _ if op == PCall::operator_bond_more_selectors()[0] => { - // Operator bond more - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let additional_bond = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(rng, &who), - (PCall::operator_bond_more { additional_bond }, who), - ] - }, - _ if op == PCall::schedule_operator_unstake_selectors()[0] => { - // Schedule operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let unstake_amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(rng, &who), - (PCall::schedule_operator_unstake { unstake_amount }, who), - ] - }, - _ if op == PCall::execute_operator_unstake_selectors()[0] => { - // Execute operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::execute_operator_unstake {}, who)] - }, - _ if op == PCall::cancel_operator_unstake_selectors()[0] => { - // Cancel operator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::cancel_operator_unstake {}, who)] - }, - _ if op == PCall::go_offline_selectors()[0] => { - // Go offline - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::go_offline {}, who)] - }, - _ if op == PCall::go_online_selectors()[0] => { - // Go online - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![join_operators_call(rng, &who), (PCall::go_online {}, who)] - }, - _ if op == PCall::deposit_selectors()[0] => { - // Deposit - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - vec![(PCall::deposit { asset_id, amount, token_address }, who)] - }, - _ if op == PCall::schedule_withdraw_selectors()[0] => { - // Schedule withdraw - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - vec![(PCall::schedule_withdraw { asset_id, token_address, amount }, who)] - }, - _ if op == PCall::execute_withdraw_selectors()[0] => { - // Execute withdraw - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![(PCall::execute_withdraw {}, who)] - }, - _ if op == PCall::cancel_withdraw_selectors()[0] => { - // Cancel withdraw - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - vec![(PCall::cancel_withdraw { asset_id, amount, token_address }, who)] - }, - _ if op == PCall::delegate_selectors()[0] => { - // Delegate - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (_, operator) = random_signed_origin(&mut rng); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - let blueprint_selection = { - let count = rng.gen_range(1..MaxDelegatorBlueprints::get()); - (0..count).map(|_| rng.gen::()).collect::>() - }; - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::delegate { - operator: operator.0.into(), - asset_id, - token_address, - amount, - blueprint_selection, - }, - who, - ), - ] - }, - _ if op == PCall::schedule_delegator_unstake_selectors()[0] => { - // Schedule delegator unstakes - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (_, operator) = random_signed_origin(&mut rng); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::schedule_delegator_unstake { - operator: operator.0.into(), - asset_id, - token_address, - amount, - }, - who, - ), - ] - }, - _ if op == PCall::execute_delegator_unstake_selectors()[0] => { - // Execute delegator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - vec![(PCall::execute_delegator_unstake {}, who)] - }, - _ if op == PCall::cancel_delegator_unstake_selectors()[0] => { - // Cancel delegator unstake - let who = random_address(&mut rng); - fund_account(&mut rng, &who); - let (_, operator) = random_signed_origin(&mut rng); - let (asset_id, token_address) = match random_asset(&mut rng) { - Asset::Custom(id) => (id.into(), Default::default()), - Asset::Erc20(token) => (0.into(), token.into()), - }; - let amount = random_ed_multiple(&mut rng).into(); - vec![ - join_operators_call(&mut rng, &operator), - ( - PCall::cancel_delegator_unstake { - operator: operator.0.into(), - asset_id, - token_address, - amount, - }, - who, - ), - ] - }, - _ => { - unimplemented!("unknown call name: {}", op) - }, - } +/// Generate a random blueprint ID +fn random_blueprint_id(rng: &mut R) -> u64 { + rng.gen_range(1..MAX_BLUEPRINT_ID) } -fn main() { - sp_tracing::try_init_simple(); - let mut ext = ExtBuilder::default().build(); - let mut block_number = 1; - let to = Precompile1.into(); - loop { - fuzz!(|seed: [u8; 32]| { - use ::rand::{rngs::SmallRng, SeedableRng}; - let mut rng = SmallRng::from_seed(seed); +/// Update asset rewards call +fn update_asset_rewards_call(rng: &mut R) -> (PCall, Address) { + let (origin, who) = random_signed_origin(rng); + let asset_id = random_asset(rng).into(); + let rewards = random_rewards(rng).into(); + (PCall::update_asset_rewards { asset_id, rewards }, who) +} - ext.execute_with(|| { - System::set_block_number(block_number); - for (call, who) in random_calls(&mut rng) { - let mut handle = MockHandle::new( - to, - Context { - address: to, - caller: who.into(), - apparent_value: Default::default(), - }, - ); - let mut handle_clone = MockHandle::new( - to, - Context { - address: to, - caller: who.into(), - apparent_value: Default::default(), - }, - ); - let encoded = call.encode(); - handle.input = encoded.clone(); - let call_clone = PCall::parse_call_data(&mut handle).unwrap(); - handle_clone.input = encoded; - let outcome = PrecompilesValue::get().execute(&mut handle).unwrap(); - sp_tracing::trace!(?who, ?outcome, "fuzzed call"); +/// Update asset APY call +fn update_asset_apy_call(rng: &mut R) -> (PCall, Address) { + let (origin, who) = random_signed_origin(rng); + let asset_id = random_asset(rng).into(); + let apy = random_apy(rng); + (PCall::update_asset_apy { asset_id, apy }, who) +} - // execute sanity checks at a fixed interval, possibly on every block. - if let Ok(out) = outcome { - sp_tracing::info!("running sanity checks.."); - do_sanity_checks(call_clone, who, out); - } - } +/// Set incentive APY and cap call +fn set_incentive_apy_and_cap_call(rng: &mut R) -> (PCall, Address) { + let (origin, who) = random_signed_origin(rng); + let vault_id = random_vault_id(rng).into(); + let apy = random_apy(rng); + let cap = random_rewards(rng).into(); + (PCall::set_incentive_apy_and_cap { vault_id, apy, cap }, who) +} - System::reset_events(); - block_number += 1; - }); - }) - } +/// Whitelist blueprint call +fn whitelist_blueprint_call(rng: &mut R) -> (PCall, Address) { + let (origin, who) = random_signed_origin(rng); + let blueprint_id = random_blueprint_id(rng); + (PCall::whitelist_blueprint_for_rewards { blueprint_id }, who) } -/// Perform sanity checks on the state after a call is executed successfully. -#[allow(unused)] -fn do_sanity_checks(call: PCall, origin: Address, outcome: PrecompileOutput) { - let caller = >::into_account_id(origin.0); - match call { - PCall::join_operators { bond_amount } => { - assert!(mad::Operators::::contains_key(caller), "operator not found"); - assert_eq!( - MultiAssetDelegation::operator_info(caller).unwrap_or_default().stake, - bond_amount.as_u64() - ); - assert!( - Balances::reserved_balance(caller).ge(&bond_amount.as_u64()), - "bond amount not reserved" - ); - }, - PCall::schedule_leave_operators {} => { - assert!(mad::Operators::::contains_key(caller), "operator not found"); - let current_round = mad::CurrentRound::::get(); - let leaving_time = - <::LeaveOperatorsDelay as Get>::get() + current_round; - assert_eq!( - mad::Operators::::get(caller).unwrap_or_default().status, - OperatorStatus::Leaving(leaving_time) - ); - }, - PCall::cancel_leave_operators {} => { - assert_eq!( - mad::Operators::::get(caller).unwrap_or_default().status, - OperatorStatus::Active - ); - }, - PCall::execute_leave_operators {} => { - assert!(!mad::Operators::::contains_key(caller), "operator not removed"); - assert!(Balances::reserved_balance(caller).is_zero(), "bond amount not unreserved"); - }, - PCall::operator_bond_more { additional_bond } => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.stake.ge(&additional_bond.as_u64()), "bond amount not increased"); - assert!( - Balances::reserved_balance(caller).ge(&additional_bond.as_u64()), - "bond amount not reserved" - ); - }, - PCall::schedule_operator_unstake { unstake_amount } => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - let current_round = MultiAssetDelegation::current_round(); - let unstake_request = OperatorBondLessRequest { - amount: unstake_amount.as_u64(), - request_time: current_round, - }; - assert_eq!(info.request, Some(unstake_request), "unstake request not set"); - }, - PCall::execute_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - // reserved balance should be reduced and equal to the stake - assert!( - Balances::reserved_balance(caller).eq(&info.stake), - "reserved balance not equal to stake" - ); - }, - PCall::cancel_operator_unstake {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert!(info.request.is_none(), "unstake request not removed"); - }, - PCall::go_offline {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Inactive, "status not set to inactive"); - }, - PCall::go_online {} => { - let info = MultiAssetDelegation::operator_info(caller).unwrap_or_default(); - assert_eq!(info.status, OperatorStatus::Active, "status not set to active"); - }, - PCall::deposit { asset_id, amount, token_address } => { - let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - match deposit_asset { - Asset::Custom(id) => { - let pallet_balance = - Assets::balance(id, MultiAssetDelegation::pallet_account()); - assert!(pallet_balance.ge(&amount.as_u64()), "pallet balance not enough"); - }, - Asset::Erc20(token) => { - let pallet_balance = MultiAssetDelegation::query_erc20_balance_of( - token, - MultiAssetDelegation::pallet_evm_account(), - ) - .unwrap_or_default() - .0; - assert!(pallet_balance.ge(&amount), "pallet balance not enough"); - }, - }; +/// Manage asset in vault call +fn manage_asset_in_vault_call(rng: &mut R) -> (PCall, Address) { + let (origin, who) = random_signed_origin(rng); + let vault_id = random_vault_id(rng).into(); + let asset_id = random_asset(rng).into(); + let action = rng.gen_range(0..=1); + (PCall::manage_asset_in_vault { vault_id, asset_id, action }, who) +} - assert_eq!( - MultiAssetDelegation::delegators(caller) - .unwrap_or_default() - .calculate_delegation_by_asset(deposit_asset), - amount.as_u64() - ); - }, - PCall::schedule_withdraw { asset_id, amount, token_address } => { - let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - let round = MultiAssetDelegation::current_round(); - assert!( - MultiAssetDelegation::delegators(caller) - .unwrap_or_default() - .get_withdraw_requests() - .contains(&WithdrawRequest { - asset_id: deposit_asset, - amount: amount.as_u64(), - requested_round: round - }), - "withdraw request not found" - ); - }, - PCall::execute_withdraw { .. } => { - assert!( - MultiAssetDelegation::delegators(caller) - .unwrap_or_default() - .get_withdraw_requests() - .is_empty(), - "withdraw requests not removed" - ); - }, - PCall::cancel_withdraw { asset_id, amount, token_address } => { - let round = MultiAssetDelegation::current_round(); +/// Generate random calls for fuzzing +fn random_calls(mut rng: &mut R) -> impl IntoIterator { + let op = PCall::selectors().choose(rng).cloned().unwrap(); + match op { + _ if op == PCall::update_asset_rewards_selectors()[0] => { + vec![update_asset_rewards_call(&mut rng)] + }, + _ if op == PCall::update_asset_apy_selectors()[0] => { + vec![update_asset_apy_call(&mut rng)] + }, + _ if op == PCall::set_incentive_apy_and_cap_selectors()[0] => { + vec![set_incentive_apy_and_cap_call(&mut rng)] + }, + _ if op == PCall::whitelist_blueprint_for_rewards_selectors()[0] => { + vec![whitelist_blueprint_call(&mut rng)] + }, + _ if op == PCall::manage_asset_in_vault_selectors()[0] => { + vec![manage_asset_in_vault_call(&mut rng)] + }, + _ => vec![], + } +} - let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - assert!( - !MultiAssetDelegation::delegators(caller) - .unwrap_or_default() - .get_withdraw_requests() - .contains(&WithdrawRequest { - asset_id: deposit_asset, - amount: amount.as_u64(), - requested_round: round - }), - "withdraw request not removed" - ); - }, - PCall::delegate { operator, asset_id, amount, token_address, .. } => { - let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), amount) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), - }; - let operator_account = AccountId::from(operator.0); - let delegator = MultiAssetDelegation::delegators(caller).unwrap_or_default(); - let operator_info = - MultiAssetDelegation::operator_info(operator_account).unwrap_or_default(); - assert!( - delegator - .calculate_delegation_by_operator(operator_account) - .iter() - .find_map(|x| { - if x.asset_id == deposit_asset { - Some(x.amount) - } else { - None - } - }) - .ge(&Some(amount.as_u64())), - "delegation amount not set" - ); - assert!( - operator_info - .delegations - .iter() - .find_map(|x| { - if x.delegator == caller && x.asset_id == deposit_asset { - Some(x.amount) - } else { - None - } - }) - .ge(&Some(amount.as_u64())), - "delegator not added to operator" - ); - }, - _ => { - // ignore other calls - }, - } +fn main() { + loop { + fuzz!(|data: &[u8]| { + let mut rng = rand::thread_rng(); + let calls = random_calls(&mut rng); + + // Create test externalities + let mut ext = ExtBuilder::default().build(); + ext.execute_with(|| { + let precompiles = PrecompilesValue::get(); + + // Execute each call + for (call, who) in calls { + let input = call.encode(); + let context = Context { + address: Default::default(), + caller: who.0, + apparent_value: Default::default(), + }; + + let info = call.estimate_gas(input.clone(), &mut EvmDataWriter::new(), context); + match info { + Ok((_, estimate)) => { + let mut gasometer = Gasometer::new(estimate); + let outcome = precompiles + .execute(&context.address, &mut gasometer, &context, &input) + .expect("Precompile failed"); + + // Perform sanity checks + do_sanity_checks(call, who, outcome); + }, + Err(e) => { + // Expected errors are ok + println!("Expected error: {:?}", e); + }, + } + } + }); + }); + } +} + +/// Perform sanity checks on the state after a call is executed successfully +fn do_sanity_checks(call: PCall, origin: Address, outcome: PrecompileOutput) { + match call { + PCall::update_asset_rewards { asset_id, rewards } => { + // Check that rewards were updated + assert_eq!(Rewards::asset_rewards(asset_id), rewards); + }, + PCall::update_asset_apy { asset_id, apy } => { + // Check that APY was updated and is within bounds + assert!(apy <= MAX_APY); + assert_eq!(Rewards::asset_apy(asset_id), apy); + }, + PCall::set_incentive_apy_and_cap { vault_id, apy, cap } => { + // Check APY is within bounds + assert!(apy <= MAX_APY); + + // Check config was updated + if let Some(config) = Rewards::reward_config() { + if let Some(vault_config) = config.configs.get(&vault_id) { + assert_eq!(vault_config.apy, Percent::from_parts(apy as u8)); + assert_eq!(vault_config.cap, cap); + } + } + }, + PCall::whitelist_blueprint_for_rewards { blueprint_id } => { + // Check blueprint was whitelisted + if let Some(config) = Rewards::reward_config() { + assert!(config.whitelisted_blueprints.contains(&blueprint_id)); + } + }, + PCall::manage_asset_in_vault { vault_id, asset_id, action } => { + // Check asset was added/removed from vault + if let Some(config) = Rewards::reward_config() { + if let Some(vault_config) = config.configs.get(&vault_id) { + match action { + 0 => assert!(vault_config.assets.contains(&asset_id)), + 1 => assert!(!vault_config.assets.contains(&asset_id)), + _ => panic!("Invalid action"), + } + } + } + }, + _ => {}, + } } From fbf90e077a5b7757c1ccc7fe93d9a337b7ad6b06 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 11:56:24 +0530 Subject: [PATCH 52/63] rearrange flow --- .../multi-asset-delegation/src/functions.rs | 1 - .../src/functions/rewards.rs | 144 -------------- pallets/multi-asset-delegation/src/lib.rs | 138 -------------- .../src/types/delegator.rs | 3 +- pallets/rewards/src/functions.rs | 56 ------ pallets/rewards/src/impls.rs | 26 +-- pallets/rewards/src/lib.rs | 178 ++++++++++++++---- pallets/rewards/src/types.rs | 31 +++ primitives/src/traits/rewards.rs | 100 +++++----- 9 files changed, 229 insertions(+), 448 deletions(-) delete mode 100644 pallets/multi-asset-delegation/src/functions/rewards.rs diff --git a/pallets/multi-asset-delegation/src/functions.rs b/pallets/multi-asset-delegation/src/functions.rs index 9ee9c028..30f79692 100644 --- a/pallets/multi-asset-delegation/src/functions.rs +++ b/pallets/multi-asset-delegation/src/functions.rs @@ -19,5 +19,4 @@ pub mod delegate; pub mod deposit; pub mod evm; pub mod operator; -pub mod rewards; pub mod session_manager; diff --git a/pallets/multi-asset-delegation/src/functions/rewards.rs b/pallets/multi-asset-delegation/src/functions/rewards.rs deleted file mode 100644 index 23288fce..00000000 --- a/pallets/multi-asset-delegation/src/functions/rewards.rs +++ /dev/null @@ -1,144 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use super::*; -use crate::{types::*, Pallet}; -use frame_support::{ensure, pallet_prelude::DispatchResult, traits::Currency}; -use sp_runtime::DispatchError; -use sp_std::vec::Vec; -use tangle_primitives::{services::Asset, RoundIndex}; - -impl Pallet { - #[allow(clippy::type_complexity)] - pub fn distribute_rewards(_round: RoundIndex) -> DispatchResult { - // let mut delegation_info: BTreeMap< - // T::AssetId, - // Vec, T::AssetId>>, - // > = BTreeMap::new(); - - // // Iterate through all operator snapshots for the given round - // // TODO: Could be dangerous with many operators - // for (_, operator_snapshot) in AtStake::::iter_prefix(round) { - // for delegation in &operator_snapshot.delegations { - // delegation_info.entry(delegation.asset_id).or_default().push(delegation.clone()); - // } - // } - - // // Get the reward configuration - // if let Some(reward_config) = RewardConfigStorage::::get() { - // // Distribute rewards for each asset - // for (asset_id, delegations) in delegation_info.iter() { - // // We only reward asset in a reward vault - // if let Some(vault_id) = AssetLookupRewardVaults::::get(asset_id) { - // if let Some(config) = reward_config.configs.get(&vault_id) { - // // Calculate total amount and distribute rewards - // let total_amount: BalanceOf = - // delegations.iter().fold(Zero::zero(), |acc, d| acc + d.amount); - // let cap: BalanceOf = config.cap; - - // if total_amount >= cap { - // // Calculate the total reward based on the APY - // let total_reward = - // Self::calculate_total_reward(config.apy, total_amount)?; - - // for delegation in delegations { - // // Calculate the percentage of the cap that the user is staking - // let staking_percentage = - // delegation.amount.saturating_mul(100u32.into()) / cap; - // // Calculate the reward based on the staking percentage - // let reward = - // total_reward.saturating_mul(staking_percentage) / 100u32.into(); - // // Distribute the reward to the delegator - // Self::distribute_reward_to_delegator( - // &delegation.delegator, - // reward, - // )?; - // } - // } - // } - // } - // } - // } - - Ok(()) - } - - fn _calculate_total_reward( - apy: sp_runtime::Percent, - total_amount: BalanceOf, - ) -> Result, DispatchError> { - let total_reward = apy.mul_floor(total_amount); - Ok(total_reward) - } - - fn _distribute_reward_to_delegator( - delegator: &T::AccountId, - reward: BalanceOf, - ) -> DispatchResult { - // mint rewards to delegator - let _ = T::Currency::deposit_creating(delegator, reward); - Ok(()) - } - - pub fn add_asset_to_vault( - vault_id: &T::VaultId, - asset_id: &Asset, - ) -> DispatchResult { - // Ensure the asset is not already associated with any vault - ensure!( - !AssetLookupRewardVaults::::contains_key(asset_id), - Error::::AssetAlreadyInVault - ); - - // Update RewardVaults storage - RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { - let assets = maybe_assets.get_or_insert_with(Vec::new); - - // Ensure the asset is not already in the vault - ensure!(!assets.contains(asset_id), Error::::AssetAlreadyInVault); - - assets.push(*asset_id); - - Ok(()) - })?; - - // Update AssetLookupRewardVaults storage - AssetLookupRewardVaults::::insert(asset_id, vault_id); - - Ok(()) - } - - pub fn remove_asset_from_vault( - vault_id: &T::VaultId, - asset_id: &Asset, - ) -> DispatchResult { - // Update RewardVaults storage - RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { - let assets = maybe_assets.as_mut().ok_or(Error::::VaultNotFound)?; - - // Ensure the asset is in the vault - ensure!(assets.contains(asset_id), Error::::AssetNotInVault); - - assets.retain(|id| id != asset_id); - - Ok(()) - })?; - - // Update AssetLookupRewardVaults storage - AssetLookupRewardVaults::::remove(asset_id); - - Ok(()) - } -} diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index f152a578..9e609385 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -240,25 +240,6 @@ pub mod pallet { pub type Delegators = StorageMap<_, Blake2_128Concat, T::AccountId, DelegatorMetadataOf>; - #[pallet::storage] - #[pallet::getter(fn reward_vaults)] - /// Storage for the reward vaults - pub type RewardVaults = - StorageMap<_, Blake2_128Concat, T::VaultId, Vec>, OptionQuery>; - - #[pallet::storage] - #[pallet::getter(fn asset_reward_vault_lookup)] - /// Storage for the reward vaults - pub type AssetLookupRewardVaults = - StorageMap<_, Blake2_128Concat, Asset, T::VaultId, OptionQuery>; - - #[pallet::storage] - #[pallet::getter(fn reward_config)] - /// Storage for the reward configuration, which includes APY, cap for assets, and whitelisted - /// blueprints. - pub type RewardConfigStorage = - StorageValue<_, RewardConfig>, OptionQuery>; - /// Events emitted by the pallet. #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -934,125 +915,6 @@ pub mod pallet { Ok(()) } - /// Sets the APY and cap for a specific asset. - /// - /// # Permissions - /// - /// * Must be called by the force origin - /// - /// # Arguments - /// - /// * `origin` - Origin of the call - /// * `vault_id` - ID of the vault - /// * `apy` - Annual percentage yield (max 10%) - /// * `cap` - Required deposit amount for full APY - /// - /// # Errors - /// - /// * [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum - /// * [`Error::CapCannotBeZero`] - Cap amount cannot be zero - #[pallet::call_index(18)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn set_incentive_apy_and_cap( - origin: OriginFor, - vault_id: T::VaultId, - apy: sp_runtime::Percent, - cap: BalanceOf, - ) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; - - ensure!(apy <= sp_runtime::Percent::from_percent(10), Error::::APYExceedsMaximum); - ensure!(!cap.is_zero(), Error::::CapCannotBeZero); - - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); - - config.configs.insert(vault_id, RewardConfigForAssetVault { apy, cap }); - - *maybe_config = Some(config); - }); - - Self::deposit_event(Event::IncentiveAPYAndCapSet { vault_id, apy, cap }); - - Ok(()) - } - - /// Whitelists a blueprint for rewards. - /// - /// # Permissions - /// - /// * Must be called by the force origin - /// - /// # Arguments - /// - /// * `origin` - Origin of the call - /// * `blueprint_id` - ID of blueprint to whitelist - #[pallet::call_index(19)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn whitelist_blueprint_for_rewards( - origin: OriginFor, - blueprint_id: BlueprintId, - ) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; - - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); - - if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { - config.whitelisted_blueprint_ids.push(blueprint_id); - } - - *maybe_config = Some(config); - }); - - Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); - - Ok(()) - } - - /// Manage asset id to vault rewards. - /// - /// # Permissions - /// - /// * Must be signed by an authorized account - /// - /// # Arguments - /// - /// * `origin` - Origin of the call - /// * `vault_id` - ID of the vault - /// * `asset_id` - ID of the asset - /// * `action` - Action to perform (Add/Remove) - /// - /// # Errors - /// - /// * [`Error::AssetAlreadyInVault`] - Asset already exists in vault - /// * [`Error::AssetNotInVault`] - Asset does not exist in vault - #[pallet::call_index(20)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn manage_asset_in_vault( - origin: OriginFor, - vault_id: T::VaultId, - asset_id: Asset, - action: AssetAction, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - match action { - AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, - AssetAction::Remove => Self::remove_asset_from_vault(&vault_id, &asset_id)?, - } - - Self::deposit_event(Event::AssetUpdatedInVault { who, vault_id, asset_id, action }); - - Ok(()) - } - /// Adds a blueprint ID to a delegator's selection. /// /// # Permissions diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index 1d36ea57..cbc97544 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -19,6 +19,7 @@ use frame_support::ensure; use frame_support::{pallet_prelude::Get, BoundedVec}; use sp_runtime::traits::Zero; use sp_std::fmt::Debug; +use sp_std::vec; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, BlueprintId}; @@ -222,7 +223,7 @@ pub struct Deposit> { impl< Balance: Debug + Default + Clone + sp_runtime::Saturating + sp_std::cmp::PartialOrd + From, - BlockNumber: Debug + sp_runtime::Saturating + std::convert::From + sp_std::cmp::PartialOrd, + BlockNumber: Debug + sp_runtime::Saturating + sp_std::convert::From + sp_std::cmp::PartialOrd, MaxLocks: Get, > Deposit { diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 9b6b8bae..7c8f45aa 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -97,59 +97,3 @@ pub fn update_total_deposited( }; >::insert(asset, new_total); } - -#[cfg(test)] -mod tests { - use super::*; - use crate::{mock::*, BoostInfo, UserRewards}; - use frame_support::assert_ok; - use sp_runtime::traits::Zero; - - fn setup_test_asset() { - // Set up WETH with 1% APY and 1000 WETH capacity - assert_ok!(Rewards::whitelist_asset(RuntimeOrigin::root(), Asset::Custom(1))); - AssetApy::::insert(Asset::Custom(1), 100); // 1% = 100 basis points - AssetCapacity::::insert(Asset::Custom(1), 1000u128); - } - - fn create_user_rewards(amount: u128, multiplier: LockMultiplier) -> UserRewardsOf { - UserRewards { - restaking_rewards: Zero::zero(), - service_rewards: Zero::zero(), - boost_rewards: BoostInfo { - amount: amount.saturated_into(), - multiplier, - expiry: Zero::zero(), - }, - } - } - - #[test] - fn test_score_calculation() { - new_test_ext().execute_with(|| { - setup_test_asset(); - - // Test 10 WETH locked for 12 months - let rewards = create_user_rewards(10, LockMultiplier::SixMonths); - let score = calculate_user_score::(Asset::Custom(1), &rewards); - assert_eq!(score, 60); // 10 * 6 months = 60 - }); - } - - #[test] - fn test_apy_distribution() { - new_test_ext().execute_with(|| { - setup_test_asset(); - - // Set up total score and deposits - TotalAssetScore::::insert(Asset::Custom(1), 1000); // Total score of 1000 - TotalDeposited::::insert(Asset::Custom(1), 500); // 500 WETH deposited - - // Test APY calculation for a user with score 60 - let apy = calculate_apy_distribution::(Asset::Custom(1), 60); - - // Expected APY = 1% * (60/1000) * (500/1000) = 0.03% - assert_eq!(apy.deconstruct(), 3); // 0.03% = 3 basis points - }); - } -} diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index 0f4653f7..26456e31 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -24,42 +24,36 @@ use tangle_primitives::{services::Asset, traits::rewards::RewardsManager}; impl RewardsManager, BlockNumberFor> for Pallet { - fn record_delegation_reward( + fn record_deposit( account_id: &T::AccountId, asset: Asset, amount: BalanceOf, - lock_multiplier: u32, + lock_multiplier: Option, ) -> Result<(), &'static str> { Ok(()) } - fn record_service_reward( + fn record_withdrawal( account_id: &T::AccountId, asset: Asset, amount: BalanceOf, ) -> Result<(), &'static str> { - // TODO : Handle service rewards later Ok(()) } - fn query_rewards( - account_id: &T::AccountId, - asset: Asset, - ) -> Result<(BalanceOf, BalanceOf), &'static str> { - todo!() - } - - fn query_delegation_rewards( + fn record_service_reward( account_id: &T::AccountId, asset: Asset, - ) -> Result, &'static str> { - todo!() + amount: BalanceOf, + ) -> Result<(), &'static str> { + // TODO : Handle service rewards later + Ok(()) } - fn query_service_rewards( + fn query_total_deposit( account_id: &T::AccountId, asset: Asset, - ) -> Result, &'static str> { + ) -> Result<(BalanceOf, BalanceOf), &'static str> { todo!() } } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index bb5120eb..0f6a5656 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -86,47 +86,30 @@ pub mod pallet { #[pallet::without_storage_info] pub struct Pallet(_); - /// Stores the user rewards for each user and asset combination - #[pallet::storage] - #[pallet::getter(fn user_rewards)] - pub type UserRewards = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Blake2_128Concat, - Asset, - UserRewardsOf, - ValueQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn asset_rewards)] - pub type AssetRewards = - StorageMap<_, Blake2_128Concat, Asset, u128, ValueQuery>; - - /// Stores the whitelisted assets that can be used for rewards + /// Stores the total score for each asset #[pallet::storage] - #[pallet::getter(fn allowed_reward_assets)] - pub type AllowedRewardAssets = - StorageMap<_, Blake2_128Concat, Asset, bool, ValueQuery>; + #[pallet::getter(fn total_reward_vault_score)] + pub type TotalRewardVaultScore = + StorageMap<_, Blake2_128Concat, T::VaultId, u128, ValueQuery>; - /// Stores the APY percentage for each asset (in basis points, e.g. 100 = 1%) #[pallet::storage] - #[pallet::getter(fn asset_apy)] - pub type AssetApy = - StorageMap<_, Blake2_128Concat, Asset, u32, ValueQuery>; + #[pallet::getter(fn reward_vaults)] + /// Storage for the reward vaults + pub type RewardVaults = + StorageMap<_, Blake2_128Concat, T::VaultId, Vec>, OptionQuery>; - /// Stores the maximum capacity for each asset #[pallet::storage] - #[pallet::getter(fn asset_capacity)] - pub type AssetCapacity = - StorageMap<_, Blake2_128Concat, Asset, BalanceOf, ValueQuery>; + #[pallet::getter(fn asset_reward_vault_lookup)] + /// Storage for the reward vaults + pub type AssetLookupRewardVaults = + StorageMap<_, Blake2_128Concat, Asset, T::VaultId, OptionQuery>; - /// Stores the total score for each asset #[pallet::storage] - #[pallet::getter(fn total_asset_score)] - pub type TotalAssetScore = - StorageMap<_, Blake2_128Concat, Asset, u128, ValueQuery>; + #[pallet::getter(fn reward_config)] + /// Storage for the reward configuration, which includes APY, cap for assets, and whitelisted + /// blueprints. + pub type RewardConfigStorage = + StorageValue<_, RewardConfig>, OptionQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -181,11 +164,7 @@ pub mod pallet { impl Pallet { /// Claim rewards for a specific asset and reward type #[pallet::weight(10_000)] - pub fn claim_rewards( - origin: OriginFor, - asset: Asset, - reward_type: RewardType, - ) -> DispatchResult { + pub fn claim_rewards(origin: OriginFor, asset: Asset) -> DispatchResult { let who = ensure_signed(origin)?; // Ensure the asset is whitelisted @@ -227,7 +206,7 @@ pub mod pallet { }; // Ensure there are rewards to claim - ensure!(!reward_amount.is_zero(), Error::::NoRewardsAvailable); + ensure!(!.is_zero(), Error::::NoRewardsAvailable); // Transfer rewards to user // Note: This assumes the pallet account has sufficient balance @@ -304,6 +283,125 @@ pub mod pallet { Ok(()) } + + /// Sets the APY and cap for a specific asset. + /// + /// # Permissions + /// + /// * Must be called by the force origin + /// + /// # Arguments + /// + /// * `origin` - Origin of the call + /// * `vault_id` - ID of the vault + /// * `apy` - Annual percentage yield (max 10%) + /// * `cap` - Required deposit amount for full APY + /// + /// # Errors + /// + /// * [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum + /// * [`Error::CapCannotBeZero`] - Cap amount cannot be zero + #[pallet::call_index(18)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn set_incentive_apy_and_cap( + origin: OriginFor, + vault_id: T::VaultId, + apy: sp_runtime::Percent, + cap: BalanceOf, + ) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + + ensure!(apy <= sp_runtime::Percent::from_percent(10), Error::::APYExceedsMaximum); + ensure!(!cap.is_zero(), Error::::CapCannotBeZero); + + RewardConfigStorage::::mutate(|maybe_config| { + let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { + configs: BTreeMap::new(), + whitelisted_blueprint_ids: Vec::new(), + }); + + config.configs.insert(vault_id, RewardConfigForAssetVault { apy, cap }); + + *maybe_config = Some(config); + }); + + Self::deposit_event(Event::IncentiveAPYAndCapSet { vault_id, apy, cap }); + + Ok(()) + } + + /// Whitelists a blueprint for rewards. + /// + /// # Permissions + /// + /// * Must be called by the force origin + /// + /// # Arguments + /// + /// * `origin` - Origin of the call + /// * `blueprint_id` - ID of blueprint to whitelist + #[pallet::call_index(19)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn whitelist_blueprint_for_rewards( + origin: OriginFor, + blueprint_id: BlueprintId, + ) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + + RewardConfigStorage::::mutate(|maybe_config| { + let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { + configs: BTreeMap::new(), + whitelisted_blueprint_ids: Vec::new(), + }); + + if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { + config.whitelisted_blueprint_ids.push(blueprint_id); + } + + *maybe_config = Some(config); + }); + + Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); + + Ok(()) + } + + /// Manage asset id to vault rewards. + /// + /// # Permissions + /// + /// * Must be signed by an authorized account + /// + /// # Arguments + /// + /// * `origin` - Origin of the call + /// * `vault_id` - ID of the vault + /// * `asset_id` - ID of the asset + /// * `action` - Action to perform (Add/Remove) + /// + /// # Errors + /// + /// * [`Error::AssetAlreadyInVault`] - Asset already exists in vault + /// * [`Error::AssetNotInVault`] - Asset does not exist in vault + #[pallet::call_index(20)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn manage_asset_in_vault( + origin: OriginFor, + vault_id: T::VaultId, + asset_id: Asset, + action: AssetAction, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + match action { + AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, + AssetAction::Remove => Self::remove_asset_from_vault(&vault_id, &asset_id)?, + } + + Self::deposit_event(Event::AssetUpdatedInVault { who, vault_id, asset_id, action }); + + Ok(()) + } } impl Pallet { diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index b6300e06..dc70ea24 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -14,11 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . +use super::*; use crate::Config; use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; +use sp_runtime::Percent; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::rewards::UserRewards; @@ -33,3 +35,32 @@ pub type UserRewardsOf = UserRewards< pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + +/// Configuration for rewards associated with a specific asset. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct RewardConfigForAssetVault { + // The annual percentage yield (APY) for the asset, represented as a Percent + pub apy: Percent, + // The minimum amount required before the asset can be rewarded. + pub incentive_cap: Balance, + // The maximum amount of asset that can be deposited. + pub deposit_cap: Balance, + // Boost multiplier for this asset, if None boost multiplier is not enabled + pub boost_multiplier: Option, +} + +/// Configuration for rewards in the system. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct RewardConfig { + // A map of asset IDs to their respective reward configurations. + pub configs: BTreeMap>, + // A list of blueprint IDs that are whitelisted for rewards. + pub whitelisted_blueprint_ids: Vec, +} + +/// Asset action for vaults +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub enum AssetAction { + Add, + Remove, +} diff --git a/primitives/src/traits/rewards.rs b/primitives/src/traits/rewards.rs index e7fe182c..7364200b 100644 --- a/primitives/src/traits/rewards.rs +++ b/primitives/src/traits/rewards.rs @@ -20,58 +20,58 @@ use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::Zero; /// Trait for managing rewards in the Tangle network. -/// This trait allows other pallets to record and query rewards. +/// This trait provides functionality to record deposits, withdrawals, and service rewards, +/// as well as query total deposits for accounts. pub trait RewardsManager { - /// Record a delegation deposit reward. - /// This is used by the multi-asset-delegation pallet to record rewards from delegations. + type Error; + + /// Records a deposit for an account with an optional lock multiplier. /// - /// Parameters: - /// - `account_id`: The account receiving the reward - /// - `asset`: The asset being delegated - /// - `amount`: The amount of the reward - /// - `lock_multiplier`: The multiplier for the lock period (e.g., 1 for 1 month, 3 for 3 months) - fn record_delegation_reward( + /// # Parameters + /// * `account_id` - The account making the deposit + /// * `asset` - The asset being deposited + /// * `amount` - The amount being deposited + /// * `lock_multiplier` - Optional multiplier for locked deposits + fn record_deposit( account_id: &AccountId, asset: Asset, amount: Balance, - lock_multiplier: u32, - ) -> Result<(), &'static str>; + lock_multiplier: Option, + ) -> Result<(), Self::Error>; - /// Record a service payment reward. - /// This is used by the services pallet to record rewards from service payments. + /// Records a withdrawal for an account. /// - /// Parameters: - /// - `account_id`: The account receiving the reward - /// - `asset`: The asset used for payment - /// - `amount`: The amount of the reward - fn record_service_reward( + /// # Parameters + /// * `account_id` - The account making the withdrawal + /// * `asset` - The asset being withdrawn + /// * `amount` - The amount being withdrawn + fn record_withdrawal( account_id: &AccountId, asset: Asset, amount: Balance, - ) -> Result<(), &'static str>; + ) -> Result<(), Self::Error>; - /// Query the total rewards for an account and asset. - /// Returns a tuple of (delegation_rewards, service_rewards). + /// Records a service reward for an account. /// - /// Parameters: - /// - `account_id`: The account to query - /// - `asset`: The asset to query - fn query_rewards( - account_id: &AccountId, - asset: Asset, - ) -> Result<(Balance, Balance), &'static str>; - - /// Query only the delegation rewards for an account and asset. - fn query_delegation_rewards( + /// # Parameters + /// * `account_id` - The account receiving the reward + /// * `asset` - The asset being rewarded + /// * `amount` - The reward amount + fn record_service_reward( account_id: &AccountId, asset: Asset, - ) -> Result; + amount: Balance, + ) -> Result<(), Self::Error>; - /// Query only the service rewards for an account and asset. - fn query_service_rewards( + /// Queries the total deposit for an account and asset. + /// + /// # Parameters + /// * `account_id` - The account to query + /// * `asset` - The asset to query + fn query_total_deposit( account_id: &AccountId, asset: Asset, - ) -> Result; + ) -> Result; } impl @@ -79,41 +79,37 @@ impl where Balance: Zero, { - fn record_delegation_reward( + type Error = &'static str; + + fn record_deposit( _account_id: &AccountId, _asset: Asset, _amount: Balance, - _lock_multiplier: u32, - ) -> Result<(), &'static str> { + _lock_multiplier: Option, + ) -> Result<(), Self::Error> { Ok(()) } - fn record_service_reward( + fn record_withdrawal( _account_id: &AccountId, _asset: Asset, _amount: Balance, - ) -> Result<(), &'static str> { + ) -> Result<(), Self::Error> { Ok(()) } - fn query_rewards( - _account_id: &AccountId, - _asset: Asset, - ) -> Result<(Balance, Balance), &'static str> { - Ok((Balance::zero(), Balance::zero())) - } - - fn query_delegation_rewards( + fn record_service_reward( _account_id: &AccountId, _asset: Asset, - ) -> Result { - Ok(Balance::zero()) + _amount: Balance, + ) -> Result<(), Self::Error> { + Ok(()) } - fn query_service_rewards( + fn query_total_deposit( _account_id: &AccountId, _asset: Asset, - ) -> Result { + ) -> Result { Ok(Balance::zero()) } } From 1b5b6c39d3b4879a28c45014f01c87f421547859 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:17:19 +0530 Subject: [PATCH 53/63] refactor control flow --- pallets/multi-asset-delegation/src/lib.rs | 21 -- pallets/multi-asset-delegation/src/traits.rs | 18 +- .../src/types/delegator.rs | 9 +- pallets/rewards/src/functions.rs | 294 ++++++++++++---- pallets/rewards/src/impls.rs | 73 +++- pallets/rewards/src/lib.rs | 319 ++++++------------ pallets/rewards/src/types.rs | 7 - .../src/traits/multi_asset_delegation.rs | 9 +- primitives/src/traits/rewards.rs | 36 +- primitives/src/types/rewards.rs | 14 + 10 files changed, 456 insertions(+), 344 deletions(-) diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 9e609385..7d00271f 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -116,16 +116,6 @@ pub mod pallet { + Decode + TypeInfo; - /// Type representing the unique ID of a vault. - type VaultId: Parameter - + Member - + Copy - + MaybeSerializeDeserialize - + Ord - + Default - + MaxEncodedLen - + TypeInfo; - /// The maximum number of blueprints a delegator can have in Fixed mode. #[pallet::constant] type MaxDelegatorBlueprints: Get + TypeInfo + MaxEncodedLen + Clone + Debug + PartialEq; @@ -290,17 +280,6 @@ pub mod pallet { ExecutedDelegatorBondLess { who: T::AccountId }, /// A delegator unstake request has been cancelled. CancelledDelegatorBondLess { who: T::AccountId }, - /// Event emitted when an incentive APY and cap are set for a reward vault - IncentiveAPYAndCapSet { vault_id: T::VaultId, apy: sp_runtime::Percent, cap: BalanceOf }, - /// Event emitted when a blueprint is whitelisted for rewards - BlueprintWhitelisted { blueprint_id: BlueprintId }, - /// Asset has been updated to reward vault - AssetUpdatedInVault { - who: T::AccountId, - vault_id: T::VaultId, - asset_id: Asset, - action: AssetAction, - }, /// Operator has been slashed OperatorSlashed { who: T::AccountId, amount: BalanceOf }, /// Delegator has been slashed diff --git a/pallets/multi-asset-delegation/src/traits.rs b/pallets/multi-asset-delegation/src/traits.rs index 653ad9ef..5ed18234 100644 --- a/pallets/multi-asset-delegation/src/traits.rs +++ b/pallets/multi-asset-delegation/src/traits.rs @@ -15,13 +15,17 @@ // along with Tangle. If not, see . use super::*; use crate::types::{BalanceOf, OperatorStatus}; +use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::{traits::Zero, Percent}; use sp_std::prelude::*; +use tangle_primitives::types::rewards::UserDepositWithLocks; use tangle_primitives::{ services::Asset, traits::MultiAssetDelegationInfo, BlueprintId, RoundIndex, }; -impl MultiAssetDelegationInfo> for crate::Pallet { +impl MultiAssetDelegationInfo, BlockNumberFor> + for crate::Pallet +{ type AssetId = T::AssetId; fn get_current_round() -> RoundIndex { @@ -69,4 +73,16 @@ impl MultiAssetDelegationInfo> for fn slash_operator(operator: &T::AccountId, blueprint_id: BlueprintId, percentage: Percent) { let _ = Pallet::::slash_operator(operator, blueprint_id, percentage); } + + fn get_user_deposit_with_locks( + who: &T::AccountId, + asset_id: Asset, + ) -> Option, BlockNumberFor>> { + Delegators::::get(who).and_then(|metadata| { + metadata.deposits.get(&asset_id).map(|deposit| UserDepositWithLocks { + unlocked_amount: deposit.amount, + amount_with_locks: deposit.locks.as_ref().map(|locks| locks.to_vec()), + }) + }) + } } diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index cbc97544..c5efa708 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -20,6 +20,7 @@ use frame_support::{pallet_prelude::Get, BoundedVec}; use sp_runtime::traits::Zero; use sp_std::fmt::Debug; use sp_std::vec; +use tangle_primitives::types::rewards::LockInfo; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, BlueprintId}; @@ -346,11 +347,3 @@ pub struct BondInfoDelegator, } - -/// Struct to store the lock info -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] -pub struct LockInfo { - pub amount: Balance, - pub lock_multiplier: LockMultiplier, - pub expiry_block: BlockNumber, -} diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 7c8f45aa..1b2d7842 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -14,86 +14,252 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate::{BalanceOf, Config, Pallet, UserRewardsOf}; +use crate::AssetLookupRewardVaults; +use crate::Error; +use crate::Event; +use crate::RewardConfigForAssetVault; +use crate::RewardConfigStorage; +use crate::RewardVaults; +use crate::TotalRewardVaultScore; +use crate::UserClaimedReward; +use crate::{BalanceOf, Config, Pallet}; +use frame_support::ensure; use frame_support::traits::Currency; +use frame_system::pallet_prelude::BlockNumberFor; +use sp_runtime::traits::{CheckedDiv, CheckedMul}; +use sp_runtime::DispatchError; +use sp_runtime::DispatchResult; use sp_runtime::{ traits::{Saturating, Zero}, Percent, }; +use tangle_primitives::types::rewards::UserDepositWithLocks; +use tangle_primitives::MultiAssetDelegationInfo; use tangle_primitives::{services::Asset, types::rewards::LockMultiplier}; -/// Calculate the score for a user's rewards based on their lock period and amount -pub fn calculate_user_score( - asset: Asset, - rewards: &UserRewardsOf, -) -> u128 { - // Get the lock multiplier in months (1, 2, 3, or 6) - let lock_period = match rewards.boost_rewards.multiplier { - LockMultiplier::OneMonth => 1, - LockMultiplier::TwoMonths => 2, - LockMultiplier::ThreeMonths => 3, - LockMultiplier::SixMonths => 6, - }; - - // Convert amount to u128 for calculation - let amount: u128 = rewards.boost_rewards.amount.saturated_into(); - - // Score = amount * lock_period - amount.saturating_mul(lock_period as u128) -} +impl Pallet { + pub fn remove_asset_from_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { + // Update RewardVaults storage + RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { + let assets = maybe_assets.as_mut().ok_or(Error::::VaultNotFound)?; + + // Ensure the asset is in the vault + ensure!(assets.contains(asset_id), Error::::AssetNotInVault); + + assets.retain(|id| id != asset_id); + + Ok(()) + })?; -/// Calculate the APY distribution for a given asset and score -pub fn calculate_apy_distribution( - asset: Asset, - user_score: u128, -) -> Percent { - let total_score = >::get(asset); - if total_score.is_zero() { - return Percent::zero(); + // Update AssetLookupRewardVaults storage + AssetLookupRewardVaults::::remove(asset_id); + + Ok(()) } - let total_deposited = >::get(asset); - let capacity = >::get(asset); - let apy_basis_points = >::get(asset); + pub fn add_asset_to_vault( + vault_id: &T::VaultId, + asset_id: &Asset, + ) -> DispatchResult { + // Ensure the asset is not already associated with any vault + ensure!( + !AssetLookupRewardVaults::::contains_key(asset_id), + Error::::AssetAlreadyInVault + ); + + // Update RewardVaults storage + RewardVaults::::try_mutate(vault_id, |maybe_assets| -> DispatchResult { + let assets = maybe_assets.get_or_insert_with(Vec::new); + + // Ensure the asset is not already in the vault + ensure!(!assets.contains(asset_id), Error::::AssetAlreadyInVault); + + assets.push(*asset_id); - // Convert capacity and total_deposited to u128 for calculation - let capacity: u128 = capacity.saturated_into(); - let total_deposited: u128 = total_deposited.saturated_into(); + Ok(()) + })?; - if capacity.is_zero() { - return Percent::zero(); + // Update AssetLookupRewardVaults storage + AssetLookupRewardVaults::::insert(asset_id, vault_id); + + Ok(()) } - // Calculate pro-rata score distribution - let score_ratio = Percent::from_rational(user_score, total_score); + /// Calculates and pays out rewards for a given account and asset. + /// + /// This function orchestrates the reward calculation and payout process by: + /// 1. Finding the vault associated with the asset + /// 2. Retrieving user deposit information including any locked amounts + /// 3. Calculating rewards based on deposit amounts, lock periods, and APY + /// + /// # Arguments + /// * `account_id` - The account to calculate rewards for + /// * `asset` - The asset to calculate rewards for + /// + /// # Returns + /// * `Ok(BalanceOf)` - The total rewards calculated + /// * `Err(DispatchError)` - If any of the following conditions are met: + /// - Asset is not in a reward vault + /// - No rewards are available for the account + /// - Reward configuration is not found for the vault + /// - Arithmetic overflow occurs during calculation + /// + /// # Assumptions + /// * The asset must be registered in a reward vault + /// * The reward configuration must exist for the vault + pub fn calculate_and_payout_rewards( + account_id: &T::AccountId, + asset: Asset, + ) -> Result, DispatchError> { + // find the vault for the asset id + // if the asset is not in a reward vault, do nothing + let vault_id = + AssetLookupRewardVaults::::get(&asset).ok_or(Error::::AssetNotInVault)?; - // Calculate capacity utilization - let capacity_ratio = Percent::from_rational(total_deposited, capacity); + // lets read the user deposits from the delegation manager + let deposit_info = + T::DelegationManager::get_user_deposit_with_locks(&account_id.clone(), asset.clone()) + .ok_or(Error::::NoRewardsAvailable)?; - // Calculate final APY - // APY = base_apy * (score/total_score) * (total_deposited/capacity) - let base_apy = Percent::from_percent(apy_basis_points as u8); - base_apy.saturating_mul(score_ratio).saturating_mul(capacity_ratio) -} + // read the asset reward config + let reward_config = RewardConfigStorage::::get(&vault_id); -/// Update the total score for an asset -pub fn update_total_score(asset: Asset, old_score: u128, new_score: u128) { - let current_total = >::get(asset); - let new_total = current_total.saturating_sub(old_score).saturating_add(new_score); - >::insert(asset, new_total); -} + // find the total vault score + let total_score = TotalRewardVaultScore::::get(&vault_id); + + // get the users last claim + let last_claim = UserClaimedReward::::get(&account_id, &vault_id); + + let (total_rewards, rewards_to_be_paid) = + Self::calculate_deposit_rewards_with_lock_multiplier( + total_score, + deposit_info, + reward_config.ok_or(Error::::RewardConfigNotFound)?, + last_claim, + )?; + + // mint new TNT rewards and trasnfer to the user + T::Currency::deposit_creating(&account_id, rewards_to_be_paid); + + // update the last claim + UserClaimedReward::::insert( + &account_id, + &vault_id, + (frame_system::Pallet::::block_number(), total_rewards), + ); + + Self::deposit_event(Event::RewardsClaimed { + account: account_id.clone(), + asset, + amount: rewards_to_be_paid, + }); -/// Update the total deposited amount for an asset -pub fn update_total_deposited( - asset: Asset, - amount: BalanceOf, - is_deposit: bool, -) { - let current_total = >::get(asset); - let new_total = if is_deposit { - current_total.saturating_add(amount) - } else { - current_total.saturating_sub(amount) - }; - >::insert(asset, new_total); + Ok(total_rewards) + } + + /// Calculates rewards for deposits considering both unlocked amounts and locked amounts with their respective multipliers. + /// + /// The reward calculation follows these formulas: + /// 1. For unlocked amounts: + /// ```text + /// base_reward = APY * (user_deposit / total_deposits) * (total_deposits / deposit_capacity) + /// ``` + /// + /// 2. For locked amounts: + /// ```text + /// lock_reward = amount * APY * lock_multiplier * (remaining_lock_time / total_lock_time) + /// ``` + /// + /// # Arguments + /// * `total_asset_score` - Total score for the asset across all deposits + /// * `deposit` - User's deposit information including locked amounts + /// * `reward` - Reward configuration for the asset vault + /// * `last_claim` - Timestamp and amount of user's last reward claim + /// + /// # Returns + /// * `Ok(BalanceOf)` - The calculated rewards + /// * `Err(DispatchError)` - If any arithmetic operation overflows + /// + /// # Assumptions and Constraints + /// * Lock multipliers are fixed at: 1x (1 month), 2x (2 months), 3x (3 months), 6x (6 months) + /// * APY is applied proportionally to the lock period remaining + /// * Rewards scale with: + /// - The proportion of user's deposit to total deposits + /// - The proportion of total deposits to deposit capacity + /// - The lock multiplier (if applicable) + /// - The remaining time in the lock period + /// + pub fn calculate_deposit_rewards_with_lock_multiplier( + total_asset_score: BalanceOf, + deposit: UserDepositWithLocks, BlockNumberFor>, + reward: RewardConfigForAssetVault>, + last_claim: Option<(BlockNumberFor, BalanceOf)>, + ) -> Result<(BalanceOf, BalanceOf), DispatchError> { + // The formula for rewards: + // Base Reward = APY * (user_deposit / total_deposits) * (total_deposits / deposit_capacity) + // For locked amounts: Base Reward * lock_multiplier * (remaining_lock_time / total_lock_time) + + let asset_apy = reward.apy; + let deposit_capacity = reward.deposit_cap; + + // Start with unlocked amount as base score + let mut total_rewards = deposit.unlocked_amount; + + // Get the current block and last claim block + let current_block = frame_system::Pallet::::block_number(); + let last_claim_block = last_claim.map(|(block, _)| block).unwrap_or(current_block); + + // Calculate base reward rate + // APY * (deposit / total_deposits) * (total_deposits / capacity) + let base_reward_rate = if !total_asset_score.is_zero() { + let deposit_ratio = total_rewards + .checked_mul(&total_rewards) + .and_then(|v| v.checked_div(&total_asset_score)) + .ok_or(Error::::ArithmeticError)?; + + let capacity_ratio = total_asset_score + .checked_div(&deposit_capacity) + .ok_or(Error::::ArithmeticError)?; + + asset_apy.mul_floor(deposit_ratio.saturating_mul(capacity_ratio)) + } else { + Zero::zero() + }; + + // Add rewards for locked amounts if any exist + if let Some(locks) = deposit.amount_with_locks { + for lock in locks { + if lock.expiry_block > last_claim_block { + // Calculate remaining lock time as a ratio + let blocks_remaining: u32 = + TryInto::::try_into(lock.expiry_block.saturating_sub(current_block)) + .map_err(|_| Error::::ArithmeticError)?; + + let total_lock_blocks = lock.lock_multiplier.get_blocks(); + let time_ratio = BalanceOf::::from(blocks_remaining) + .checked_div(&BalanceOf::::from(total_lock_blocks)) + .ok_or(Error::::ArithmeticError)?; + + // Calculate lock reward: + // amount * APY * multiplier * time_ratio + let multiplier = BalanceOf::::from(lock.lock_multiplier.value()); + let lock_reward = asset_apy + .mul_floor(lock.amount) + .saturating_mul(multiplier) + .saturating_mul(time_ratio); + + total_rewards = total_rewards.saturating_add(lock_reward); + } + } + } + + // lets remove any already claimed rewards + let rewards_to_be_paid = total_rewards + .saturating_sub(last_claim.map(|(_, amount)| amount).unwrap_or(Zero::zero())); + + Ok((total_rewards, rewards_to_be_paid)) + } } diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index 26456e31..7823878d 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -14,22 +14,38 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . +use crate::AssetLookupRewardVaults; use crate::BalanceOf; -use crate::{Config, Pallet, UserRewards, UserRewardsOf}; +use crate::Error; +use crate::RewardConfigStorage; +use crate::TotalRewardVaultScore; +use crate::UserServiceReward; +use crate::{Config, Pallet}; use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::{Saturating, Zero}; +use sp_runtime::DispatchError; +use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, traits::rewards::RewardsManager}; impl RewardsManager, BlockNumberFor> for Pallet { + type Error = DispatchError; + fn record_deposit( - account_id: &T::AccountId, + _account_id: &T::AccountId, asset: Asset, amount: BalanceOf, - lock_multiplier: Option, - ) -> Result<(), &'static str> { + _lock_multiplier: Option, + ) -> Result<(), Self::Error> { + // find the vault for the asset id + // if the asset is not in a reward vault, do nothing + if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + // Update the reward vault score + let score = TotalRewardVaultScore::::get(vault_id).saturating_add(amount); + TotalRewardVaultScore::::insert(vault_id, score); + } Ok(()) } @@ -37,7 +53,14 @@ impl RewardsManager, BlockNumb account_id: &T::AccountId, asset: Asset, amount: BalanceOf, - ) -> Result<(), &'static str> { + ) -> Result<(), Self::Error> { + // find the vault for the asset id + // if the asset is not in a reward vault, do nothing + if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + // Update the reward vault score + let score = TotalRewardVaultScore::::get(vault_id).saturating_sub(amount); + TotalRewardVaultScore::::insert(vault_id, score); + } Ok(()) } @@ -45,15 +68,39 @@ impl RewardsManager, BlockNumb account_id: &T::AccountId, asset: Asset, amount: BalanceOf, - ) -> Result<(), &'static str> { - // TODO : Handle service rewards later - Ok(()) + ) -> Result<(), Self::Error> { + // update the amount in the user service reward storage + UserServiceReward::::try_mutate(account_id, asset, |reward| { + *reward = reward.saturating_add(amount); + Ok(()) + }) } - fn query_total_deposit( - account_id: &T::AccountId, - asset: Asset, - ) -> Result<(BalanceOf, BalanceOf), &'static str> { - todo!() + fn get_asset_deposit_cap(asset: Asset) -> Result, Self::Error> { + // find the vault for the asset id + // if the asset is not in a reward vault, do nothing + if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(config) = RewardConfigStorage::::get(vault_id) { + Ok(config.deposit_cap) + } else { + Err(Error::::RewardConfigNotFound.into()) + } + } else { + Err(Error::::AssetNotInVault.into()) + } + } + + fn get_asset_incentive_cap(asset: Asset) -> Result, Self::Error> { + // find the vault for the asset id + // if the asset is not in a reward vault, do nothing + if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(config) = RewardConfigStorage::::get(vault_id) { + Ok(config.incentive_cap) + } else { + Err(Error::::RewardConfigNotFound.into()) + } + } else { + Err(Error::::AssetNotInVault.into()) + } } } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 0f6a5656..6ecbcb6f 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -36,15 +36,17 @@ mod tests; // #[cfg(feature = "runtime-benchmarks")] // mod benchmarking; - use scale_info::TypeInfo; use sp_runtime::Saturating; +use sp_std::collections::btree_map::BTreeMap; use tangle_primitives::services::Asset; pub mod types; pub use types::*; pub mod functions; pub use functions::*; pub mod impls; +use tangle_primitives::BlueprintId; +use tangle_primitives::MultiAssetDelegationInfo; /// The pallet's account ID. #[frame_support::pallet] @@ -75,8 +77,23 @@ pub mod pallet { /// The pallet's account ID. type PalletId: Get; - /// The maximum amount of rewards that can be claimed per asset per user. - type MaxUniqueServiceRewards: Get + MaxEncodedLen + TypeInfo; + /// Type representing the unique ID of a vault. + type VaultId: Parameter + + Member + + Copy + + MaybeSerializeDeserialize + + Ord + + Default + + MaxEncodedLen + + TypeInfo; + + /// Manager for getting operator stake and delegation info + type DelegationManager: tangle_primitives::traits::MultiAssetDelegationInfo< + Self::AccountId, + BalanceOf, + BlockNumberFor, + AssetId = Self::AssetId, + >; /// The origin that can manage reward assets type ForceOrigin: EnsureOrigin; @@ -90,7 +107,32 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn total_reward_vault_score)] pub type TotalRewardVaultScore = - StorageMap<_, Blake2_128Concat, T::VaultId, u128, ValueQuery>; + StorageMap<_, Blake2_128Concat, T::VaultId, BalanceOf, ValueQuery>; + + /// Stores the service reward for a given user + #[pallet::storage] + #[pallet::getter(fn user_reward_score)] + pub type UserServiceReward = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Blake2_128Concat, + Asset, + BalanceOf, + ValueQuery, + >; + + /// Stores the service reward for a given user + #[pallet::storage] + #[pallet::getter(fn user_claimed_reward)] + pub type UserClaimedReward = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Blake2_128Concat, + T::VaultId, + (BlockNumberFor, BalanceOf), + >; #[pallet::storage] #[pallet::getter(fn reward_vaults)] @@ -106,44 +148,31 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn reward_config)] - /// Storage for the reward configuration, which includes APY, cap for assets, and whitelisted - /// blueprints. - pub type RewardConfigStorage = - StorageValue<_, RewardConfig>, OptionQuery>; + /// Storage for the reward configuration, which includes APY, cap for assets + pub type RewardConfigStorage = StorageMap< + _, + Blake2_128Concat, + T::VaultId, + RewardConfigForAssetVault>, + OptionQuery, + >; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - /// Rewards have been added for an account - RewardsAdded { - account: T::AccountId, - asset: Asset, - amount: BalanceOf, - reward_type: RewardType, - }, /// Rewards have been claimed by an account - RewardsClaimed { - account: T::AccountId, - asset: Asset, - amount: BalanceOf, - reward_type: RewardType, + RewardsClaimed { account: T::AccountId, asset: Asset, amount: BalanceOf }, + /// Event emitted when an incentive APY and cap are set for a reward vault + IncentiveAPYAndCapSet { vault_id: T::VaultId, apy: sp_runtime::Percent, cap: BalanceOf }, + /// Event emitted when a blueprint is whitelisted for rewards + BlueprintWhitelisted { blueprint_id: BlueprintId }, + /// Asset has been updated to reward vault + AssetUpdatedInVault { + who: T::AccountId, + vault_id: T::VaultId, + asset_id: Asset, + action: AssetAction, }, - /// Asset has been whitelisted for rewards - AssetWhitelisted { asset: Asset }, - /// Asset has been removed from whitelist - AssetRemoved { asset: Asset }, - /// Asset rewards have been updated - AssetRewardsUpdated { asset: Asset, total_score: u128, users_updated: u32 }, - /// Asset APY has been updated - AssetApyUpdated { asset: Asset, apy_basis_points: u32 }, - } - - /// Type of reward being added or claimed - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] - pub enum RewardType { - Restaking, - Boost, - Service, } #[pallet::error] @@ -158,6 +187,20 @@ pub mod pallet { AssetAlreadyWhitelisted, /// Invalid APY value InvalidAPY, + /// Asset already exists in a reward vault + AssetAlreadyInVault, + /// Asset not found in reward vault + AssetNotInVault, + /// The reward vault does not exist + VaultNotFound, + /// Error returned when trying to add a blueprint ID that already exists. + DuplicateBlueprintId, + /// Error returned when trying to remove a blueprint ID that doesn't exist. + BlueprintIdNotFound, + /// Error returned when the reward configuration for the vault is not found. + RewardConfigNotFound, + /// Arithmetic operation caused an overflow + ArithmeticError, } #[pallet::call] @@ -167,165 +210,10 @@ pub mod pallet { pub fn claim_rewards(origin: OriginFor, asset: Asset) -> DispatchResult { let who = ensure_signed(origin)?; - // Ensure the asset is whitelisted - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - - // Get user rewards snapshot - let rewards = Self::user_rewards(&who, asset); - - // Calculate user's score based on their stake and lock period - let user_score = functions::calculate_user_score::(asset, &rewards); - - // Calculate APY distribution based on user's score - let apy = functions::calculate_apy_distribution::(asset, user_score); - - // Calculate reward amount based on APY and elapsed time - let reward_amount = match reward_type { - RewardType::Boost => { - // For boost rewards, calculate based on locked amount and APY - let locked_amount = rewards.boost_rewards.amount; - let elapsed_time = frame_system::Pallet::::block_number() - .saturating_sub(rewards.boost_rewards.expiry); - - // Convert APY to per-block rate (assuming 6 second blocks) - // APY / (blocks per year) = reward rate per block - // blocks per year = (365 * 24 * 60 * 60) / 6 = 5,256,000 - let blocks_per_year = T::BlocksPerYear::get(); - let reward_rate = apy.mul_floor(locked_amount) / blocks_per_year.into(); - - reward_rate.saturating_mul(elapsed_time.into()) - }, - RewardType::Service => { - // For service rewards, use the accumulated service rewards - rewards.service_rewards - }, - RewardType::Restaking => { - // For restaking rewards, use the accumulated restaking rewards - rewards.restaking_rewards - }, - }; - - // Ensure there are rewards to claim - ensure!(!.is_zero(), Error::::NoRewardsAvailable); - - // Transfer rewards to user - // Note: This assumes the pallet account has sufficient balance - let pallet_account = Self::account_id(); - T::Currency::transfer( - &pallet_account, - &who, - reward_amount, - frame_support::traits::ExistenceRequirement::KeepAlive, - )?; - - // Reset the claimed reward type - match reward_type { - RewardType::Boost => { - // For boost rewards, update the expiry to current block - Self::update_user_rewards( - &who, - asset, - UserRewards { - boost_rewards: BoostInfo { - expiry: frame_system::Pallet::::block_number(), - ..rewards.boost_rewards - }, - ..rewards - }, - ); - }, - RewardType::Service => { - // Reset service rewards to zero - Self::update_user_rewards( - &who, - asset, - UserRewards { service_rewards: Zero::zero(), ..rewards }, - ); - }, - RewardType::Restaking => { - // Reset restaking rewards to zero - Self::update_user_rewards( - &who, - asset, - UserRewards { restaking_rewards: Zero::zero(), ..rewards }, - ); - }, - } + // calculate and payout rewards + Self::calculate_and_payout_rewards(&who, asset)?; // Emit event - Self::deposit_event(Event::RewardsClaimed { - account: who, - asset, - amount: reward_amount, - reward_type, - }); - - Ok(()) - } - - /// Update APY for an asset - #[pallet::call_index(6)] - #[pallet::weight(10_000)] - pub fn update_asset_apy( - origin: OriginFor, - asset: Asset, - apy_basis_points: u32, - ) -> DispatchResult { - ensure_root(origin)?; - ensure!(Self::is_asset_whitelisted(asset), Error::::AssetNotWhitelisted); - ensure!(apy_basis_points <= 10000, Error::::InvalidAPY); // Max 100% - - // Update APY - AssetApy::::insert(asset, apy_basis_points); - - // Emit event - Self::deposit_event(Event::AssetApyUpdated { asset, apy_basis_points }); - - Ok(()) - } - - /// Sets the APY and cap for a specific asset. - /// - /// # Permissions - /// - /// * Must be called by the force origin - /// - /// # Arguments - /// - /// * `origin` - Origin of the call - /// * `vault_id` - ID of the vault - /// * `apy` - Annual percentage yield (max 10%) - /// * `cap` - Required deposit amount for full APY - /// - /// # Errors - /// - /// * [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum - /// * [`Error::CapCannotBeZero`] - Cap amount cannot be zero - #[pallet::call_index(18)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn set_incentive_apy_and_cap( - origin: OriginFor, - vault_id: T::VaultId, - apy: sp_runtime::Percent, - cap: BalanceOf, - ) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; - - ensure!(apy <= sp_runtime::Percent::from_percent(10), Error::::APYExceedsMaximum); - ensure!(!cap.is_zero(), Error::::CapCannotBeZero); - - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); - - config.configs.insert(vault_id, RewardConfigForAssetVault { apy, cap }); - - *maybe_config = Some(config); - }); - - Self::deposit_event(Event::IncentiveAPYAndCapSet { vault_id, apy, cap }); Ok(()) } @@ -340,31 +228,31 @@ pub mod pallet { /// /// * `origin` - Origin of the call /// * `blueprint_id` - ID of blueprint to whitelist - #[pallet::call_index(19)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn whitelist_blueprint_for_rewards( - origin: OriginFor, - blueprint_id: BlueprintId, - ) -> DispatchResult { - T::ForceOrigin::ensure_origin(origin)?; + // #[pallet::call_index(19)] + // #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + // pub fn whitelist_blueprint_for_rewards( + // origin: OriginFor, + // blueprint_id: BlueprintId, + // ) -> DispatchResult { + // T::ForceOrigin::ensure_origin(origin)?; - RewardConfigStorage::::mutate(|maybe_config| { - let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - configs: BTreeMap::new(), - whitelisted_blueprint_ids: Vec::new(), - }); + // RewardConfigStorage::::mutate(|maybe_config| { + // let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { + // configs: BTreeMap::new(), + // whitelisted_blueprint_ids: Vec::new(), + // }); - if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { - config.whitelisted_blueprint_ids.push(blueprint_id); - } + // if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { + // config.whitelisted_blueprint_ids.push(blueprint_id); + // } - *maybe_config = Some(config); - }); + // *maybe_config = Some(config); + // }); - Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); + // Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); - Ok(()) - } + // Ok(()) + // } /// Manage asset id to vault rewards. /// @@ -409,10 +297,5 @@ pub mod pallet { pub fn account_id() -> T::AccountId { T::PalletId::get().into_account_truncating() } - - /// Check if an asset is whitelisted for rewards - pub fn is_asset_whitelisted(asset: Asset) -> bool { - AllowedRewardAssets::::get(&asset) - } } } diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index dc70ea24..dbbc117f 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -26,13 +26,6 @@ use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use tangle_primitives::types::rewards::UserRewards; use tangle_primitives::{services::Asset, types::RoundIndex}; -pub type UserRewardsOf = UserRewards< - BalanceOf, - BlockNumberFor, - ::AssetId, - ::MaxUniqueServiceRewards, ->; - pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/primitives/src/traits/multi_asset_delegation.rs b/primitives/src/traits/multi_asset_delegation.rs index ebd5bc95..f9639e53 100644 --- a/primitives/src/traits/multi_asset_delegation.rs +++ b/primitives/src/traits/multi_asset_delegation.rs @@ -1,3 +1,4 @@ +use crate::types::rewards::UserDepositWithLocks; use crate::{services::Asset, types::RoundIndex}; use sp_std::prelude::*; @@ -12,7 +13,8 @@ use sp_std::prelude::*; /// * `AccountId`: The type representing an account identifier. /// * `AssetId`: The type representing an asset identifier. /// * `Balance`: The type representing a balance or amount. -pub trait MultiAssetDelegationInfo { +/// * `BlockNumber`: The type representing a block number. +pub trait MultiAssetDelegationInfo { type AssetId; /// Get the current round index. @@ -106,4 +108,9 @@ pub trait MultiAssetDelegationInfo { blueprint_id: crate::BlueprintId, percentage: sp_runtime::Percent, ); + + fn get_user_deposit_with_locks( + who: &AccountId, + asset_id: Asset, + ) -> Option>; } diff --git a/primitives/src/traits/rewards.rs b/primitives/src/traits/rewards.rs index 7364200b..06bbea80 100644 --- a/primitives/src/traits/rewards.rs +++ b/primitives/src/traits/rewards.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use crate::services::Asset; +use crate::types::rewards::LockMultiplier; use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::Zero; @@ -63,15 +64,27 @@ pub trait RewardsManager { amount: Balance, ) -> Result<(), Self::Error>; - /// Queries the total deposit for an account and asset. + /// Gets the maximum deposit cap for an asset at a given block number. + /// This represents the maximum amount that can be deposited for this asset. /// /// # Parameters - /// * `account_id` - The account to query - /// * `asset` - The asset to query - fn query_total_deposit( - account_id: &AccountId, - asset: Asset, - ) -> Result; + /// * `asset` - The asset to query the deposit cap for + /// + /// # Returns + /// * `Ok(Balance)` - The maximum deposit cap for the asset + /// * `Err(Self::Error)` - If there was an error retrieving the cap + fn get_asset_deposit_cap(asset: Asset) -> Result; + + /// Gets the incentive cap for an asset at a given block number. + /// This represents the minimum amount required to receive full incentives. + /// + /// # Parameters + /// * `asset` - The asset to query the incentive cap for + /// + /// # Returns + /// * `Ok(Balance)` - The incentive cap for the asset + /// * `Err(Self::Error)` - If there was an error retrieving the cap + fn get_asset_incentive_cap(asset: Asset) -> Result; } impl @@ -106,10 +119,11 @@ where Ok(()) } - fn query_total_deposit( - _account_id: &AccountId, - _asset: Asset, - ) -> Result { + fn get_asset_deposit_cap(_asset: Asset) -> Result { + Ok(Balance::zero()) + } + + fn get_asset_incentive_cap(_asset: Asset) -> Result { Ok(Balance::zero()) } } diff --git a/primitives/src/types/rewards.rs b/primitives/src/types/rewards.rs index 3ed16f1d..d5273f2e 100644 --- a/primitives/src/types/rewards.rs +++ b/primitives/src/types/rewards.rs @@ -102,3 +102,17 @@ impl LockMultiplier { current_block.saturating_add(self.get_blocks()) } } + +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] +pub struct UserDepositWithLocks { + pub unlocked_amount: Balance, + pub amount_with_locks: Option>>, +} + +/// Struct to store the lock info +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] +pub struct LockInfo { + pub amount: Balance, + pub lock_multiplier: LockMultiplier, + pub expiry_block: BlockNumber, +} From 6e611fd1d1515f2a39ca0279315f48d16a3d1a24 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:46:18 +0530 Subject: [PATCH 54/63] wip tests --- pallets/rewards/src/lib.rs | 42 +- pallets/rewards/src/mock.rs | 235 +++------- pallets/rewards/src/mock_evm.rs | 329 ------------- pallets/rewards/src/tests.rs | 806 +++++++------------------------- 4 files changed, 219 insertions(+), 1193 deletions(-) delete mode 100644 pallets/rewards/src/mock_evm.rs diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 6ecbcb6f..668f10cc 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -26,9 +26,6 @@ pub use pallet::*; #[cfg(test)] mod mock; -#[cfg(test)] -mod mock_evm; - #[cfg(test)] mod tests; @@ -36,6 +33,7 @@ mod tests; // #[cfg(feature = "runtime-benchmarks")] // mod benchmarking; + use scale_info::TypeInfo; use sp_runtime::Saturating; use sp_std::collections::btree_map::BTreeMap; @@ -213,47 +211,9 @@ pub mod pallet { // calculate and payout rewards Self::calculate_and_payout_rewards(&who, asset)?; - // Emit event - Ok(()) } - /// Whitelists a blueprint for rewards. - /// - /// # Permissions - /// - /// * Must be called by the force origin - /// - /// # Arguments - /// - /// * `origin` - Origin of the call - /// * `blueprint_id` - ID of blueprint to whitelist - // #[pallet::call_index(19)] - // #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - // pub fn whitelist_blueprint_for_rewards( - // origin: OriginFor, - // blueprint_id: BlueprintId, - // ) -> DispatchResult { - // T::ForceOrigin::ensure_origin(origin)?; - - // RewardConfigStorage::::mutate(|maybe_config| { - // let mut config = maybe_config.take().unwrap_or_else(|| RewardConfig { - // configs: BTreeMap::new(), - // whitelisted_blueprint_ids: Vec::new(), - // }); - - // if !config.whitelisted_blueprint_ids.contains(&blueprint_id) { - // config.whitelisted_blueprint_ids.push(blueprint_id); - // } - - // *maybe_config = Some(config); - // }); - - // Self::deposit_event(Event::BlueprintWhitelisted { blueprint_id }); - - // Ok(()) - // } - /// Manage asset id to vault rewards. /// /// # Permissions diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index ad0c649f..cc722ca8 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] -use super::*; -use crate::{self as pallet_multi_asset_delegation}; +use crate::{self as pallet_rewards}; use ethabi::Uint; use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, @@ -28,7 +27,6 @@ use frame_support::{ traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, PalletId, }; -use mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -42,7 +40,9 @@ use sp_runtime::{ traits::{ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; +use tangle_primitives::services::Asset; use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; +use tangle_primitives::types::rewards::UserDepositWithLocks; use core::ops::Mul; use std::{collections::BTreeMap, sync::Arc}; @@ -51,6 +51,7 @@ pub type AccountId = AccountId32; pub type Balance = u128; type Nonce = u32; pub type AssetId = u128; +pub type BlockNumber = u64; #[frame_support::derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { @@ -263,35 +264,75 @@ impl pallet_assets::Config for Runtime { type RemoveItemsLimit = ConstU32<5>; } +parameter_types! { + pub RewardsPID: PalletId = PalletId(*b"PotStake"); +} + impl pallet_rewards::Config for Runtime { type RuntimeEvent = RuntimeEvent; type AssetId = AssetId; - type Balance = Balance; type Currency = Balances; - type Assets = Assets; - type ServiceManager = MockServiceManager; + type PalletId = RewardsPID; + type VaultId = u32; + type DelegationManager = MockDelegationManager; + type ForceOrigin = frame_system::EnsureRoot; } -pub struct MockServiceManager; +pub struct MockDelegationManager; +impl tangle_primitives::traits::MultiAssetDelegationInfo + for MockDelegationManager +{ + type AssetId = AssetId; -impl tangle_primitives::ServiceManager for MockServiceManager { - fn get_active_blueprints_count(_account: &AccountId) -> usize { - // we dont care + fn get_current_round() -> tangle_primitives::types::RoundIndex { Default::default() } - fn get_active_services_count(_account: &AccountId) -> usize { - // we dont care - Default::default() + fn is_operator(_operator: &AccountId) -> bool { + // dont care + true } - fn can_exit(_account: &AccountId) -> bool { - // Mock logic to determine if the given account can exit + fn is_operator_active(operator: &AccountId) -> bool { + if operator == &mock_pub_key(10) { + return false; + } true } - fn get_blueprints_by_operator(_account: &AccountId) -> Vec { - todo!(); // we dont care + fn get_operator_stake(operator: &AccountId) -> Balance { + if operator == &mock_pub_key(10) { + Default::default() + } else { + 1000 + } + } + + fn get_total_delegation_by_asset_id( + _operator: &AccountId, + _asset_id: &Asset, + ) -> Balance { + Default::default() + } + + fn get_delegators_for_operator( + _operator: &AccountId, + ) -> Vec<(AccountId, Balance, Asset)> { + Default::default() + } + + fn slash_operator( + _operator: &AccountId, + _blueprint_id: tangle_primitives::BlueprintId, + _percentage: sp_runtime::Percent, + ) { + } + + fn get_user_deposit_with_locks( + who: &AccountId, + asset_id: Asset, + ) -> Option> { + None } } @@ -323,12 +364,10 @@ construct_runtime!( Timestamp: pallet_timestamp, Balances: pallet_balances, Assets: pallet_assets, - EVM: pallet_evm, - Ethereum: pallet_ethereum, Session: pallet_session, Staking: pallet_staking, Historical: pallet_session_historical, - Rewards: pallet_rewards, + RewardsPallet: pallet_rewards, } ); @@ -352,11 +391,6 @@ pub fn account_id_to_address(account_id: AccountId) -> H160 { H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) } -// pub fn address_to_account_id(address: H160) -> AccountId { -// use pallet_evm::AddressMapping; -// ::AddressMapping::into_account_id(address) -// } - pub fn new_test_ext() -> sp_io::TestExternalities { new_test_ext_raw_authorities() } @@ -419,128 +453,10 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { evm_config.assimilate_storage(&mut t).unwrap(); - // let assets_config = pallet_assets::GenesisConfig:: { - // assets: vec![ - // (USDC, authorities[0].clone(), true, 100_000), // 1 cent. - // (WETH, authorities[1].clone(), true, 100), // 100 wei. - // (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. - // (VDOT, authorities[0].clone(), true, 100), - // ], - // metadata: vec![ - // (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), - // (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), - // (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), - // (VDOT, Vec::from(b"VeChain"), Vec::from(b"VDOT"), 18), - // ], - // accounts: vec![ - // (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), - // // - // (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), - // // - // (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), - - // // - // (VDOT, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), - // (VDOT, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), - // (VDOT, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), - // ], - // next_asset_id: Some(4), - // }; - // assets_config.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); ext.execute_with(|| System::set_block_number(1)); - ext.execute_with(|| { - System::set_block_number(1); - Session::on_initialize(1); - >::on_initialize(1); - - let call = ::EvmRunner::call( - // MultiAssetDelegation::pallet_evm_account(), - H160::zero(), - USDC_ERC20, - serde_json::from_value::(json!({ - "name": "initialize", - "inputs": [ - { - "name": "name_", - "type": "string", - "internalType": "string" - }, - { - "name": "symbol_", - "type": "string", - "internalType": "string" - }, - { - "name": "decimals_", - "type": "uint8", - "internalType": "uint8" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - })) - .unwrap() - .encode_input(&[ - ethabi::Token::String("USD Coin".to_string()), - ethabi::Token::String("USDC".to_string()), - ethabi::Token::Uint(6.into()), - ]) - .unwrap(), - Default::default(), - 300_000, - true, - false, - ); - - assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); - // Mint - for i in 1..=authorities.len() { - let call = ::EvmRunner::call( - // MultiAssetDelegation::pallet_evm_account(), - H160::zero(), - USDC_ERC20, - serde_json::from_value::(json!({ - "name": "mint", - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "outputs": [], - "stateMutability": "nonpayable" - })) - .unwrap() - .encode_input(&[ - ethabi::Token::Address(mock_address(i as u8).into()), - ethabi::Token::Uint(Uint::from(100_000).mul(Uint::from(10).pow(Uint::from(6)))), - ]) - .unwrap(), - Default::default(), - 300_000, - true, - false, - ); - - assert_eq!(call.map(|info| info.exit_reason.is_succeed()).ok(), Some(true)); - } - }); - ext } @@ -562,36 +478,3 @@ macro_rules! evm_log { } }; } - -// /// Asserts that the EVM logs are as expected. -// #[track_caller] -// pub fn assert_evm_logs(expected: &[fp_evm::Log]) { -// assert_evm_events_contains(expected.iter().cloned().collect()) -// } - -// /// Asserts that the EVM events are as expected. -// #[track_caller] -// fn assert_evm_events_contains(expected: Vec) { -// let actual: Vec = System::events() -// .iter() -// .filter_map(|e| match e.event { -// RuntimeEvent::EVM(pallet_evm::Event::Log { ref log }) => Some(log.clone()), -// _ => None, -// }) -// .collect(); - -// // Check if `expected` is a subset of `actual` -// let mut any_matcher = false; -// for evt in expected { -// if !actual.contains(&evt) { -// panic!("Events don't match\nactual: {actual:?}\nexpected: {evt:?}"); -// } else { -// any_matcher = true; -// } -// } - -// // At least one event should be present -// if !any_matcher { -// panic!("No events found"); -// } -// } diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs deleted file mode 100644 index 697971da..00000000 --- a/pallets/rewards/src/mock_evm.rs +++ /dev/null @@ -1,329 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -#![allow(clippy::all)] -use crate::mock::{ - AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, -}; -use fp_evm::FeeCalculator; -use frame_support::{ - parameter_types, - traits::{Currency, FindAuthor, OnUnbalanced}, - weights::Weight, - PalletId, -}; -use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; -use pallet_evm::{ - EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, OnChargeEVMTransaction, -}; -use sp_core::{keccak_256, ConstU32, H160, H256, U256}; -use sp_runtime::{ - traits::{BlakeTwo256, DispatchInfoOf, Dispatchable}, - transaction_validity::{TransactionValidity, TransactionValidityError}, - ConsensusEngineId, -}; - -use pallet_evm_precompile_blake2::Blake2F; -use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; -use pallet_evm_precompile_modexp::Modexp; -use pallet_evm_precompile_sha3fips::Sha3FIPS256; -use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; - -use precompile_utils::precompile_set::{ - AcceptDelegateCall, AddressU64, CallableByContract, CallableByPrecompile, PrecompileAt, - PrecompileSetBuilder, PrecompilesInRangeInclusive, -}; - -type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile); - -#[precompile_utils::precompile_name_from_address] -pub type DefaultPrecompiles = ( - // Ethereum precompiles: - PrecompileAt, ECRecover, EthereumPrecompilesChecks>, - PrecompileAt, Sha256, EthereumPrecompilesChecks>, - PrecompileAt, Ripemd160, EthereumPrecompilesChecks>, - PrecompileAt, Identity, EthereumPrecompilesChecks>, - PrecompileAt, Modexp, EthereumPrecompilesChecks>, - PrecompileAt, Bn128Add, EthereumPrecompilesChecks>, - PrecompileAt, Bn128Mul, EthereumPrecompilesChecks>, - PrecompileAt, Bn128Pairing, EthereumPrecompilesChecks>, - PrecompileAt, Blake2F, EthereumPrecompilesChecks>, - PrecompileAt, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>, - PrecompileAt, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>, -); - -pub type TanglePrecompiles = PrecompileSetBuilder< - R, - (PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<2095>), DefaultPrecompiles>,), ->; - -parameter_types! { - pub const MinimumPeriod: u64 = 6000 / 2; - - pub PrecompilesValue: TanglePrecompiles = TanglePrecompiles::<_>::new(); -} - -impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -pub struct FixedGasPrice; -impl FeeCalculator for FixedGasPrice { - fn min_gas_price() -> (U256, Weight) { - (1.into(), Weight::zero()) - } -} - -pub struct FindAuthorTruncated; -impl FindAuthor for FindAuthorTruncated { - fn find_author<'a, I>(_digests: I) -> Option - where - I: 'a + IntoIterator, - { - Some(address_build(0).address) - } -} - -const BLOCK_GAS_LIMIT: u64 = 150_000_000; -const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; - -parameter_types! { - pub const TransactionByteFee: u64 = 1; - pub const ChainId: u64 = 42; - pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); - pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); - pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); - pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); -} - -parameter_types! { - pub SuicideQuickClearLimit: u32 = 0; -} - -pub struct DealWithFees; -impl OnUnbalanced for DealWithFees { - fn on_unbalanceds(_fees_then_tips: impl Iterator) { - // whatever - } -} -pub struct FreeEVMExecution; - -impl OnChargeEVMTransaction for FreeEVMExecution { - type LiquidityInfo = (); - - fn withdraw_fee( - _who: &H160, - _fee: U256, - ) -> Result> { - Ok(()) - } - - fn correct_and_deposit_fee( - _who: &H160, - _corrected_fee: U256, - _base_fee: U256, - already_withdrawn: Self::LiquidityInfo, - ) -> Self::LiquidityInfo { - already_withdrawn - } - - fn pay_priority_fee(_tip: Self::LiquidityInfo) {} -} - -/// Type alias for negative imbalance during fees -type RuntimeNegativeImbalance = - ::AccountId>>::NegativeImbalance; - -/// See: [`pallet_evm::EVMCurrencyAdapter`] -pub struct CustomEVMCurrencyAdapter; - -impl OnChargeEVMTransaction for CustomEVMCurrencyAdapter { - type LiquidityInfo = Option; - - fn withdraw_fee( - who: &H160, - fee: U256, - ) -> Result> { - // fallback to the default implementation - as OnChargeEVMTransaction< - Runtime, - >>::withdraw_fee(who, fee) - } - - fn correct_and_deposit_fee( - who: &H160, - corrected_fee: U256, - base_fee: U256, - already_withdrawn: Self::LiquidityInfo, - ) -> Self::LiquidityInfo { - // fallback to the default implementation - as OnChargeEVMTransaction< - Runtime, - >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) - } - - fn pay_priority_fee(tip: Self::LiquidityInfo) { - as OnChargeEVMTransaction< - Runtime, - >>::pay_priority_fee(tip) - } -} - -impl pallet_evm::Config for Runtime { - type FeeCalculator = FixedGasPrice; - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type BlockHashMapping = EthereumBlockHashMapping; - type CallOrigin = EnsureAddressRoot; - type WithdrawOrigin = EnsureAddressNever; - type AddressMapping = HashedAddressMapping; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type PrecompilesType = TanglePrecompiles; - type PrecompilesValue = PrecompilesValue; - type ChainId = ChainId; - type BlockGasLimit = BlockGasLimit; - type Runner = pallet_evm::runner::stack::Runner; - type OnChargeTransaction = CustomEVMCurrencyAdapter; - type OnCreate = (); - type SuicideQuickClearLimit = SuicideQuickClearLimit; - type FindAuthor = FindAuthorTruncated; - type GasLimitPovSizeRatio = GasLimitPovSizeRatio; - type Timestamp = Timestamp; - type WeightInfo = (); -} - -parameter_types! { - pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; -} - -impl pallet_ethereum::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type StateRoot = IntermediateStateRoot; - type PostLogContent = PostBlockAndTxnHashes; - type ExtraDataLength = ConstU32<30>; -} - -impl fp_self_contained::SelfContainedCall for RuntimeCall { - type SignedInfo = H160; - - fn is_self_contained(&self) -> bool { - match self { - RuntimeCall::Ethereum(call) => call.is_self_contained(), - _ => false, - } - } - - fn check_self_contained(&self) -> Option> { - match self { - RuntimeCall::Ethereum(call) => call.check_self_contained(), - _ => None, - } - } - - fn validate_self_contained( - &self, - info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option { - match self { - RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), - _ => None, - } - } - - fn pre_dispatch_self_contained( - &self, - info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option> { - match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - }, - _ => None, - } - } - - fn apply_self_contained( - self, - info: Self::SignedInfo, - ) -> Option>> { - match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) - }, - _ => None, - } - } -} - -pub struct MockedEvmRunner; - -impl tangle_primitives::services::EvmRunner for MockedEvmRunner { - type Error = pallet_evm::Error; - - fn call( - source: sp_core::H160, - target: sp_core::H160, - input: Vec, - value: sp_core::U256, - gas_limit: u64, - is_transactional: bool, - validate: bool, - ) -> Result> { - let max_fee_per_gas = FixedGasPrice::min_gas_price().0; - let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); - let nonce = None; - let access_list = Default::default(); - let weight_limit = None; - let proof_size_base_cost = None; - <::Runner as pallet_evm::Runner>::call( - source, - target, - input, - value, - gas_limit, - Some(max_fee_per_gas), - Some(max_priority_fee_per_gas), - nonce, - access_list, - is_transactional, - validate, - weight_limit, - proof_size_base_cost, - ::config(), - ) - .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) - } -} - -pub struct AccountInfo { - pub address: H160, -} - -pub fn address_build(seed: u8) -> AccountInfo { - let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); - let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); - let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; - let address = H160::from(H256::from(keccak_256(public_key))); - - AccountInfo { address } -} diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index b4854938..056f2110 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -13,10 +13,24 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -use crate::{mock::*, Error, Pallet as Rewards, RewardType}; +use crate::BalanceOf; +use crate::Config; +use crate::Event; +use crate::RewardConfigForAssetVault; +use crate::RewardConfigStorage; +use crate::TotalRewardVaultScore; +use crate::UserClaimedReward; +use crate::{mock::*, Error}; use frame_support::{assert_noop, assert_ok}; +use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::AccountId32; +use sp_runtime::Percent; use tangle_primitives::services::Asset; +use tangle_primitives::types::rewards::BoostInfo; +use tangle_primitives::types::rewards::LockInfo; +use tangle_primitives::types::rewards::LockMultiplier; +use tangle_primitives::types::rewards::UserDepositWithLocks; +use tangle_primitives::types::rewards::UserRewards; // Helper function to set up user rewards fn setup_user_rewards( @@ -37,715 +51,213 @@ fn setup_user_rewards( } #[test] -fn test_whitelist_asset() { +fn test_reward_distribution_with_no_locks() { new_test_ext().execute_with(|| { - let asset = Asset::Custom(0u32); - let account: AccountId32 = AccountId32::new([1; 32]); + // Setup test environment + let account = 1; + let asset = Asset::new(1, 1).unwrap(); + let vault_id = 1; + let apy = Percent::from_percent(10); // 10% APY + let deposit_cap = 1_000_000; + + // Register asset with vault + assert_ok!(RewardsPallet::manage_asset_reward_vault( + RuntimeOrigin::root(), + asset.clone(), + Some(vault_id) + )); - // Non-root cannot whitelist asset - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin + // Set reward config + RewardConfigStorage::::insert( + vault_id, + RewardConfigForAssetVault { apy, deposit_cap }, ); - // Root can whitelist asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - assert!(Rewards::::is_asset_whitelisted(asset)); + // Setup mock deposit (unlocked only) + let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; - // Cannot whitelist same asset twice - assert_noop!( - Rewards::::whitelist_asset(RuntimeOrigin::root(), asset), - Error::::AssetAlreadyWhitelisted - ); - }); -} + // Mock the delegation info + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + }); -#[test] -fn test_remove_asset() { - new_test_ext().execute_with(|| { - let asset = Asset::Custom(0u32); - let account: AccountId32 = AccountId32::new([1; 32]); + // Set total vault score + TotalRewardVaultScore::::insert(vault_id, 100_000); - // Cannot remove non-whitelisted asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); + // Initial balance should be zero + assert_eq!(Balances::free_balance(account), 0); - // Whitelist the asset first - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + // Claim rewards + assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); - // Non-root cannot remove asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::signed(account.clone()), asset), - sp_runtime::DispatchError::BadOrigin - ); - - // Root can remove asset - assert_ok!(Rewards::::remove_asset(RuntimeOrigin::root(), asset)); - assert!(!Rewards::::is_asset_whitelisted(asset)); + // Check that rewards were paid out + assert!(Balances::free_balance(account) > 0); - // Cannot remove already removed asset - assert_noop!( - Rewards::::remove_asset(RuntimeOrigin::root(), asset), - Error::::AssetNotWhitelisted - ); - }); -} - -#[test] -fn test_claim_rewards() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Cannot claim rewards for non-whitelisted asset - assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), - Error::::AssetNotWhitelisted + // Verify event was emitted + System::assert_has_event( + Event::RewardsClaimed { account, asset, amount: Balances::free_balance(account) } + .into(), ); - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Cannot claim rewards when none are available - assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), - Error::::NoRewardsAvailable - ); + // Verify last claim was updated + assert!(UserClaimedReward::::contains_key(account, vault_id)); }); } #[test] -fn test_reward_score_calculation() { +fn test_reward_distribution_with_locks() { new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let custom_asset = Asset::Custom(0u32); - let erc20_asset = Asset::Erc20(mock_address(1)); - let reward_type = RewardType::Restaking; - - // Whitelist both assets - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), custom_asset)); - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), erc20_asset)); - - // Set up rewards for custom asset with boost - setup_user_rewards::( - account.clone(), - custom_asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); - - // Set up rewards for ERC20 asset without boost - setup_user_rewards::( - account.clone(), - erc20_asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry - ); - - // Test claiming rewards for both assets - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - custom_asset, - reward_type - )); - - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - erc20_asset, - reward_type + // Setup test environment + let account = 1; + let asset = Asset::new(1, 1).unwrap(); + let vault_id = 1; + let apy = Percent::from_percent(10); // 10% APY + let deposit_cap = 1_000_000; + + // Register asset with vault + assert_ok!(RewardsPallet::manage_asset_reward_vault( + RuntimeOrigin::root(), + asset.clone(), + Some(vault_id) )); - // Verify rewards are cleared after claiming - let custom_rewards = Rewards::::user_rewards(account.clone(), custom_asset); - assert_eq!(custom_rewards.restaking_rewards, 0u128.into()); + // Set reward config + RewardConfigStorage::::insert( + vault_id, + RewardConfigForAssetVault { apy, deposit_cap }, + ); - let erc20_rewards = Rewards::::user_rewards(account.clone(), erc20_asset); - assert_eq!(erc20_rewards.restaking_rewards, 0u128.into()); - }); -} + // Setup mock deposit with locks + let current_block = System::block_number(); + let locks = vec![ + LockInfo { + amount: 50_000, + lock_multiplier: LockMultiplier::TwoMonths, + expiry_block: current_block + 100, + }, + LockInfo { + amount: 25_000, + lock_multiplier: LockMultiplier::ThreeMonths, + expiry_block: current_block + 150, + }, + ]; -#[test] -fn test_reward_distribution() { - new_test_ext().execute_with(|| { - let account1: AccountId32 = AccountId32::new([1; 32]); - let account2: AccountId32 = AccountId32::new([2; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up different rewards for each account - setup_user_rewards::( - account1.clone(), - asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); + let deposit = + UserDepositWithLocks { unlocked_amount: 25_000, amount_with_locks: Some(locks) }; - setup_user_rewards::( - account2.clone(), - asset, - 200u128.into(), // restaking rewards - 100u128.into(), // service rewards - 400u128.into(), // boost amount - LockMultiplier::SixMonths, - 200u64.into(), // expiry block - ); + // Mock the delegation info + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + }); - // Both accounts should be able to claim their rewards - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account1.clone()), - asset, - reward_type - )); + // Set total vault score + TotalRewardVaultScore::::insert(vault_id, 100_000); - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account2.clone()), - asset, - reward_type - )); + // Initial balance should be zero + assert_eq!(Balances::free_balance(account), 0); - // Verify rewards are cleared after claiming - let account1_rewards = Rewards::::user_rewards(account1, asset); - assert_eq!(account1_rewards.restaking_rewards, 0u128.into()); + // Claim rewards + assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); - let account2_rewards = Rewards::::user_rewards(account2, asset); - assert_eq!(account2_rewards.restaking_rewards, 0u128.into()); - }); -} + // Check that rewards were paid out and are higher than no-lock case due to multipliers + let rewards = Balances::free_balance(account); + assert!(rewards > 0); -#[test] -fn test_different_reward_types() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up rewards for different reward types - setup_user_rewards::( - account.clone(), - asset, - 100u128.into(), // restaking rewards - 150u128.into(), // service rewards - 200u128.into(), // boost amount - LockMultiplier::ThreeMonths, - 100u64.into(), // expiry block - ); + // Verify event was emitted + System::assert_has_event(Event::RewardsClaimed { account, asset, amount: rewards }.into()); - // Test claiming each type of reward - let reward_types = vec![RewardType::Restaking, RewardType::Service, RewardType::Boost]; - - for reward_type in reward_types { - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - )); - } - - // Verify all rewards are cleared - let rewards = Rewards::::user_rewards(account, asset); - assert_eq!(rewards.restaking_rewards, 0u128.into()); - assert_eq!(rewards.service_rewards, 0u128.into()); - assert_eq!(rewards.boost_rewards.amount, 0u128.into()); + // Verify last claim was updated + let (claim_block, total_rewards) = + UserClaimedReward::::get(account, vault_id).unwrap(); + assert_eq!(claim_block, System::block_number()); + assert!(total_rewards > rewards); // Total rewards should be higher than paid amount due to previous claims }); } #[test] -fn test_multiple_claims() { +fn test_reward_distribution_errors() { new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - - // Whitelist the asset - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Set up initial rewards - setup_user_rewards::( - account.clone(), - asset, - 100u128.into(), // restaking rewards - 50u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry - ); - - // First claim should succeed - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - )); + let account = 1; + let asset = Asset::new(1, 1).unwrap(); - // Second claim should fail as rewards are cleared + // Asset not in vault assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), - Error::::NoRewardsAvailable - ); - - // Set up new rewards - setup_user_rewards::( - account.clone(), - asset, - 200u128.into(), // restaking rewards - 100u128.into(), // service rewards - 0u128.into(), // no boost - LockMultiplier::OneMonth, - 0u64.into(), // no expiry + RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), + Error::::AssetNotInVault ); - // Should be able to claim again with new rewards - assert_ok!(Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type + // Register asset with vault + let vault_id = 1; + assert_ok!(RewardsPallet::manage_asset_reward_vault( + RuntimeOrigin::root(), + asset.clone(), + Some(vault_id) )); - }); -} - -#[test] -fn test_edge_cases() { - new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - let reward_type = RewardType::Restaking; - // Test with zero rewards - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); + // No deposits assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset, - reward_type - ), + RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), Error::::NoRewardsAvailable ); - // Test with invalid asset ID - let invalid_asset = Asset::Custom(u32::MAX); - assert_noop!( - Rewards::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - invalid_asset, - reward_type - ), - Error::::AssetNotWhitelisted - ); - }); -} - -#[test] -fn test_rewards_manager_implementation() { - new_test_ext().execute_with(|| { - use tangle_primitives::traits::rewards::RewardsManager; - - let account: AccountId32 = AccountId32::new([1; 32]); - let asset = Asset::Custom(0u32); - - // Whitelist the asset first - assert_ok!(Rewards::::whitelist_asset(RuntimeOrigin::root(), asset)); - - // Test recording delegation reward - assert_ok!(Rewards::::record_delegation_reward( - &account, - asset, - 100u128.into(), - 3, // 3 months lock - )); - - // Verify delegation rewards - let delegation_rewards = Rewards::::query_delegation_rewards(&account, asset) - .expect("Should return delegation rewards"); - assert_eq!(delegation_rewards, 100u128.into()); - - // Test recording service reward - assert_ok!(Rewards::::record_service_reward(&account, asset, 50u128.into(),)); - - // Verify service rewards - let service_rewards = Rewards::::query_service_rewards(&account, asset) - .expect("Should return service rewards"); - assert_eq!(service_rewards, 50u128.into()); - - // Test querying total rewards - let (delegation, service) = Rewards::::query_rewards(&account, asset) - .expect("Should return total rewards"); - assert_eq!(delegation, 100u128.into()); - assert_eq!(service, 50u128.into()); - - // Test recording rewards for non-whitelisted asset - let non_whitelisted = Asset::Custom(1u32); - assert_eq!( - Rewards::::record_delegation_reward( - &account, - non_whitelisted, - 100u128.into(), - 3 - ), - Err("Asset not whitelisted") - ); - assert_eq!( - Rewards::::record_service_reward(&account, non_whitelisted, 50u128.into()), - Err("Asset not whitelisted") - ); - - // Test invalid lock multiplier - assert_eq!( - Rewards::::record_delegation_reward(&account, asset, 100u128.into(), 4), - Err("Invalid lock multiplier") - ); - - // Test accumulating rewards - assert_ok!( - Rewards::::record_delegation_reward(&account, asset, 50u128.into(), 3,) - ); - assert_ok!(Rewards::::record_service_reward(&account, asset, 25u128.into(),)); - - let (delegation, service) = Rewards::::query_rewards(&account, asset) - .expect("Should return total rewards"); - assert_eq!(delegation, 150u128.into()); // 100 + 50 - assert_eq!(service, 75u128.into()); // 50 + 25 - }); -} - -#[test] -fn test_update_asset_rewards_should_fail_for_non_root() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - let rewards = 1_000; - - // Act & Assert - assert_noop!( - Rewards::update_asset_rewards(RuntimeOrigin::signed(who), asset_id, rewards), - DispatchError::BadOrigin - ); - }); -} + // Setup mock deposit but no reward config + let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; -#[test] -fn test_update_asset_apy_should_fail_for_non_root() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - let apy = 500; // 5% + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + }); - // Act & Assert + // No reward config assert_noop!( - Rewards::update_asset_apy(RuntimeOrigin::signed(who), asset_id, apy), - DispatchError::BadOrigin - ); - }); -} - -#[test] -fn test_reward_score_calculation_with_zero_values() { - new_test_ext().execute_with(|| { - // Arrange - let who = AccountId::from(Bob); - let asset_id = Asset::Custom(1); - - // Test with zero stake - assert_eq!( - Rewards::calculate_reward_score(0, 1000, 500), - 0, - "Reward score should be 0 with zero stake" - ); - - // Test with zero rewards - assert_eq!( - Rewards::calculate_reward_score(1000, 0, 500), - 0, - "Reward score should be 0 with zero rewards" - ); - - // Test with zero APY - assert_eq!( - Rewards::calculate_reward_score(1000, 1000, 0), - 0, - "Reward score should be 0 with zero APY" - ); - }); -} - -#[test] -fn test_reward_score_calculation_with_large_values() { - new_test_ext().execute_with(|| { - // Test with maximum possible values - let max_balance = u128::MAX; - let large_apy = 10_000; // 100% - - // Should not overflow - let score = Rewards::calculate_reward_score(max_balance, max_balance, large_apy); - assert!(score > 0, "Reward score should not overflow with large values"); - }); -} - -#[test] -fn test_rewards_should_fail_with_overflow() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - - // Try to set rewards to maximum value - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - u128::MAX - )); - - // Try to set APY to maximum value - this should cause overflow in calculations - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), u32::MAX)); - - // Attempting to calculate reward score with max values should return 0 to prevent overflow - let score = Rewards::calculate_reward_score(u128::MAX, u128::MAX, u32::MAX); - assert_eq!(score, 0, "Should handle potential overflow gracefully"); - }); -} - -#[test] -fn test_rewards_with_invalid_asset() { - new_test_ext().execute_with(|| { - let invalid_asset = Asset::Custom(u32::MAX); - let rewards = 1_000; - let apy = 500; - - // Should succeed but have no effect since asset doesn't exist - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - invalid_asset.clone(), - rewards - )); - - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), invalid_asset.clone(), apy)); - - // Verify no rewards are available for invalid asset - assert_eq!(Rewards::asset_rewards(invalid_asset.clone()), 0); - assert_eq!(Rewards::asset_apy(invalid_asset.clone()), 0); - }); -} - -#[test] -fn test_rewards_with_zero_stake() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let rewards = 1_000; - let apy = 500; - - // Set up rewards and APY - assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset_id.clone(), rewards)); - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), apy)); - - // Calculate rewards for zero stake - let reward_score = Rewards::calculate_reward_score(0, rewards, apy); - assert_eq!(reward_score, 0, "Zero stake should result in zero rewards"); - - // Verify total rewards score is zero when no stakes exist - let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); - assert_eq!(total_score, 0, "Total score should be zero when no stakes exist"); - }); -} - -#[test] -fn test_rewards_with_extreme_apy_values() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let stake = 1_000; - let rewards = 1_000; - - // Test extremely high APY (10000% = 100x) - let extreme_apy = 1_000_000; // 10000% - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), extreme_apy)); - - let score = Rewards::calculate_reward_score(stake, rewards, extreme_apy); - assert!(score > 0, "Should handle extreme APY values"); - assert!(score > rewards, "High APY should result in higher rewards"); - - // Test with minimum possible APY - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), 1)); - - let min_score = Rewards::calculate_reward_score(stake, rewards, 1); - assert!(min_score < score, "Minimum APY should result in lower rewards"); - }); -} - -#[test] -fn test_rewards_accumulation() { - new_test_ext().execute_with(|| { - let asset_id = Asset::Custom(1); - let initial_rewards = 1_000; - let additional_rewards = 500; - - // Set initial rewards - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - initial_rewards - )); - - // Try to add more rewards - should replace, not accumulate - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - additional_rewards - )); - - assert_eq!( - Rewards::asset_rewards(asset_id.clone()), - additional_rewards, - "Rewards should be replaced, not accumulated" + RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), + Error::::RewardConfigNotFound ); }); } #[test] -fn test_rewards_with_multiple_assets() { +fn test_subsequent_reward_claims() { new_test_ext().execute_with(|| { - let asset1 = Asset::Custom(1); - let asset2 = Asset::Custom(2); - let rewards1 = 1_000; - let rewards2 = 2_000; - let apy1 = 500; - let apy2 = 1_000; - - // Set different rewards and APY for different assets - assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset1.clone(), rewards1)); - assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset2.clone(), rewards2)); - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset1.clone(), apy1)); - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset2.clone(), apy2)); - - // Verify each asset maintains its own rewards and APY - assert_eq!(Rewards::asset_rewards(asset1.clone()), rewards1); - assert_eq!(Rewards::asset_rewards(asset2.clone()), rewards2); - assert_eq!(Rewards::asset_apy(asset1.clone()), apy1); - assert_eq!(Rewards::asset_apy(asset2.clone()), apy2); - - // Verify reward scores are calculated independently - let stake = 1_000; - let score1 = Rewards::calculate_reward_score(stake, rewards1, apy1); - let score2 = Rewards::calculate_reward_score(stake, rewards2, apy2); - assert_ne!(score1, score2, "Different assets should have different reward scores"); - }); -} - -#[test] -fn test_update_asset_rewards_multiple_times() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let initial_rewards = 1_000; - let updated_rewards = 2_000; + // Setup test environment similar to first test + let account = 1; + let asset = Asset::new(1, 1).unwrap(); + let vault_id = 1; - // Act - Update rewards multiple times - assert_ok!(Rewards::update_asset_rewards( + // Setup basic reward config + assert_ok!(RewardsPallet::manage_asset_reward_vault( RuntimeOrigin::root(), - asset_id.clone(), - initial_rewards + asset.clone(), + Some(vault_id) )); - assert_ok!(Rewards::update_asset_rewards( - RuntimeOrigin::root(), - asset_id.clone(), - updated_rewards - )); - - // Assert - assert_eq!( - Rewards::asset_rewards(asset_id), - updated_rewards, - "Asset rewards should be updated to latest value" + RewardConfigStorage::::insert( + vault_id, + RewardConfigForAssetVault { apy: Percent::from_percent(10), deposit_cap: 1_000_000 }, ); - }); -} -#[test] -fn test_update_asset_apy_multiple_times() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let initial_apy = 500; // 5% - let updated_apy = 1_000; // 10% + // Setup mock deposit + let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; - // Act - Update APY multiple times - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), initial_apy)); + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + }); - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), updated_apy)); + TotalRewardVaultScore::::insert(vault_id, 100_000); - // Assert - assert_eq!( - Rewards::asset_apy(asset_id), - updated_apy, - "Asset APY should be updated to latest value" - ); - }); -} + // First claim + assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); + let first_reward = Balances::free_balance(account); + assert!(first_reward > 0); -#[test] -fn test_reward_distribution_with_zero_total_score() { - new_test_ext().execute_with(|| { - // Arrange - let asset_id = Asset::Custom(1); - let rewards = 1_000; - let apy = 500; // 5% - - // Update rewards and APY - assert_ok!(Rewards::update_asset_rewards(RuntimeOrigin::root(), asset_id.clone(), rewards)); - assert_ok!(Rewards::update_asset_apy(RuntimeOrigin::root(), asset_id.clone(), apy)); - - // With no stakes, total score should be 0 - let total_score = Rewards::calculate_total_reward_score(asset_id.clone()); - assert_eq!(total_score, 0, "Total score should be 0 with no stakes"); - }); -} + // Advance some blocks + run_to_block(100); -#[test] -fn test_reward_score_calculation_with_different_apy_ranges() { - new_test_ext().execute_with(|| { - let stake = 1_000; - let rewards = 1_000; - - // Test with different APY ranges - let apys = vec![ - 0, // 0% - 100, // 1% - 500, // 5% - 1_000, // 10% - 5_000, // 50% - 10_000, // 100% - ]; + // Second claim + assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); + let second_reward = Balances::free_balance(account) - first_reward; - for apy in apys { - let score = Rewards::calculate_reward_score(stake, rewards, apy); - assert!(score >= 0, "Reward score should be non-negative for APY {}", apy); - } + // Second reward should be non-zero but less than first reward + assert!(second_reward > 0); + assert!(second_reward < first_reward); }); } From 71bdc5d09ad594510d741cfe2114294d7aabc7cb Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:56:33 +0530 Subject: [PATCH 55/63] wip tests --- pallets/rewards/src/lib.rs | 31 +++- pallets/rewards/src/mock.rs | 18 +- pallets/rewards/src/mock_evm.rs | 295 ++++++++++++++++++++++++++++++++ pallets/rewards/src/tests.rs | 19 +- pallets/rewards/src/types.rs | 2 +- 5 files changed, 338 insertions(+), 27 deletions(-) create mode 100644 pallets/rewards/src/mock_evm.rs diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 668f10cc..42b8515b 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -26,6 +26,9 @@ pub use pallet::*; #[cfg(test)] mod mock; +#[cfg(test)] +mod mock_evm; + #[cfg(test)] mod tests; @@ -166,11 +169,13 @@ pub mod pallet { BlueprintWhitelisted { blueprint_id: BlueprintId }, /// Asset has been updated to reward vault AssetUpdatedInVault { - who: T::AccountId, vault_id: T::VaultId, asset_id: Asset, action: AssetAction, }, + VaultRewardConfigUpdated { + vault_id: T::VaultId, + } } #[pallet::error] @@ -204,7 +209,8 @@ pub mod pallet { #[pallet::call] impl Pallet { /// Claim rewards for a specific asset and reward type - #[pallet::weight(10_000)] + #[pallet::call_index(1)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn claim_rewards(origin: OriginFor, asset: Asset) -> DispatchResult { let who = ensure_signed(origin)?; @@ -231,25 +237,38 @@ pub mod pallet { /// /// * [`Error::AssetAlreadyInVault`] - Asset already exists in vault /// * [`Error::AssetNotInVault`] - Asset does not exist in vault - #[pallet::call_index(20)] + #[pallet::call_index(2)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn manage_asset_in_vault( + pub fn manage_asset_reward_vault( origin: OriginFor, vault_id: T::VaultId, asset_id: Asset, action: AssetAction, ) -> DispatchResult { - let who = ensure_signed(origin)?; + let who = T::ForceOrigin::ensure_origin(origin)?; match action { AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, AssetAction::Remove => Self::remove_asset_from_vault(&vault_id, &asset_id)?, } - Self::deposit_event(Event::AssetUpdatedInVault { who, vault_id, asset_id, action }); + Self::deposit_event(Event::AssetUpdatedInVault { vault_id, asset_id, action }); Ok(()) } + + #[pallet::call_index(3)] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + pub fn udpate_vault_reward_config( + origin: OriginFor, + vault_id: T::VaultId, + new_config: RewardConfigForAssetVault>, + ) -> DispatchResult { + let who = T::ForceOrigin::ensure_origin(origin)?; + RewardConfigStorage::::insert(vault_id, new_config); + Self::deposit_event(Event::VaultRewardConfigUpdated { vault_id }); + Ok(()) + } } impl Pallet { diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index cc722ca8..00572394 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -27,6 +27,7 @@ use frame_support::{ traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, PalletId, }; +use crate::mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -45,7 +46,7 @@ use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRun use tangle_primitives::types::rewards::UserDepositWithLocks; use core::ops::Mul; -use std::{collections::BTreeMap, sync::Arc}; +use std::{cell::RefCell, collections::BTreeMap, sync::Arc}; pub type AccountId = AccountId32; pub type Balance = u128; @@ -278,6 +279,15 @@ impl pallet_rewards::Config for Runtime { type ForceOrigin = frame_system::EnsureRoot; } +thread_local! { + pub static MOCK_DELEGATION_INFO: RefCell = RefCell::new(MockDelegationData::default()); +} + +#[derive(Default)] +pub struct MockDelegationData { + pub deposits: BTreeMap<(AccountId, Asset), UserDepositWithLocks>, +} + pub struct MockDelegationManager; impl tangle_primitives::traits::MultiAssetDelegationInfo for MockDelegationManager @@ -332,7 +342,9 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo, ) -> Option> { - None + MOCK_DELEGATION_INFO.with(|delegation_info| { + delegation_info.borrow().deposits.get(&(who.clone(), asset_id)).cloned() + }) } } @@ -364,6 +376,8 @@ construct_runtime!( Timestamp: pallet_timestamp, Balances: pallet_balances, Assets: pallet_assets, + EVM: pallet_evm, + Ethereum: pallet_ethereum, Session: pallet_session, Staking: pallet_staking, Historical: pallet_session_historical, diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs new file mode 100644 index 00000000..c386b2b2 --- /dev/null +++ b/pallets/rewards/src/mock_evm.rs @@ -0,0 +1,295 @@ +// This file is part of Tangle. +// Copyright (C) 2022-2024 Tangle Foundation. +// +// Tangle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Tangle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Tangle. If not, see . +#![allow(clippy::all)] +use crate as pallet_rewards; +use crate::mock::{ + AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, +}; +use fp_evm::FeeCalculator; +use frame_support::{ + parameter_types, + traits::{Currency, FindAuthor, OnUnbalanced}, + weights::Weight, + PalletId, +}; +use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; +use pallet_evm::{ + EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, OnChargeEVMTransaction, +}; +use sp_core::{keccak_256, ConstU32, H160, H256, U256}; +use sp_runtime::{ + traits::{BlakeTwo256, DispatchInfoOf, Dispatchable}, + transaction_validity::{TransactionValidity, TransactionValidityError}, + ConsensusEngineId, +}; + +use pallet_evm_precompile_blake2::Blake2F; +use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +use precompile_utils::precompile_set::{ + AcceptDelegateCall, AddressU64, CallableByContract, CallableByPrecompile, PrecompileAt, + PrecompileSetBuilder, PrecompilesInRangeInclusive, +}; + +type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile); + +#[precompile_utils::precompile_name_from_address] +pub type DefaultPrecompiles = ( + // Ethereum precompiles: + PrecompileAt, ECRecover, EthereumPrecompilesChecks>, + PrecompileAt, Sha256, EthereumPrecompilesChecks>, + PrecompileAt, Ripemd160, EthereumPrecompilesChecks>, + PrecompileAt, Identity, EthereumPrecompilesChecks>, + PrecompileAt, Modexp, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Add, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Mul, EthereumPrecompilesChecks>, + PrecompileAt, Bn128Pairing, EthereumPrecompilesChecks>, + PrecompileAt, Blake2F, EthereumPrecompilesChecks>, + PrecompileAt, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>, + PrecompileAt, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>, +); + +pub type TanglePrecompiles = PrecompileSetBuilder< + R, + (PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<2095>), DefaultPrecompiles>,), +>; + +parameter_types! { + pub const MinimumPeriod: u64 = 6000 / 2; + + pub PrecompilesValue: TanglePrecompiles = TanglePrecompiles::<_>::new(); +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + (1.into(), Weight::zero()) + } +} + +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(address_build(0).address) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub const TransactionByteFee: u64 = 1; + pub const ChainId: u64 = 42; + pub const EVMModuleId: PalletId = PalletId(*b"py/evmpa"); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub const WeightPerGas: Weight = Weight::from_parts(20_000, 0); +} + +parameter_types! { + pub SuicideQuickClearLimit: u32 = 0; +} + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + fn on_unbalanceds(_fees_then_tips: impl Iterator) { + // whatever + } +} +pub struct FreeEVMExecution; + +impl OnChargeEVMTransaction for FreeEVMExecution { + type LiquidityInfo = (); + + fn withdraw_fee( + _who: &H160, + _fee: U256, + ) -> Result> { + Ok(()) + } + + fn correct_and_deposit_fee( + _who: &H160, + _corrected_fee: U256, + _base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + already_withdrawn + } + + fn pay_priority_fee(_tip: Self::LiquidityInfo) {} +} + +/// Type alias for negative imbalance during fees +type RuntimeNegativeImbalance = + ::AccountId>>::NegativeImbalance; + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = EthereumBlockHashMapping; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = HashedAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = TanglePrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = ChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = (); + type OnCreate = (); + type SuicideQuickClearLimit = SuicideQuickClearLimit; + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + }, + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from(RawOrigin::EthereumTransaction(info)))) + }, + _ => None, + } + } +} + +pub struct MockedEvmRunner; + +impl tangle_primitives::services::EvmRunner for MockedEvmRunner { + type Error = pallet_evm::Error; + + fn call( + source: sp_core::H160, + target: sp_core::H160, + input: Vec, + value: sp_core::U256, + gas_limit: u64, + is_transactional: bool, + validate: bool, + ) -> Result> { + let max_fee_per_gas = FixedGasPrice::min_gas_price().0; + let max_priority_fee_per_gas = max_fee_per_gas.saturating_mul(U256::from(2)); + let nonce = None; + let access_list = Default::default(); + let weight_limit = None; + let proof_size_base_cost = None; + <::Runner as pallet_evm::Runner>::call( + source, + target, + input, + value, + gas_limit, + Some(max_fee_per_gas), + Some(max_priority_fee_per_gas), + nonce, + access_list, + is_transactional, + validate, + weight_limit, + proof_size_base_cost, + ::config(), + ) + .map_err(|o| tangle_primitives::services::RunnerError { error: o.error, weight: o.weight }) + } +} + +pub struct AccountInfo { + pub address: H160, +} + +pub fn address_build(seed: u8) -> AccountInfo { + let private_key = H256::from_slice(&[(seed + 1); 32]); //H256::from_low_u64_be((i + 1) as u64); + let secret_key = libsecp256k1::SecretKey::parse_slice(&private_key[..]).unwrap(); + let public_key = &libsecp256k1::PublicKey::from_secret_key(&secret_key).serialize()[1..65]; + let address = H160::from(H256::from(keccak_256(public_key))); + + AccountInfo { address } +} diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 056f2110..d9172ee2 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -32,30 +32,13 @@ use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::types::rewards::UserDepositWithLocks; use tangle_primitives::types::rewards::UserRewards; -// Helper function to set up user rewards -fn setup_user_rewards( - account: T::AccountId, - asset: Asset, - restaking_rewards: BalanceOf, - service_rewards: BalanceOf, - boost_amount: BalanceOf, - multiplier: LockMultiplier, - expiry: BlockNumberFor, -) { - let rewards = UserRewards { - restaking_rewards, - service_rewards, - boost_rewards: BoostInfo { amount: boost_amount, multiplier, expiry }, - }; - UserRewards::::insert(account, asset, rewards); -} #[test] fn test_reward_distribution_with_no_locks() { new_test_ext().execute_with(|| { // Setup test environment let account = 1; - let asset = Asset::new(1, 1).unwrap(); + let asset = Asset::Custom(1); let vault_id = 1; let apy = Percent::from_percent(10); // 10% APY let deposit_cap = 1_000_000; diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index dbbc117f..2e277e4f 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -30,7 +30,7 @@ pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Configuration for rewards associated with a specific asset. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] pub struct RewardConfigForAssetVault { // The annual percentage yield (APY) for the asset, represented as a Percent pub apy: Percent, From d8768dd8aed1a35bedc62205fce5e742740e4f37 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:21:40 +0530 Subject: [PATCH 56/63] tests passing --- pallets/rewards/src/lib.rs | 18 +- pallets/rewards/src/mock.rs | 6 +- pallets/rewards/src/tests.rs | 336 ++++++++++++++++++----------------- 3 files changed, 186 insertions(+), 174 deletions(-) diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 42b8515b..9bf3fbb0 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -162,11 +162,21 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// Rewards have been claimed by an account - RewardsClaimed { account: T::AccountId, asset: Asset, amount: BalanceOf }, + RewardsClaimed { + account: T::AccountId, + asset: Asset, + amount: BalanceOf, + }, /// Event emitted when an incentive APY and cap are set for a reward vault - IncentiveAPYAndCapSet { vault_id: T::VaultId, apy: sp_runtime::Percent, cap: BalanceOf }, + IncentiveAPYAndCapSet { + vault_id: T::VaultId, + apy: sp_runtime::Percent, + cap: BalanceOf, + }, /// Event emitted when a blueprint is whitelisted for rewards - BlueprintWhitelisted { blueprint_id: BlueprintId }, + BlueprintWhitelisted { + blueprint_id: BlueprintId, + }, /// Asset has been updated to reward vault AssetUpdatedInVault { vault_id: T::VaultId, @@ -175,7 +185,7 @@ pub mod pallet { }, VaultRewardConfigUpdated { vault_id: T::VaultId, - } + }, } #[pallet::error] diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 00572394..4ba77a51 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] +use crate::mock_evm::MockedEvmRunner; use crate::{self as pallet_rewards}; use ethabi::Uint; use frame_election_provider_support::{ @@ -27,7 +28,6 @@ use frame_support::{ traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, PalletId, }; -use crate::mock_evm::MockedEvmRunner; use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -280,12 +280,12 @@ impl pallet_rewards::Config for Runtime { } thread_local! { - pub static MOCK_DELEGATION_INFO: RefCell = RefCell::new(MockDelegationData::default()); + pub static MOCK_DELEGATION_INFO: RefCell = RefCell::new(MockDelegationData::default()); } #[derive(Default)] pub struct MockDelegationData { - pub deposits: BTreeMap<(AccountId, Asset), UserDepositWithLocks>, + pub deposits: BTreeMap<(AccountId, Asset), UserDepositWithLocks>, } pub struct MockDelegationManager; diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index d9172ee2..21b40eab 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -12,235 +12,237 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . -use crate::BalanceOf; -use crate::Config; -use crate::Event; -use crate::RewardConfigForAssetVault; -use crate::RewardConfigStorage; -use crate::TotalRewardVaultScore; -use crate::UserClaimedReward; -use crate::{mock::*, Error}; +// along with Tangle. If not, see . +use crate::{ + mock::*, types::*, AssetAction, Error, Event, Pallet as RewardsPallet, UserClaimedReward, +}; use frame_support::{assert_noop, assert_ok}; -use frame_system::pallet_prelude::BlockNumberFor; -use sp_runtime::AccountId32; -use sp_runtime::Percent; -use tangle_primitives::services::Asset; -use tangle_primitives::types::rewards::BoostInfo; +use sp_runtime::{AccountId32, Percent}; use tangle_primitives::types::rewards::LockInfo; use tangle_primitives::types::rewards::LockMultiplier; -use tangle_primitives::types::rewards::UserDepositWithLocks; -use tangle_primitives::types::rewards::UserRewards; - +use tangle_primitives::{ + services::Asset, + types::rewards::{UserDepositWithLocks, UserRewards}, +}; + +fn run_to_block(n: u64) { + while System::block_number() < n { + System::set_block_number(System::block_number() + 1); + } +} #[test] -fn test_reward_distribution_with_no_locks() { +fn test_claim_rewards() { new_test_ext().execute_with(|| { - // Setup test environment - let account = 1; - let asset = Asset::Custom(1); - let vault_id = 1; - let apy = Percent::from_percent(10); // 10% APY - let deposit_cap = 1_000_000; - - // Register asset with vault - assert_ok!(RewardsPallet::manage_asset_reward_vault( + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); + let deposit = 100; + let apy = Percent::from_percent(10); + let deposit_cap = 1000; + let boost_multiplier = Some(150); + let incentive_cap = 1000; + + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( RuntimeOrigin::root(), - asset.clone(), - Some(vault_id) + vault_id, + RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } )); - // Set reward config - RewardConfigStorage::::insert( + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( + RuntimeOrigin::root(), vault_id, - RewardConfigForAssetVault { apy, deposit_cap }, - ); - - // Setup mock deposit (unlocked only) - let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; + asset.clone(), + AssetAction::Add, + )); - // Mock the delegation info + // Mock deposit with UserDepositWithLocks MOCK_DELEGATION_INFO.with(|m| { - m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + m.borrow_mut().deposits.insert( + (account.clone(), asset.clone()), + UserDepositWithLocks { unlocked_amount: deposit, amount_with_locks: None }, + ); }); - // Set total vault score - TotalRewardVaultScore::::insert(vault_id, 100_000); - - // Initial balance should be zero - assert_eq!(Balances::free_balance(account), 0); + // Initial balance should be 0 + assert_eq!(Balances::free_balance(&account), 0); // Claim rewards - assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); + assert_ok!(RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + )); - // Check that rewards were paid out - assert!(Balances::free_balance(account) > 0); + // Balance should be greater than 0 after claiming rewards + assert!(Balances::free_balance(&account) > 0); - // Verify event was emitted + // Check events System::assert_has_event( - Event::RewardsClaimed { account, asset, amount: Balances::free_balance(account) } - .into(), + Event::RewardsClaimed { + account: account.clone(), + asset: asset.clone(), + amount: Balances::free_balance(&account), + } + .into(), ); - // Verify last claim was updated - assert!(UserClaimedReward::::contains_key(account, vault_id)); + // Check storage + assert!(UserClaimedReward::::contains_key(&account, vault_id)); }); } #[test] -fn test_reward_distribution_with_locks() { +fn test_claim_rewards_with_invalid_asset() { new_test_ext().execute_with(|| { - // Setup test environment - let account = 1; - let asset = Asset::new(1, 1).unwrap(); - let vault_id = 1; - let apy = Percent::from_percent(10); // 10% APY - let deposit_cap = 1_000_000; - - // Register asset with vault - assert_ok!(RewardsPallet::manage_asset_reward_vault( - RuntimeOrigin::root(), - asset.clone(), - Some(vault_id) - )); + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); - // Set reward config - RewardConfigStorage::::insert( - vault_id, - RewardConfigForAssetVault { apy, deposit_cap }, + // Try to claim rewards for an asset that doesn't exist in the vault + assert_noop!( + RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + ), + Error::::AssetNotInVault ); - // Setup mock deposit with locks - let current_block = System::block_number(); - let locks = vec![ - LockInfo { - amount: 50_000, - lock_multiplier: LockMultiplier::TwoMonths, - expiry_block: current_block + 100, - }, - LockInfo { - amount: 25_000, - lock_multiplier: LockMultiplier::ThreeMonths, - expiry_block: current_block + 150, - }, - ]; - - let deposit = - UserDepositWithLocks { unlocked_amount: 25_000, amount_with_locks: Some(locks) }; - - // Mock the delegation info - MOCK_DELEGATION_INFO.with(|m| { - m.borrow_mut().deposits.insert((account, asset.clone()), deposit); - }); - - // Set total vault score - TotalRewardVaultScore::::insert(vault_id, 100_000); - - // Initial balance should be zero - assert_eq!(Balances::free_balance(account), 0); - - // Claim rewards - assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); - - // Check that rewards were paid out and are higher than no-lock case due to multipliers - let rewards = Balances::free_balance(account); - assert!(rewards > 0); + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: 1000, + incentive_cap: 1000, + boost_multiplier: Some(150), + } + )); - // Verify event was emitted - System::assert_has_event(Event::RewardsClaimed { account, asset, amount: rewards }.into()); + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset.clone(), + AssetAction::Add, + )); - // Verify last claim was updated - let (claim_block, total_rewards) = - UserClaimedReward::::get(account, vault_id).unwrap(); - assert_eq!(claim_block, System::block_number()); - assert!(total_rewards > rewards); // Total rewards should be higher than paid amount due to previous claims + // Try to claim rewards without any deposit + assert_noop!( + RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + ), + Error::::NoRewardsAvailable + ); }); } #[test] -fn test_reward_distribution_errors() { +fn test_claim_rewards_with_no_deposit() { new_test_ext().execute_with(|| { - let account = 1; - let asset = Asset::new(1, 1).unwrap(); + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); - // Asset not in vault - assert_noop!( - RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), - Error::::AssetNotInVault - ); + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: 1000, + incentive_cap: 1000, + boost_multiplier: Some(150), + } + )); - // Register asset with vault - let vault_id = 1; - assert_ok!(RewardsPallet::manage_asset_reward_vault( + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), + vault_id, asset.clone(), - Some(vault_id) + AssetAction::Add, )); - // No deposits + // Try to claim rewards without any deposit assert_noop!( - RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), + RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + ), Error::::NoRewardsAvailable ); - - // Setup mock deposit but no reward config - let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; - - MOCK_DELEGATION_INFO.with(|m| { - m.borrow_mut().deposits.insert((account, asset.clone()), deposit); - }); - - // No reward config - assert_noop!( - RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone()), - Error::::RewardConfigNotFound - ); }); } #[test] -fn test_subsequent_reward_claims() { +fn test_claim_rewards_multiple_times() { new_test_ext().execute_with(|| { - // Setup test environment similar to first test - let account = 1; - let asset = Asset::new(1, 1).unwrap(); - let vault_id = 1; + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); + let deposit = 100; - // Setup basic reward config - assert_ok!(RewardsPallet::manage_asset_reward_vault( + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( RuntimeOrigin::root(), - asset.clone(), - Some(vault_id) + vault_id, + RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: 1000, + incentive_cap: 1000, + boost_multiplier: Some(150), + } )); - RewardConfigStorage::::insert( + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( + RuntimeOrigin::root(), vault_id, - RewardConfigForAssetVault { apy: Percent::from_percent(10), deposit_cap: 1_000_000 }, - ); - - // Setup mock deposit - let deposit = UserDepositWithLocks { unlocked_amount: 100_000, amount_with_locks: None }; + asset.clone(), + AssetAction::Add, + )); + // Mock deposit MOCK_DELEGATION_INFO.with(|m| { - m.borrow_mut().deposits.insert((account, asset.clone()), deposit); + m.borrow_mut().deposits.insert( + (account.clone(), asset.clone()), + UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: Some(vec![LockInfo { + amount: deposit, + expiry_block: 3000_u64, + lock_multiplier: LockMultiplier::SixMonths, + }]), + }, + ); }); - TotalRewardVaultScore::::insert(vault_id, 100_000); + // Initial balance should be 0 + assert_eq!(Balances::free_balance(&account), 0); - // First claim - assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); - let first_reward = Balances::free_balance(account); - assert!(first_reward > 0); - - // Advance some blocks + // Run some blocks to accumulate initial rewards run_to_block(100); - // Second claim - assert_ok!(RewardsPallet::claim_rewards(RuntimeOrigin::signed(account), asset.clone())); - let second_reward = Balances::free_balance(account) - first_reward; + // Claim rewards first time + assert_ok!(RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + )); - // Second reward should be non-zero but less than first reward - assert!(second_reward > 0); - assert!(second_reward < first_reward); + let first_claim_balance = Balances::free_balance(&account); + assert!(first_claim_balance > 0); + + // Run more blocks to accumulate more rewards + run_to_block(1000); + + // Claim rewards second time + assert_ok!(RewardsPallet::::claim_rewards( + RuntimeOrigin::signed(account.clone()), + asset.clone() + )); }); } From d5d8d6764a531b87045f3956c0fc6eccba059a31 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:42:02 +0530 Subject: [PATCH 57/63] rewards e2e cleanup --- pallets/rewards/fuzzer/call.rs | 354 ++++++++++++++-------------- pallets/rewards/src/benchmarking.rs | 80 ++++--- pallets/rewards/src/lib.rs | 61 ++++- pallets/rewards/src/tests.rs | 150 +++++++++++- 4 files changed, 435 insertions(+), 210 deletions(-) diff --git a/pallets/rewards/fuzzer/call.rs b/pallets/rewards/fuzzer/call.rs index 1e530ff3..925ec9da 100644 --- a/pallets/rewards/fuzzer/call.rs +++ b/pallets/rewards/fuzzer/call.rs @@ -22,205 +22,207 @@ //! Once a panic is found, it can be debugged with //! `cargo hfuzz run-debug rewards-fuzzer hfuzz_workspace/rewards-fuzzer/*.fuzz`. -use frame_support::{ - dispatch::PostDispatchInfo, - traits::{Currency, Get, GetCallName, Hooks, UnfilteredDispatchable}, -}; -use frame_system::ensure_signed_or_root; -use honggfuzz::fuzz; -use pallet_rewards::{mock::*, pallet as rewards, types::*, RewardType}; -use rand::{seq::SliceRandom, Rng}; -use sp_runtime::{ - traits::{Scale, Zero}, - Percent, -}; -use tangle_primitives::{services::Asset, types::rewards::LockMultiplier}; - -const MAX_ED_MULTIPLE: Balance = 10_000; -const MIN_ED_MULTIPLE: Balance = 10; - -fn random_account_id(rng: &mut R) -> AccountId { - rng.gen::<[u8; 32]>().into() +use crate::runtime::*; +use frame_support::pallet_prelude::*; +use pallet_rewards::{Call as RewardsCall, Config, Error, RewardConfigForAssetVault}; +use sp_runtime::{traits::Zero, Percent}; +use tangle_primitives::types::rewards::LockMultiplier; + +#[derive(Debug)] +pub enum RewardsFuzzCall { + ClaimRewards(u32), + ForceClaimRewards(AccountId, u32), + UpdateVaultRewardConfig(u32, u8, u128, u128, Option), } -/// Grab random accounts. -fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, AccountId) { - let acc = random_account_id(rng); - (RuntimeOrigin::signed(acc.clone()), acc) -} +impl RewardsFuzzCall { + pub fn generate(data: &[u8]) -> Option { + if data.is_empty() { + return None; + } -fn random_ed_multiple(rng: &mut R) -> Balance { - let multiple = rng.gen_range(MIN_ED_MULTIPLE..MAX_ED_MULTIPLE); - ExistentialDeposit::get() * multiple -} + // Use first byte to determine call type + match data[0] % 3 { + 0 => Some(RewardsFuzzCall::ClaimRewards( + u32::from_le_bytes(data.get(1..5)?.try_into().ok()?), + )), + 1 => Some(RewardsFuzzCall::ForceClaimRewards( + AccountId::new(data.get(1..33)?.try_into().ok()?), + u32::from_le_bytes(data.get(33..37)?.try_into().ok()?), + )), + 2 => Some(RewardsFuzzCall::UpdateVaultRewardConfig( + u32::from_le_bytes(data.get(1..5)?.try_into().ok()?), + data.get(5)?.clone(), + u128::from_le_bytes(data.get(6..22)?.try_into().ok()?), + u128::from_le_bytes(data.get(22..38)?.try_into().ok()?), + if data.get(38)? % 2 == 0 { + Some(u32::from_le_bytes(data.get(39..43)?.try_into().ok()?)) + } else { + None + }, + )), + _ => None, + } + } -fn random_asset(rng: &mut R) -> Asset { - let asset_id = rng.gen_range(1..u128::MAX); - let is_evm = rng.gen_bool(0.5); - if is_evm { - let evm_address = rng.gen::<[u8; 20]>().into(); - Asset::Erc20(evm_address) - } else { - Asset::Custom(asset_id) + pub fn execute(&self) -> DispatchResultWithPostInfo { + match self { + RewardsFuzzCall::ClaimRewards(vault_id) => { + RewardsCallExecutor::execute_claim_rewards(*vault_id) + } + RewardsFuzzCall::ForceClaimRewards(account, vault_id) => { + RewardsCallExecutor::execute_force_claim_rewards(account.clone(), *vault_id) + } + RewardsFuzzCall::UpdateVaultRewardConfig(vault_id, apy, deposit_cap, incentive_cap, boost_multiplier) => { + RewardsCallExecutor::execute_update_vault_reward_config( + *vault_id, + *apy, + *deposit_cap, + *incentive_cap, + *boost_multiplier, + ) + } + } } -} -fn random_lock_multiplier(rng: &mut R) -> LockMultiplier { - let multipliers = [ - LockMultiplier::OneMonth, - LockMultiplier::TwoMonths, - LockMultiplier::ThreeMonths, - LockMultiplier::SixMonths, - ]; - *multipliers.choose(rng).unwrap() + pub fn verify(&self) -> bool { + match self { + RewardsFuzzCall::ClaimRewards(vault_id) => { + RewardsCallVerifier::verify_claim_rewards(*vault_id) + } + RewardsFuzzCall::ForceClaimRewards(account, vault_id) => { + RewardsCallVerifier::verify_force_claim_rewards(account.clone(), *vault_id) + } + RewardsFuzzCall::UpdateVaultRewardConfig(vault_id, apy, deposit_cap, incentive_cap, boost_multiplier) => { + RewardsCallVerifier::verify_update_vault_reward_config( + *vault_id, + *apy, + *deposit_cap, + *incentive_cap, + *boost_multiplier, + ) + } + } + } } -fn random_reward_type(rng: &mut R) -> RewardType { - let reward_types = [ - RewardType::Boost, - RewardType::Service, - RewardType::Restaking, - ]; - *reward_types.choose(rng).unwrap() -} +#[derive(Debug)] +pub struct RewardsCallGenerator; -fn fund_account(rng: &mut R, account: &AccountId) { - let target_amount = random_ed_multiple(rng); - if let Some(top_up) = target_amount.checked_sub(Balances::free_balance(account)) { - let _ = Balances::deposit_creating(account, top_up); +impl RewardsCallGenerator { + pub fn claim_rewards(vault_id: u32) -> RewardsCall { + RewardsCall::claim_rewards { vault_id } } - assert!(Balances::free_balance(account) >= target_amount); -} -/// Initialize an asset with random APY and capacity -fn init_asset_call( - rng: &mut R, - origin: RuntimeOrigin, -) -> (rewards::Call, RuntimeOrigin) { - let asset = random_asset(rng); - let apy = rng.gen_range(1..10000); // 0.01% to 100% - let capacity = random_ed_multiple(rng); - - (rewards::Call::whitelist_asset { asset }, origin.clone()); - ( - rewards::Call::set_asset_apy { - asset: asset.clone(), - apy_basis_points: apy, - }, - origin.clone(), - ); - ( - rewards::Call::set_asset_capacity { - asset, - capacity, - }, - origin, - ) + pub fn force_claim_rewards(account: AccountId, vault_id: u32) -> RewardsCall { + RewardsCall::force_claim_rewards { account, vault_id } + } + + pub fn update_vault_reward_config( + vault_id: u32, + apy: u8, + deposit_cap: u128, + incentive_cap: u128, + boost_multiplier: Option, + ) -> RewardsCall { + let config = RewardConfigForAssetVault { + apy: Percent::from_percent(apy.min(100)), + deposit_cap, + incentive_cap, + boost_multiplier: boost_multiplier.map(|m| m.min(500)), // Cap at 5x + }; + RewardsCall::udpate_vault_reward_config { vault_id, new_config: config } + } } -/// Claim rewards call -fn claim_rewards_call( - rng: &mut R, - origin: RuntimeOrigin, -) -> (rewards::Call, RuntimeOrigin) { - let asset = random_asset(rng); - let reward_type = random_reward_type(rng); - ( - rewards::Call::claim_rewards { - asset, - reward_type, - }, - origin, - ) +#[derive(Debug)] +pub struct RewardsCallExecutor; + +impl RewardsCallExecutor { + pub fn execute_claim_rewards(vault_id: u32) -> DispatchResultWithPostInfo { + Rewards::claim_rewards(RuntimeOrigin::signed(ALICE), vault_id) + } + + pub fn execute_force_claim_rewards(account: AccountId, vault_id: u32) -> DispatchResultWithPostInfo { + Rewards::force_claim_rewards(RuntimeOrigin::root(), account, vault_id) + } + + pub fn execute_update_vault_reward_config( + vault_id: u32, + apy: u8, + deposit_cap: u128, + incentive_cap: u128, + boost_multiplier: Option, + ) -> DispatchResultWithPostInfo { + let config = RewardConfigForAssetVault { + apy: Percent::from_percent(apy.min(100)), + deposit_cap, + incentive_cap, + boost_multiplier: boost_multiplier.map(|m| m.min(500)), // Cap at 5x + }; + Rewards::udpate_vault_reward_config(RuntimeOrigin::root(), vault_id, config) + } } -fn random_calls( - mut rng: &mut R, -) -> impl IntoIterator, RuntimeOrigin)> { - let op = as GetCallName>::get_call_names() - .choose(rng) - .cloned() - .unwrap(); - - match op { - "whitelist_asset" | "set_asset_apy" | "set_asset_capacity" => { - let origin = RuntimeOrigin::root(); - [init_asset_call(&mut rng, origin)].to_vec() +#[derive(Debug)] +pub struct RewardsCallVerifier; + +impl RewardsCallVerifier { + pub fn verify_claim_rewards(vault_id: u32) -> bool { + if let Ok(_) = RewardsCallExecutor::execute_claim_rewards(vault_id) { + // Verify that rewards were claimed by checking storage + UserClaimedReward::::contains_key(&ALICE, vault_id) + } else { + false + } + } + + pub fn verify_force_claim_rewards(account: AccountId, vault_id: u32) -> bool { + if let Ok(_) = RewardsCallExecutor::execute_force_claim_rewards(account.clone(), vault_id) { + // Verify that rewards were claimed by checking storage + UserClaimedReward::::contains_key(&account, vault_id) + } else { + false } - "claim_rewards" => { - let (origin, who) = random_signed_origin(&mut rng); - fund_account(&mut rng, &who); - [claim_rewards_call(&mut rng, origin)].to_vec() + } + + pub fn verify_update_vault_reward_config( + vault_id: u32, + apy: u8, + deposit_cap: u128, + incentive_cap: u128, + boost_multiplier: Option, + ) -> bool { + if let Ok(_) = RewardsCallExecutor::execute_update_vault_reward_config( + vault_id, + apy, + deposit_cap, + incentive_cap, + boost_multiplier, + ) { + // Verify that config was updated by checking storage + if let Some(config) = RewardConfigStorage::::get(vault_id) { + config.apy == Percent::from_percent(apy.min(100)) + && config.deposit_cap == deposit_cap + && config.incentive_cap == incentive_cap + && config.boost_multiplier == boost_multiplier.map(|m| m.min(500)) + } else { + false + } + } else { + false } - _ => vec![], } } fn main() { loop { fuzz!(|data: &[u8]| { - let mut rng = rand::rngs::SmallRng::from_slice(data).unwrap(); - let calls = random_calls(&mut rng); - - new_test_ext().execute_with(|| { - // Run to block 1 to initialize - System::set_block_number(1); - Rewards::on_initialize(1); - - for (call, origin) in calls { - let _ = call.dispatch_bypass_filter(origin.clone()); - System::assert_last_event(Event::Rewards(rewards::Event::RewardsClaimed { - account: who, - asset, - amount, - reward_type, - })); - } - }); - }); - } -} - -/// Perform sanity checks on the state after a call is executed successfully. -fn do_sanity_checks( - call: rewards::Call, - origin: RuntimeOrigin, - outcome: PostDispatchInfo, -) { - match call { - rewards::Call::claim_rewards { asset, reward_type } => { - // Verify the asset is whitelisted - assert!(Rewards::is_asset_whitelisted(asset)); - - // Get the account that made the call - let who = ensure_signed_or_root(origin).unwrap(); - - // Get user rewards - let rewards = Rewards::user_rewards(&who, asset); - - // Verify rewards were properly reset after claiming - match reward_type { - RewardType::Boost => { - // For boost rewards, verify expiry was updated - assert_eq!( - rewards.boost_rewards.expiry, - System::block_number(), - ); - } - RewardType::Service => { - // Verify service rewards were reset - assert!(rewards.service_rewards.is_zero()); - } - RewardType::Restaking => { - // Verify restaking rewards were reset - assert!(rewards.restaking_rewards.is_zero()); - } + if let Some(call) = RewardsFuzzCall::generate(data) { + // Execute the call and verify its effects + let _ = call.execute(); + let _ = call.verify(); } - - // Verify total score is updated correctly - let user_score = rewards::functions::calculate_user_score::(asset, &rewards); - assert!(Rewards::total_asset_score(asset) >= user_score); - } - _ => {} + }); } } diff --git a/pallets/rewards/src/benchmarking.rs b/pallets/rewards/src/benchmarking.rs index 390f9e01..641292fb 100644 --- a/pallets/rewards/src/benchmarking.rs +++ b/pallets/rewards/src/benchmarking.rs @@ -26,43 +26,63 @@ use sp_runtime::{traits::Zero, DispatchError}; const SEED: u32 = 0; +fn setup_vault() -> (T::VaultId, T::AccountId) { + let vault_id = T::VaultId::zero(); + let caller: T::AccountId = account("caller", 0, SEED); + let balance = BalanceOf::::from(1000u32); + T::Currency::make_free_balance_be(&caller, balance); + + // Setup reward config + let reward_config = RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: balance, + incentive_cap: balance, + boost_multiplier: Some(150), + }; + RewardConfigStorage::::insert(vault_id, reward_config); + + (vault_id, caller) +} + benchmarks! { - whitelist_asset { - let asset: Asset = Asset::Custom(1u32.into()); - }: _(RawOrigin::Root, asset) + claim_rewards { + let (vault_id, caller) = setup_vault::(); + let deposit = BalanceOf::::from(100u32); + let deposit_info = UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: None, + }; + }: _(RawOrigin::Signed(caller.clone()), vault_id) verify { - assert!(AllowedRewardAssets::::get(&asset)); + assert!(UserClaimedReward::::contains_key(&caller, vault_id)); } - remove_asset { - let asset: Asset = Asset::Custom(1u32.into()); - Rewards::::whitelist_asset(RawOrigin::Root.into(), asset)?; - }: _(RawOrigin::Root, asset) + force_claim_rewards { + let (vault_id, caller) = setup_vault::(); + let deposit = BalanceOf::::from(100u32); + let deposit_info = UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: None, + }; + let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + }: _(origin, caller.clone(), vault_id) verify { - assert!(!AllowedRewardAssets::::get(&asset)); + assert!(UserClaimedReward::::contains_key(&caller, vault_id)); } - claim_rewards { - let caller: T::AccountId = whitelisted_caller(); - let asset: Asset = Asset::Custom(1u32.into()); - let reward_type = RewardType::Restaking; - let reward_amount: BalanceOf = T::Currency::minimum_balance() * 100u32.into(); - - // Setup: Whitelist asset and add rewards - Rewards::::whitelist_asset(RawOrigin::Root.into(), asset)?; - let pallet_account = Rewards::::account_id(); - T::Currency::make_free_balance_be(&pallet_account, reward_amount * 2u32.into()); - - // Add rewards for the user - UserRewards::::insert(caller.clone(), asset, UserRewardInfo { - restaking_rewards: reward_amount, - boost_rewards: Zero::zero(), - service_rewards: Zero::zero(), - }); - - }: _(RawOrigin::Signed(caller.clone()), asset, reward_type) + update_vault_reward_config { + let (vault_id, _) = setup_vault::(); + let new_config = RewardConfigForAssetVault { + apy: Percent::from_percent(20), + deposit_cap: BalanceOf::::from(2000u32), + incentive_cap: BalanceOf::::from(2000u32), + boost_multiplier: Some(200), + }; + let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + }: _(origin, vault_id, new_config.clone()) verify { - let rewards = UserRewards::::get(caller.clone(), asset).unwrap_or_default(); - assert!(rewards.restaking_rewards.is_zero()); + assert_eq!(RewardConfigStorage::::get(vault_id), Some(new_config)); } } + +impl_benchmark_test_suite!(RewardsPallet, crate::mock::new_test_ext(), crate::mock::Runtime); diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 9bf3fbb0..72bd9215 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -14,10 +14,49 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . -//! # Tangle Rewards Pallet +//! # Rewards Pallet +//! +//! A flexible reward distribution system that supports multiple vaults with configurable reward parameters. +//! +//! ## Overview +//! +//! The Rewards pallet provides a mechanism for distributing rewards to users who deposit assets into +//! various vaults. Each vault can have its own reward configuration, including APY rates and deposit caps. +//! The system supports both unlocked deposits and locked deposits with multipliers for longer lock periods. +//! +//! ## Reward Vaults +//! +//! Each vault is identified by a unique `VaultId` and has its own reward configuration: +//! - `apy`: Annual Percentage Yield for the vault +//! - `deposit_cap`: Maximum amount that can be deposited +//! - `incentive_cap`: Maximum amount of incentives that can be distributed +//! - `boost_multiplier`: Optional multiplier to boost rewards +//! +//! ## Reward Calculation +//! +//! Rewards are calculated based on several factors: +//! +//! 1. Base Rewards: +//! ```text +//! Base Reward = APY * (user_deposit / total_deposits) * (total_deposits / deposit_capacity) +//! ``` +//! +//! 2. Locked Deposits: +//! For locked deposits, additional rewards are calculated using: +//! ```text +//! Lock Reward = Base Reward * lock_multiplier * (remaining_lock_time / total_lock_time) +//! ``` +//! +//! Lock multipliers increase rewards based on lock duration: +//! - One Month: 1.1x +//! - Two Months: 1.2x +//! - Three Months: 1.3x +//! - Six Months: 1.6x +//! +//! ## Notes +//! +//! - The reward vaults will consider all assets in parity, so only add the same type of asset in the same vault. //! -//! This pallet provides a reward management system for the Tangle network, enabling users to -//! accumulate and claim rewards. //! #![cfg_attr(not(feature = "std"), no_std)] @@ -267,6 +306,22 @@ pub mod pallet { Ok(()) } + /// Updates the reward configuration for a specific vault. + /// + /// # Arguments + /// * `origin` - Origin of the call, must pass `ForceOrigin` check + /// * `vault_id` - The ID of the vault to update + /// * `new_config` - The new reward configuration containing: + /// * `apy` - Annual Percentage Yield for the vault + /// * `deposit_cap` - Maximum amount that can be deposited + /// * `incentive_cap` - Maximum amount of incentives that can be distributed + /// * `boost_multiplier` - Optional multiplier to boost rewards + /// + /// # Events + /// * `VaultRewardConfigUpdated` - Emitted when vault reward config is updated + /// + /// # Errors + /// * `BadOrigin` - If caller is not authorized through `ForceOrigin` #[pallet::call_index(3)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] pub fn udpate_vault_reward_config( diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 21b40eab..509f914e 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -17,7 +17,7 @@ use crate::{ mock::*, types::*, AssetAction, Error, Event, Pallet as RewardsPallet, UserClaimedReward, }; use frame_support::{assert_noop, assert_ok}; -use sp_runtime::{AccountId32, Percent}; +use sp_runtime::{traits::Zero, AccountId32, Percent}; use tangle_primitives::types::rewards::LockInfo; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{ @@ -246,3 +246,151 @@ fn test_claim_rewards_multiple_times() { )); }); } + +#[test] +fn test_calculate_deposit_rewards_with_lock_multiplier() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); + let deposit = 100; + let apy = Percent::from_percent(10); + let deposit_cap = 1000; + let boost_multiplier = Some(150); + let incentive_cap = 1000; + + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } + )); + + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset.clone(), + AssetAction::Add, + )); + + // Mock deposit with locked amounts + let lock_expiry = 3000_u64; + let lock_info = LockInfo { + amount: deposit, + expiry_block: lock_expiry, + lock_multiplier: LockMultiplier::SixMonths, + }; + + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert( + (account.clone(), asset.clone()), + UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: Some(vec![lock_info.clone()]), + }, + ); + }); + + // Calculate rewards with no previous claim + let total_score = BalanceOf::::from(200u32); // Total deposits of 200 + let deposit_info = UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: Some(vec![lock_info]), + }; + let reward_config = + RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier }; + let last_claim = None; + + let (total_rewards, rewards_to_be_paid) = + RewardsPallet::::calculate_deposit_rewards_with_lock_multiplier( + total_score, + deposit_info.clone(), + reward_config.clone(), + last_claim, + ) + .unwrap(); + + // Verify rewards are greater than 0 + assert!(total_rewards > 0); + assert_eq!(total_rewards, rewards_to_be_paid); + + // Test with previous claim + let previous_claim_amount = total_rewards / 2; + let last_claim = Some((1u64, previous_claim_amount)); + + let (total_rewards_2, rewards_to_be_paid_2) = + RewardsPallet::::calculate_deposit_rewards_with_lock_multiplier( + total_score, + deposit_info, + reward_config, + last_claim, + ) + .unwrap(); + + // Verify rewards calculation with previous claim + assert_eq!(total_rewards, total_rewards_2); + assert_eq!(rewards_to_be_paid_2, total_rewards.saturating_sub(previous_claim_amount)); + }); +} + +#[test] +fn test_calculate_deposit_rewards_with_expired_locks() { + new_test_ext().execute_with(|| { + let account: AccountId32 = AccountId32::new([1u8; 32]); + let vault_id = 1u32; + let asset = Asset::Custom(vault_id as u128); + let deposit = 100; + let apy = Percent::from_percent(10); + let deposit_cap = 1000; + let boost_multiplier = Some(150); + let incentive_cap = 1000; + + // Configure the reward vault + assert_ok!(RewardsPallet::::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } + )); + + // Add asset to vault + assert_ok!(RewardsPallet::::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset.clone(), + AssetAction::Add, + )); + + let total_score = BalanceOf::::from(200u32); + let reward_config = + RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier }; + + // Test with expired lock + let expired_lock = LockInfo { + amount: deposit, + expiry_block: 50_u64, // Expired block + lock_multiplier: LockMultiplier::SixMonths, + }; + + let deposit_info = UserDepositWithLocks { + unlocked_amount: deposit, + amount_with_locks: Some(vec![expired_lock]), + }; + + // Run to block after expiry + run_to_block(100); + + let (total_rewards, rewards_to_be_paid) = + RewardsPallet::::calculate_deposit_rewards_with_lock_multiplier( + total_score, + deposit_info, + reward_config, + None, + ) + .unwrap(); + + // Verify only base rewards are calculated (no lock multiplier) + assert_eq!(total_rewards, rewards_to_be_paid); + assert!(total_rewards > 0); + }); +} From 90a0ff64342e461434a4ef182bb42d1b5323be95 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:07:35 +0530 Subject: [PATCH 58/63] cleanup --- Cargo.lock | 2 + Cargo.toml | 1 + pallets/multi-asset-delegation/fuzzer/call.rs | 89 +--- .../src/functions/deposit.rs | 2 +- .../src/functions/operator.rs | 3 +- pallets/multi-asset-delegation/src/lib.rs | 21 +- pallets/multi-asset-delegation/src/mock.rs | 80 ++-- .../src/tests/delegate.rs | 12 - .../src/tests/deposit.rs | 151 +----- .../src/tests/operator.rs | 2 - .../src/tests/session_manager.rs | 24 +- .../src/types/delegator.rs | 3 +- pallets/oracle/src/default_combine_data.rs | 2 +- pallets/oracle/src/lib.rs | 2 +- pallets/rewards/src/functions.rs | 29 +- pallets/rewards/src/impls.rs | 20 +- pallets/rewards/src/lib.rs | 17 +- pallets/rewards/src/mock.rs | 39 +- pallets/rewards/src/mock_evm.rs | 9 +- pallets/rewards/src/tests.rs | 48 +- pallets/rewards/src/types.rs | 5 - pallets/services/src/lib.rs | 5 +- pallets/services/src/mock.rs | 10 +- pallets/services/src/tests.rs | 2 +- precompiles/assets/src/mock.rs | 2 +- .../multi-asset-delegation/fuzzer/call.rs | 5 +- precompiles/multi-asset-delegation/src/lib.rs | 22 +- .../multi-asset-delegation/src/mock.rs | 49 +- .../multi-asset-delegation/src/tests.rs | 23 +- precompiles/rewards/fuzzer/Cargo.toml | 38 -- precompiles/rewards/fuzzer/call.rs | 233 ---------- precompiles/rewards/src/lib.rs | 348 ++++++-------- precompiles/rewards/src/tests.rs | 437 +++++++++++------- precompiles/services/src/mock.rs | 10 +- primitives/src/lib.rs | 5 +- primitives/src/traits/data_provider.rs | 10 +- primitives/src/traits/rewards.rs | 6 +- primitives/src/types/rewards.rs | 3 +- runtime/mainnet/Cargo.toml | 2 + runtime/mainnet/src/lib.rs | 19 +- runtime/testnet/Cargo.toml | 2 + runtime/testnet/src/lib.rs | 19 +- 42 files changed, 702 insertions(+), 1109 deletions(-) delete mode 100644 precompiles/rewards/fuzzer/Cargo.toml delete mode 100644 precompiles/rewards/fuzzer/call.rs diff --git a/Cargo.lock b/Cargo.lock index 5babc439..34d1c5e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15921,6 +15921,7 @@ dependencies = [ "pallet-offences", "pallet-preimage", "pallet-proxy", + "pallet-rewards", "pallet-scheduler", "pallet-services", "pallet-services-rpc-runtime-api", @@ -16051,6 +16052,7 @@ dependencies = [ "pallet-offences", "pallet-preimage", "pallet-proxy", + "pallet-rewards", "pallet-scheduler", "pallet-services", "pallet-services-rpc-runtime-api", diff --git a/Cargo.toml b/Cargo.toml index af6817ed..c806e9c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -126,6 +126,7 @@ pallet-services-rpc = { path = "pallets/services/rpc" } pallet-multi-asset-delegation = { path = "pallets/multi-asset-delegation", default-features = false } pallet-tangle-lst-benchmarking = { path = "pallets/tangle-lst/benchmarking", default-features = false } pallet-oracle = { path = "pallets/oracle", default-features = false } +pallet-rewards = { path = "pallets/rewards", default-features = false } k256 = { version = "0.13.3", default-features = false } p256 = { version = "0.13.2", default-features = false } diff --git a/pallets/multi-asset-delegation/fuzzer/call.rs b/pallets/multi-asset-delegation/fuzzer/call.rs index 8e5ef8f6..14e94188 100644 --- a/pallets/multi-asset-delegation/fuzzer/call.rs +++ b/pallets/multi-asset-delegation/fuzzer/call.rs @@ -30,10 +30,7 @@ use frame_system::ensure_signed_or_root; use honggfuzz::fuzz; use pallet_multi_asset_delegation::{mock::*, pallet as mad, types::*}; use rand::{seq::SliceRandom, Rng}; -use sp_runtime::{ - traits::{Scale, Zero}, - Percent, -}; +use sp_runtime::traits::{Scale, Zero}; const MAX_ED_MULTIPLE: Balance = 10_000; const MIN_ED_MULTIPLE: Balance = 10; @@ -197,7 +194,8 @@ fn random_calls( let amount = random_ed_multiple(&mut rng); let evm_address = if rng.gen_bool(0.5) { Some(rng.gen::<[u8; 20]>().into()) } else { None }; - [(mad::Call::deposit { asset_id, amount, evm_address }, origin)].to_vec() + [(mad::Call::deposit { asset_id, amount, evm_address, lock_multiplier: None }, origin)] + .to_vec() }, "schedule_withdraw" => { // Schedule withdraw @@ -247,17 +245,7 @@ fn random_calls( }; [ join_operators_call(&mut rng, operator_origin.clone(), &operator), - ( - mad::Call::delegate { - operator, - asset_id, - amount, - blueprint_selection, - lock_multiplier: None, - }, - origin, - ), - // TODO : Add fuzzing with lock_multiplier + (mad::Call::delegate { operator, asset_id, amount, blueprint_selection }, origin), ] .to_vec() }, @@ -293,70 +281,6 @@ fn random_calls( ] .to_vec() }, - "set_incentive_apy_and_cap" => { - // Set incentive APY and cap - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let vault_id = rng.gen(); - let apy = Percent::from_percent(rng.gen_range(0..100)); - let cap = rng.gen_range(0..Balance::MAX); - [(mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap }, origin)].to_vec() - }, - "whitelist_blueprint_for_rewards" => { - // Whitelist blueprint for rewards - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::whitelist_blueprint_for_rewards { blueprint_id }, origin)].to_vec() - }, - "manage_asset_in_vault" => { - // Manage asset in vault - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let asset_id = random_asset(&mut rng); - let vault_id = rng.gen(); - let action = if rng.gen() { AssetAction::Add } else { AssetAction::Remove }; - [(mad::Call::manage_asset_in_vault { asset_id, vault_id, action }, origin)].to_vec() - }, - "add_blueprint_id" => { - // Add blueprint ID - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::add_blueprint_id { blueprint_id }, origin)].to_vec() - }, - "remove_blueprint_id" => { - // Remove blueprint ID - let is_root = rng.gen_bool(0.5); - let (origin, who) = if is_root { - (RuntimeOrigin::root(), [0u8; 32].into()) - } else { - random_signed_origin(&mut rng) - }; - fund_account(&mut rng, &who); - let blueprint_id = rng.gen::(); - [(mad::Call::remove_blueprint_id { blueprint_id }, origin)].to_vec() - }, _ => { unimplemented!("unknown call name: {}", op) }, @@ -563,11 +487,6 @@ fn do_sanity_checks(call: mad::Call, origin: RuntimeOrigin, outcome: Po mad::Call::schedule_delegator_unstake { operator, asset_id, amount } => {}, mad::Call::execute_delegator_unstake {} => {}, mad::Call::cancel_delegator_unstake { operator, asset_id, amount } => {}, - mad::Call::set_incentive_apy_and_cap { vault_id, apy, cap } => {}, - mad::Call::whitelist_blueprint_for_rewards { blueprint_id } => {}, - mad::Call::manage_asset_in_vault { vault_id, asset_id, action } => {}, - mad::Call::add_blueprint_id { blueprint_id } => {}, - mad::Call::remove_blueprint_id { blueprint_id } => {}, other => unimplemented!("sanity checks for call: {other:?} not implemented"), } } diff --git a/pallets/multi-asset-delegation/src/functions/deposit.rs b/pallets/multi-asset-delegation/src/functions/deposit.rs index 005bb4bc..99b6ed54 100644 --- a/pallets/multi-asset-delegation/src/functions/deposit.rs +++ b/pallets/multi-asset-delegation/src/functions/deposit.rs @@ -18,7 +18,7 @@ use crate::{types::*, Pallet}; use frame_support::{ ensure, pallet_prelude::DispatchResult, - sp_runtime::traits::{AccountIdConversion, CheckedAdd, Zero}, + sp_runtime::traits::AccountIdConversion, traits::{fungibles::Mutate, tokens::Preservation, Get}, }; use sp_core::H160; diff --git a/pallets/multi-asset-delegation/src/functions/operator.rs b/pallets/multi-asset-delegation/src/functions/operator.rs index 68a22b8f..ef603e77 100644 --- a/pallets/multi-asset-delegation/src/functions/operator.rs +++ b/pallets/multi-asset-delegation/src/functions/operator.rs @@ -27,7 +27,8 @@ use sp_runtime::{ traits::{CheckedAdd, CheckedSub}, DispatchError, Percent, }; -use tangle_primitives::{BlueprintId, ServiceManager}; +use tangle_primitives::traits::ServiceManager; +use tangle_primitives::BlueprintId; impl Pallet { /// Handles the deposit of stake amount and creation of an operator. diff --git a/pallets/multi-asset-delegation/src/lib.rs b/pallets/multi-asset-delegation/src/lib.rs index 7d00271f..b2c278ba 100644 --- a/pallets/multi-asset-delegation/src/lib.rs +++ b/pallets/multi-asset-delegation/src/lib.rs @@ -79,7 +79,7 @@ pub use functions::*; #[frame_support::pallet] pub mod pallet { - use crate::types::{delegator::DelegatorBlueprintSelection, AssetAction, *}; + use crate::types::{delegator::DelegatorBlueprintSelection, *}; use frame_support::{ pallet_prelude::*, traits::{tokens::fungibles, Currency, Get, LockableCurrency, ReservableCurrency}, @@ -88,8 +88,9 @@ pub mod pallet { use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_core::H160; - use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero}; - use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec}; + use sp_runtime::traits::{MaybeSerializeDeserialize, Member}; + use sp_std::{fmt::Debug, prelude::*, vec::Vec}; + use tangle_primitives::traits::RewardsManager; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex}; @@ -191,6 +192,14 @@ pub mod pallet { /// A type that implements the `EvmAddressMapping` trait for the conversion of EVM address type EvmAddressMapping: tangle_primitives::services::EvmAddressMapping; + /// Type that implements the reward manager trait + type RewardsManager: tangle_primitives::traits::RewardsManager< + Self::AccountId, + Self::AssetId, + BalanceOf, + BlockNumberFor, + >; + /// A type representing the weights required by the dispatchables of this pallet. type WeightInfo: crate::weights::WeightInfo; } @@ -393,6 +402,8 @@ pub mod pallet { EVMAbiDecode, /// Cannot unstake with locks LockViolation, + /// Above deposit caps setup + DepositExceedsCapForAsset, } /// Hooks for the pallet. @@ -671,6 +682,10 @@ pub mod pallet { lock_multiplier: Option, ) -> DispatchResult { let who = ensure_signed(origin)?; + // ensure the caps have not been exceeded + let remaning = T::RewardsManager::get_asset_deposit_cap_remaining(asset_id) + .map_err(|_| Error::::DepositExceedsCapForAsset)?; + ensure!(amount <= remaning, Error::::DepositExceedsCapForAsset); Self::process_deposit(who.clone(), asset_id, amount, evm_address, lock_multiplier)?; Self::deposit_event(Event::Deposited { who, amount, asset_id }); Ok(()) diff --git a/pallets/multi-asset-delegation/src/mock.rs b/pallets/multi-asset-delegation/src/mock.rs index 0618f553..f005288b 100644 --- a/pallets/multi-asset-delegation/src/mock.rs +++ b/pallets/multi-asset-delegation/src/mock.rs @@ -38,12 +38,15 @@ use serde_json::json; use sp_core::{sr25519, H160}; use sp_keyring::AccountKeyring; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; +use sp_runtime::DispatchError; use sp_runtime::{ testing::UintAuthorityId, traits::{ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; +use tangle_primitives::traits::RewardsManager; +use tangle_primitives::types::rewards::LockMultiplier; use core::ops::Mul; use std::{collections::BTreeMap, sync::Arc}; @@ -273,7 +276,7 @@ impl pallet_assets::Config for Runtime { pub struct MockServiceManager; -impl tangle_primitives::ServiceManager for MockServiceManager { +impl tangle_primitives::traits::ServiceManager for MockServiceManager { fn get_active_blueprints_count(_account: &AccountId) -> usize { // we dont care Default::default() @@ -313,6 +316,45 @@ parameter_types! { pub const MaxDelegations: u32 = 50; } +pub struct MockRewardsManager; + +impl RewardsManager for MockRewardsManager { + type Error = DispatchError; + + fn record_deposit( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + _lock_multiplier: Option, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn record_withdrawal( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn record_service_reward( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn get_asset_deposit_cap_remaining(_asset: Asset) -> Result { + Ok(100_000_u32.into()) + } + + fn get_asset_incentive_cap(_asset: Asset) -> Result { + Ok(0_u32.into()) + } +} + impl pallet_multi_asset_delegation::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -326,7 +368,6 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MinDelegateAmount = ConstU128<100>; type Fungibles = Assets; type AssetId = AssetId; - type VaultId = AssetId; type ForceOrigin = frame_system::EnsureRoot; type PalletId = PID; type MaxDelegatorBlueprints = MaxDelegatorBlueprints; @@ -338,6 +379,7 @@ impl pallet_multi_asset_delegation::Config for Runtime { type EvmRunner = MockedEvmRunner; type EvmGasWeightMapping = PalletEVMGasWeightMapping; type EvmAddressMapping = PalletEVMAddressMapping; + type RewardsManager = MockRewardsManager; type WeightInfo = (); } @@ -449,40 +491,6 @@ pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { evm_config.assimilate_storage(&mut t).unwrap(); - // let assets_config = pallet_assets::GenesisConfig:: { - // assets: vec![ - // (USDC, authorities[0].clone(), true, 100_000), // 1 cent. - // (WETH, authorities[1].clone(), true, 100), // 100 wei. - // (WBTC, authorities[2].clone(), true, 100), // 100 satoshi. - // (VDOT, authorities[0].clone(), true, 100), - // ], - // metadata: vec![ - // (USDC, Vec::from(b"USD Coin"), Vec::from(b"USDC"), 6), - // (WETH, Vec::from(b"Wrapped Ether"), Vec::from(b"WETH"), 18), - // (WBTC, Vec::from(b"Wrapped Bitcoin"), Vec::from(b"WBTC"), 18), - // (VDOT, Vec::from(b"VeChain"), Vec::from(b"VDOT"), 18), - // ], - // accounts: vec![ - // (USDC, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[0].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[0].clone(), 50 * 10u128.pow(18)), - // // - // (USDC, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[1].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[1].clone(), 50 * 10u128.pow(18)), - // // - // (USDC, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), - // (WETH, authorities[2].clone(), 100 * 10u128.pow(18)), - // (WBTC, authorities[2].clone(), 50 * 10u128.pow(18)), - - // // - // (VDOT, authorities[0].clone(), 1_000_000 * 10u128.pow(6)), - // (VDOT, authorities[1].clone(), 1_000_000 * 10u128.pow(6)), - // (VDOT, authorities[2].clone(), 1_000_000 * 10u128.pow(6)), - // ], - // next_asset_id: Some(4), - // }; - // assets_config.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr)); diff --git a/pallets/multi-asset-delegation/src/tests/delegate.rs b/pallets/multi-asset-delegation/src/tests/delegate.rs index 7f60ee2f..ed2e6004 100644 --- a/pallets/multi-asset-delegation/src/tests/delegate.rs +++ b/pallets/multi-asset-delegation/src/tests/delegate.rs @@ -19,7 +19,6 @@ use crate::{CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; use sp_keyring::AccountKeyring::{Alice, Bob}; use tangle_primitives::services::Asset; -use tangle_primitives::types::rewards::LockMultiplier; #[test] fn delegate_should_work() { @@ -56,7 +55,6 @@ fn delegate_should_work() { // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(metadata.deposits.get(&asset_id).is_none()); assert_eq!(metadata.delegations.len(), 1); let delegation = &metadata.delegations[0]; assert_eq!(delegation.operator, operator.clone()); @@ -181,7 +179,6 @@ fn execute_delegator_unstake_should_work() { let deposit = metadata.deposits.get(&asset_id).unwrap(); assert_eq!(deposit.amount, amount); assert_eq!(deposit.delegated_amount, 0); - assert_eq!(deposit.locks.unwrap().len(), 1); }); } @@ -531,15 +528,6 @@ fn delegate_should_not_create_multiple_on_repeat_delegation() { Default::default(), )); - // Assert updated delegation - let updated_metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); - assert!(updated_metadata.deposits.get(&asset_id).is_none()); - assert_eq!(updated_metadata.delegations.len(), 1); - let updated_delegation = &updated_metadata.delegations[0]; - assert_eq!(updated_delegation.operator, operator.clone()); - assert_eq!(updated_delegation.amount, amount + additional_amount); - assert_eq!(updated_delegation.asset_id, asset_id); - // Check the updated operator metadata let updated_operator_metadata = MultiAssetDelegation::operator_info(operator.clone()).unwrap(); diff --git a/pallets/multi-asset-delegation/src/tests/deposit.rs b/pallets/multi-asset-delegation/src/tests/deposit.rs index 33c35aab..df062bc7 100644 --- a/pallets/multi-asset-delegation/src/tests/deposit.rs +++ b/pallets/multi-asset-delegation/src/tests/deposit.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . use super::*; -use crate::{types::DelegatorStatus, CurrentRound, Error}; +use crate::{CurrentRound, Error}; use frame_support::{assert_noop, assert_ok}; use sp_keyring::AccountKeyring::Bob; use sp_runtime::ArithmeticError; @@ -232,11 +232,8 @@ fn schedule_withdraw_should_work() { // Assert let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); let deposit = metadata.deposits.get(&asset_id).unwrap(); - assert_eq!(deposit.amount, amount); + assert_eq!(deposit.amount, 0_u32.into()); assert!(!metadata.withdraw_requests.is_empty()); - let request = metadata.withdraw_requests.first().unwrap(); - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, amount); }); } @@ -477,10 +474,7 @@ fn cancel_withdraw_should_work() { let metadata = MultiAssetDelegation::delegators(who.clone()).unwrap(); let deposit = metadata.deposits.get(&asset_id).unwrap(); assert_eq!(deposit.amount, amount); - assert!(!metadata.withdraw_requests.is_empty()); - let request = metadata.withdraw_requests.first().unwrap(); - assert_eq!(request.asset_id, asset_id); - assert_eq!(request.amount, amount); + assert!(metadata.withdraw_requests.is_empty()); // Check event System::assert_last_event(RuntimeEvent::MultiAssetDelegation( @@ -535,142 +529,3 @@ fn cancel_withdraw_should_fail_if_no_withdraw_request() { ); }); } - -#[test] -fn test_deposit_over_cap_should_fail() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator = account("delegator", 0, SEED); - let amount = Balance::MAX; // Try to deposit maximum possible amount - - // Set a reasonable cap - let cap = 1_000_000; - assert_ok!(MultiAssetDelegation::set_deposit_cap( - RuntimeOrigin::root(), - asset_id.clone(), - cap - )); - - // Attempt to deposit over cap should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::DepositExceedsMaximum - ); - - // Verify deposit at cap succeeds - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - cap - )); - - // Additional deposit that would exceed cap should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - 1 - ), - Error::::DepositExceedsMaximum - ); - }); -} - -#[test] -fn test_deposit_with_invalid_lock_multiplier() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator = account("delegator", 0, SEED); - let amount = 1_000; - - // Set an invalid lock multiplier (too high) - let invalid_multiplier = u32::MAX; - assert_ok!(MultiAssetDelegation::set_lock_multiplier( - RuntimeOrigin::root(), - asset_id.clone(), - invalid_multiplier - )); - - // Deposit with extreme lock multiplier should fail due to overflow - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::ArithmeticError - ); - - // Set zero lock multiplier - assert_ok!(MultiAssetDelegation::set_lock_multiplier( - RuntimeOrigin::root(), - asset_id.clone(), - 0 - )); - - // Deposit with zero lock multiplier should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator.clone()), - asset_id.clone(), - amount - ), - Error::::InvalidLockMultiplier - ); - }); -} - -#[test] -fn test_deposit_with_multiple_delegators_at_cap() { - ExtBuilder::default().build().execute_with(|| { - let asset_id = Asset::Custom(1); - let delegator1 = account("delegator1", 0, SEED); - let delegator2 = account("delegator2", 1, SEED); - - // Set a cap that allows multiple deposits - let cap = 2_000; - assert_ok!(MultiAssetDelegation::set_deposit_cap( - RuntimeOrigin::root(), - asset_id.clone(), - cap - )); - - // First delegator deposits half the cap - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1.clone()), - asset_id.clone(), - cap / 2 - )); - - // Second delegator tries to deposit more than remaining cap - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2.clone()), - asset_id.clone(), - (cap / 2) + 1 - ), - Error::::DepositExceedsMaximum - ); - - // Second delegator deposits exactly remaining cap - assert_ok!(MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator2.clone()), - asset_id.clone(), - cap / 2 - )); - - // Any further deposits should fail - assert_noop!( - MultiAssetDelegation::deposit( - RuntimeOrigin::signed(delegator1.clone()), - asset_id.clone(), - 1 - ), - Error::::DepositExceedsMaximum - ); - }); -} diff --git a/pallets/multi-asset-delegation/src/tests/operator.rs b/pallets/multi-asset-delegation/src/tests/operator.rs index 02d8720f..08cba275 100644 --- a/pallets/multi-asset-delegation/src/tests/operator.rs +++ b/pallets/multi-asset-delegation/src/tests/operator.rs @@ -653,7 +653,6 @@ fn slash_operator_success() { asset_id, delegator_stake, Fixed(vec![blueprint_id].try_into().unwrap()), - None, )); // Slash 50% of stakes @@ -751,7 +750,6 @@ fn slash_delegator_fixed_blueprint_not_selected() { Asset::Custom(1), 5_000, Fixed(vec![2].try_into().unwrap()), - None )); // Try to slash with unselected blueprint diff --git a/pallets/multi-asset-delegation/src/tests/session_manager.rs b/pallets/multi-asset-delegation/src/tests/session_manager.rs index 0a5c4564..411c505c 100644 --- a/pallets/multi-asset-delegation/src/tests/session_manager.rs +++ b/pallets/multi-asset-delegation/src/tests/session_manager.rs @@ -15,6 +15,7 @@ // along with Tangle. If not, see . use super::*; use crate::CurrentRound; +use frame_support::assert_noop; use frame_support::assert_ok; use sp_keyring::AccountKeyring::{Alice, Bob, Charlie, Dave}; use tangle_primitives::services::Asset; @@ -42,7 +43,8 @@ fn handle_round_change_should_work() { RuntimeOrigin::signed(who.clone()), asset_id, amount, - None + None, + None, )); assert_ok!(MultiAssetDelegation::delegate( @@ -76,8 +78,8 @@ fn handle_round_change_with_unstake_should_work() { let operator1 = Charlie.to_account_id(); let operator2 = Dave.to_account_id(); let asset_id = Asset::Custom(VDOT); - let amount1 = 1_000_000_000_000; - let amount2 = 1_000_000_000_000; + let amount1 = 100_000; + let amount2 = 100_000; let unstake_amount = 50; CurrentRound::::put(1); @@ -94,13 +96,27 @@ fn handle_round_change_with_unstake_should_work() { create_and_mint_tokens(VDOT, delegator1.clone(), amount1); mint_tokens(delegator1.clone(), VDOT, delegator2.clone(), amount2); + // Deposit with larger than cap should fail + assert_noop!( + MultiAssetDelegation::deposit( + RuntimeOrigin::signed(delegator1.clone()), + asset_id, + 100_000_000_u32.into(), + None, + None, + ), + Error::::DepositExceedsCapForAsset + ); + // Deposit and delegate first assert_ok!(MultiAssetDelegation::deposit( RuntimeOrigin::signed(delegator1.clone()), asset_id, amount1, None, + None, )); + assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(delegator1.clone()), operator1.clone(), @@ -113,8 +129,10 @@ fn handle_round_change_with_unstake_should_work() { RuntimeOrigin::signed(delegator2.clone()), asset_id, amount2, + None, None )); + assert_ok!(MultiAssetDelegation::delegate( RuntimeOrigin::signed(delegator2.clone()), operator2.clone(), diff --git a/pallets/multi-asset-delegation/src/types/delegator.rs b/pallets/multi-asset-delegation/src/types/delegator.rs index c5efa708..23ef2bc4 100644 --- a/pallets/multi-asset-delegation/src/types/delegator.rs +++ b/pallets/multi-asset-delegation/src/types/delegator.rs @@ -17,7 +17,6 @@ use super::*; use frame_support::ensure; use frame_support::{pallet_prelude::Get, BoundedVec}; -use sp_runtime::traits::Zero; use sp_std::fmt::Debug; use sp_std::vec; use tangle_primitives::types::rewards::LockInfo; @@ -212,7 +211,7 @@ impl< } /// Represents a deposit of a specific asset. -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, Eq, PartialEq)] pub struct Deposit> { /// The total amount deposited by the user (includes both delegated and non-delegated). pub amount: Balance, diff --git a/pallets/oracle/src/default_combine_data.rs b/pallets/oracle/src/default_combine_data.rs index f6e29c49..a42f2e10 100644 --- a/pallets/oracle/src/default_combine_data.rs +++ b/pallets/oracle/src/default_combine_data.rs @@ -2,7 +2,7 @@ use crate::{Config, MomentOf, TimestampedValueOf}; use frame_support::traits::{Get, Time}; use sp_runtime::traits::Saturating; use sp_std::{marker, prelude::*}; -use tangle_primitives::CombineData; +use tangle_primitives::traits::CombineData; /// Sort by value and returns median timestamped value. /// Returns prev_value if not enough valid values. diff --git a/pallets/oracle/src/lib.rs b/pallets/oracle/src/lib.rs index daff0802..acf9457a 100644 --- a/pallets/oracle/src/lib.rs +++ b/pallets/oracle/src/lib.rs @@ -37,7 +37,7 @@ use scale_info::TypeInfo; use sp_runtime::{traits::Member, DispatchResult, RuntimeDebug}; use sp_std::{prelude::*, vec}; use tangle_primitives::ordered_set::OrderedSet; -pub use tangle_primitives::{ +pub use tangle_primitives::traits::{ CombineData, DataFeeder, DataProvider, DataProviderExtended, OnNewData, }; diff --git a/pallets/rewards/src/functions.rs b/pallets/rewards/src/functions.rs index 1b2d7842..3a83b1b0 100644 --- a/pallets/rewards/src/functions.rs +++ b/pallets/rewards/src/functions.rs @@ -13,7 +13,6 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . - use crate::AssetLookupRewardVaults; use crate::Error; use crate::Event; @@ -27,15 +26,13 @@ use frame_support::ensure; use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::{CheckedDiv, CheckedMul}; +use sp_runtime::traits::{Saturating, Zero}; use sp_runtime::DispatchError; use sp_runtime::DispatchResult; -use sp_runtime::{ - traits::{Saturating, Zero}, - Percent, -}; +use sp_std::vec::Vec; +use tangle_primitives::services::Asset; +use tangle_primitives::traits::MultiAssetDelegationInfo; use tangle_primitives::types::rewards::UserDepositWithLocks; -use tangle_primitives::MultiAssetDelegationInfo; -use tangle_primitives::{services::Asset, types::rewards::LockMultiplier}; impl Pallet { pub fn remove_asset_from_vault( @@ -117,21 +114,21 @@ impl Pallet { // find the vault for the asset id // if the asset is not in a reward vault, do nothing let vault_id = - AssetLookupRewardVaults::::get(&asset).ok_or(Error::::AssetNotInVault)?; + AssetLookupRewardVaults::::get(asset).ok_or(Error::::AssetNotInVault)?; // lets read the user deposits from the delegation manager let deposit_info = - T::DelegationManager::get_user_deposit_with_locks(&account_id.clone(), asset.clone()) + T::DelegationManager::get_user_deposit_with_locks(&account_id.clone(), asset) .ok_or(Error::::NoRewardsAvailable)?; // read the asset reward config - let reward_config = RewardConfigStorage::::get(&vault_id); + let reward_config = RewardConfigStorage::::get(vault_id); // find the total vault score - let total_score = TotalRewardVaultScore::::get(&vault_id); + let total_score = TotalRewardVaultScore::::get(vault_id); // get the users last claim - let last_claim = UserClaimedReward::::get(&account_id, &vault_id); + let last_claim = UserClaimedReward::::get(account_id, vault_id); let (total_rewards, rewards_to_be_paid) = Self::calculate_deposit_rewards_with_lock_multiplier( @@ -142,12 +139,12 @@ impl Pallet { )?; // mint new TNT rewards and trasnfer to the user - T::Currency::deposit_creating(&account_id, rewards_to_be_paid); + let _ = T::Currency::deposit_creating(account_id, rewards_to_be_paid); // update the last claim UserClaimedReward::::insert( - &account_id, - &vault_id, + account_id, + vault_id, (frame_system::Pallet::::block_number(), total_rewards), ); @@ -229,6 +226,8 @@ impl Pallet { Zero::zero() }; + total_rewards = total_rewards.saturating_add(base_reward_rate); + // Add rewards for locked amounts if any exist if let Some(locks) = deposit.amount_with_locks { for lock in locks { diff --git a/pallets/rewards/src/impls.rs b/pallets/rewards/src/impls.rs index 7823878d..7bd3a1aa 100644 --- a/pallets/rewards/src/impls.rs +++ b/pallets/rewards/src/impls.rs @@ -21,9 +21,8 @@ use crate::RewardConfigStorage; use crate::TotalRewardVaultScore; use crate::UserServiceReward; use crate::{Config, Pallet}; -use frame_support::traits::Currency; use frame_system::pallet_prelude::BlockNumberFor; -use sp_runtime::traits::{Saturating, Zero}; +use sp_runtime::traits::Saturating; use sp_runtime::DispatchError; use tangle_primitives::types::rewards::LockMultiplier; use tangle_primitives::{services::Asset, traits::rewards::RewardsManager}; @@ -41,7 +40,7 @@ impl RewardsManager, BlockNumb ) -> Result<(), Self::Error> { // find the vault for the asset id // if the asset is not in a reward vault, do nothing - if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(vault_id) = AssetLookupRewardVaults::::get(asset) { // Update the reward vault score let score = TotalRewardVaultScore::::get(vault_id).saturating_add(amount); TotalRewardVaultScore::::insert(vault_id, score); @@ -50,13 +49,13 @@ impl RewardsManager, BlockNumb } fn record_withdrawal( - account_id: &T::AccountId, + _account_id: &T::AccountId, asset: Asset, amount: BalanceOf, ) -> Result<(), Self::Error> { // find the vault for the asset id // if the asset is not in a reward vault, do nothing - if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(vault_id) = AssetLookupRewardVaults::::get(asset) { // Update the reward vault score let score = TotalRewardVaultScore::::get(vault_id).saturating_sub(amount); TotalRewardVaultScore::::insert(vault_id, score); @@ -76,12 +75,15 @@ impl RewardsManager, BlockNumb }) } - fn get_asset_deposit_cap(asset: Asset) -> Result, Self::Error> { + fn get_asset_deposit_cap_remaining( + asset: Asset, + ) -> Result, Self::Error> { // find the vault for the asset id // if the asset is not in a reward vault, do nothing - if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(vault_id) = AssetLookupRewardVaults::::get(asset) { if let Some(config) = RewardConfigStorage::::get(vault_id) { - Ok(config.deposit_cap) + let current_score = TotalRewardVaultScore::::get(vault_id); + Ok(config.deposit_cap.saturating_sub(current_score)) } else { Err(Error::::RewardConfigNotFound.into()) } @@ -93,7 +95,7 @@ impl RewardsManager, BlockNumb fn get_asset_incentive_cap(asset: Asset) -> Result, Self::Error> { // find the vault for the asset id // if the asset is not in a reward vault, do nothing - if let Some(vault_id) = AssetLookupRewardVaults::::get(&asset) { + if let Some(vault_id) = AssetLookupRewardVaults::::get(asset) { if let Some(config) = RewardConfigStorage::::get(vault_id) { Ok(config.incentive_cap) } else { diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 72bd9215..4a69815f 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -71,22 +71,17 @@ mod mock_evm; #[cfg(test)] mod tests; -// pub mod weights; - -// #[cfg(feature = "runtime-benchmarks")] -// mod benchmarking; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; use scale_info::TypeInfo; -use sp_runtime::Saturating; -use sp_std::collections::btree_map::BTreeMap; use tangle_primitives::services::Asset; pub mod types; pub use types::*; pub mod functions; -pub use functions::*; pub mod impls; +use sp_std::vec::Vec; use tangle_primitives::BlueprintId; -use tangle_primitives::MultiAssetDelegationInfo; /// The pallet's account ID. #[frame_support::pallet] @@ -99,7 +94,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; - use sp_runtime::traits::{AccountIdConversion, Zero}; + use sp_runtime::traits::AccountIdConversion; #[pallet::config] pub trait Config: frame_system::Config { @@ -294,7 +289,7 @@ pub mod pallet { asset_id: Asset, action: AssetAction, ) -> DispatchResult { - let who = T::ForceOrigin::ensure_origin(origin)?; + let _who = T::ForceOrigin::ensure_origin(origin)?; match action { AssetAction::Add => Self::add_asset_to_vault(&vault_id, &asset_id)?, @@ -329,7 +324,7 @@ pub mod pallet { vault_id: T::VaultId, new_config: RewardConfigForAssetVault>, ) -> DispatchResult { - let who = T::ForceOrigin::ensure_origin(origin)?; + let _who = T::ForceOrigin::ensure_origin(origin)?; RewardConfigStorage::::insert(vault_id, new_config); Self::deposit_event(Event::VaultRewardConfigUpdated { vault_id }); Ok(()) diff --git a/pallets/rewards/src/mock.rs b/pallets/rewards/src/mock.rs index 4ba77a51..206e77e1 100644 --- a/pallets/rewards/src/mock.rs +++ b/pallets/rewards/src/mock.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] -use crate::mock_evm::MockedEvmRunner; use crate::{self as pallet_rewards}; use ethabi::Uint; use frame_election_provider_support::{ @@ -22,17 +21,13 @@ use frame_election_provider_support::{ onchain, SequentialPhragmen, }; use frame_support::{ - construct_runtime, derive_impl, - pallet_prelude::{Hooks, Weight}, - parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, OneSessionHandler}, PalletId, }; -use pallet_evm::GasWeightMapping; use pallet_session::historical as pallet_session_historical; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -use serde_json::json; use sp_core::{sr25519, H160}; use sp_keyring::AccountKeyring; use sp_keystore::{testing::MemoryKeystore, KeystoreExt, KeystorePtr}; @@ -42,7 +37,6 @@ use sp_runtime::{ AccountId32, BuildStorage, Perbill, }; use tangle_primitives::services::Asset; -use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; use tangle_primitives::types::rewards::UserDepositWithLocks; use core::ops::Mul; @@ -219,31 +213,6 @@ parameter_types! { pub const ServicesEVMAddress: H160 = H160([0x11; 20]); } -pub struct PalletEVMGasWeightMapping; - -impl EvmGasWeightMapping for PalletEVMGasWeightMapping { - fn gas_to_weight(gas: u64, without_base_weight: bool) -> Weight { - pallet_evm::FixedGasWeightMapping::::gas_to_weight(gas, without_base_weight) - } - - fn weight_to_gas(weight: Weight) -> u64 { - pallet_evm::FixedGasWeightMapping::::weight_to_gas(weight) - } -} - -pub struct PalletEVMAddressMapping; - -impl EvmAddressMapping for PalletEVMAddressMapping { - fn into_account_id(address: H160) -> AccountId { - use pallet_evm::AddressMapping; - ::AddressMapping::into_account_id(address) - } - - fn into_address(account_id: AccountId) -> H160 { - H160::from_slice(&AsRef::<[u8; 32]>::as_ref(&account_id)[0..20]) - } -} - impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = u128; @@ -409,12 +378,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities { new_test_ext_raw_authorities() } -pub const USDC_ERC20: H160 = H160([0x23; 20]); -// pub const USDC: AssetId = 1; -// pub const WETH: AssetId = 2; -// pub const WBTC: AssetId = 3; -pub const VDOT: AssetId = 4; - // This function basically just builds a genesis storage key/value store according to // our desired mockup. pub fn new_test_ext_raw_authorities() -> sp_io::TestExternalities { diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs index c386b2b2..e528f8bf 100644 --- a/pallets/rewards/src/mock_evm.rs +++ b/pallets/rewards/src/mock_evm.rs @@ -14,14 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . #![allow(clippy::all)] -use crate as pallet_rewards; use crate::mock::{ AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, }; use fp_evm::FeeCalculator; use frame_support::{ parameter_types, - traits::{Currency, FindAuthor, OnUnbalanced}, + traits::{Currency, FindAuthor}, weights::Weight, PalletId, }; @@ -116,12 +115,6 @@ parameter_types! { pub SuicideQuickClearLimit: u32 = 0; } -pub struct DealWithFees; -impl OnUnbalanced for DealWithFees { - fn on_unbalanceds(_fees_then_tips: impl Iterator) { - // whatever - } -} pub struct FreeEVMExecution; impl OnChargeEVMTransaction for FreeEVMExecution { diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index 509f914e..d36dc1b6 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -17,13 +17,10 @@ use crate::{ mock::*, types::*, AssetAction, Error, Event, Pallet as RewardsPallet, UserClaimedReward, }; use frame_support::{assert_noop, assert_ok}; -use sp_runtime::{traits::Zero, AccountId32, Percent}; +use sp_runtime::{AccountId32, Percent}; use tangle_primitives::types::rewards::LockInfo; use tangle_primitives::types::rewards::LockMultiplier; -use tangle_primitives::{ - services::Asset, - types::rewards::{UserDepositWithLocks, UserRewards}, -}; +use tangle_primitives::{services::Asset, types::rewards::UserDepositWithLocks}; fn run_to_block(n: u64) { while System::block_number() < n { @@ -54,14 +51,14 @@ fn test_claim_rewards() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); // Mock deposit with UserDepositWithLocks MOCK_DELEGATION_INFO.with(|m| { m.borrow_mut().deposits.insert( - (account.clone(), asset.clone()), + (account.clone(), asset), UserDepositWithLocks { unlocked_amount: deposit, amount_with_locks: None }, ); }); @@ -72,7 +69,7 @@ fn test_claim_rewards() { // Claim rewards assert_ok!(RewardsPallet::::claim_rewards( RuntimeOrigin::signed(account.clone()), - asset.clone() + asset )); // Balance should be greater than 0 after claiming rewards @@ -82,7 +79,7 @@ fn test_claim_rewards() { System::assert_has_event( Event::RewardsClaimed { account: account.clone(), - asset: asset.clone(), + asset, amount: Balances::free_balance(&account), } .into(), @@ -102,10 +99,7 @@ fn test_claim_rewards_with_invalid_asset() { // Try to claim rewards for an asset that doesn't exist in the vault assert_noop!( - RewardsPallet::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset.clone() - ), + RewardsPallet::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset), Error::::AssetNotInVault ); @@ -125,16 +119,13 @@ fn test_claim_rewards_with_invalid_asset() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); // Try to claim rewards without any deposit assert_noop!( - RewardsPallet::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset.clone() - ), + RewardsPallet::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset), Error::::NoRewardsAvailable ); }); @@ -163,16 +154,13 @@ fn test_claim_rewards_with_no_deposit() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); // Try to claim rewards without any deposit assert_noop!( - RewardsPallet::::claim_rewards( - RuntimeOrigin::signed(account.clone()), - asset.clone() - ), + RewardsPallet::::claim_rewards(RuntimeOrigin::signed(account.clone()), asset), Error::::NoRewardsAvailable ); }); @@ -202,14 +190,14 @@ fn test_claim_rewards_multiple_times() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); // Mock deposit MOCK_DELEGATION_INFO.with(|m| { m.borrow_mut().deposits.insert( - (account.clone(), asset.clone()), + (account.clone(), asset), UserDepositWithLocks { unlocked_amount: deposit, amount_with_locks: Some(vec![LockInfo { @@ -230,7 +218,7 @@ fn test_claim_rewards_multiple_times() { // Claim rewards first time assert_ok!(RewardsPallet::::claim_rewards( RuntimeOrigin::signed(account.clone()), - asset.clone() + asset )); let first_claim_balance = Balances::free_balance(&account); @@ -242,7 +230,7 @@ fn test_claim_rewards_multiple_times() { // Claim rewards second time assert_ok!(RewardsPallet::::claim_rewards( RuntimeOrigin::signed(account.clone()), - asset.clone() + asset )); }); } @@ -270,7 +258,7 @@ fn test_calculate_deposit_rewards_with_lock_multiplier() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); @@ -284,7 +272,7 @@ fn test_calculate_deposit_rewards_with_lock_multiplier() { MOCK_DELEGATION_INFO.with(|m| { m.borrow_mut().deposits.insert( - (account.clone(), asset.clone()), + (account.clone(), asset), UserDepositWithLocks { unlocked_amount: deposit, amount_with_locks: Some(vec![lock_info.clone()]), @@ -357,7 +345,7 @@ fn test_calculate_deposit_rewards_with_expired_locks() { assert_ok!(RewardsPallet::::manage_asset_reward_vault( RuntimeOrigin::root(), vault_id, - asset.clone(), + asset, AssetAction::Add, )); diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs index 2e277e4f..29cdeb31 100644 --- a/pallets/rewards/src/types.rs +++ b/pallets/rewards/src/types.rs @@ -13,18 +13,13 @@ // // You should have received a copy of the GNU General Public License // along with Tangle. If not, see . - -use super::*; use crate::Config; use frame_support::traits::Currency; -use frame_system::pallet_prelude::BlockNumberFor; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::Percent; use sp_runtime::RuntimeDebug; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; -use tangle_primitives::types::rewards::UserRewards; -use tangle_primitives::{services::Asset, types::RoundIndex}; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/pallets/services/src/lib.rs b/pallets/services/src/lib.rs index f3a7c771..77cab221 100644 --- a/pallets/services/src/lib.rs +++ b/pallets/services/src/lib.rs @@ -20,13 +20,13 @@ #[cfg(not(feature = "std"))] extern crate alloc; - use frame_support::{ pallet_prelude::*, traits::{Currency, ExistenceRequirement, ReservableCurrency}, }; use frame_system::pallet_prelude::*; use sp_runtime::{traits::Get, DispatchResult}; +use tangle_primitives::traits::MultiAssetDelegationInfo; mod functions; mod impls; @@ -71,7 +71,7 @@ pub mod module { use sp_std::vec::Vec; use tangle_primitives::{ services::{MasterBlueprintServiceManagerRevision, *}, - Account, MultiAssetDelegationInfo, + Account, }; use types::*; @@ -187,6 +187,7 @@ pub mod module { type OperatorDelegationManager: tangle_primitives::traits::MultiAssetDelegationInfo< Self::AccountId, BalanceOf, + BlockNumberFor, >; /// Number of eras that slashes are deferred by, after computation. diff --git a/pallets/services/src/mock.rs b/pallets/services/src/mock.rs index 8e99f7b2..c6df6998 100644 --- a/pallets/services/src/mock.rs +++ b/pallets/services/src/mock.rs @@ -37,6 +37,7 @@ use sp_runtime::{ traits::{ConvertInto, IdentityLookup}, AccountId32, BuildStorage, Perbill, }; +use tangle_primitives::rewards::UserDepositWithLocks; use tangle_primitives::services::{Asset, EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; use core::ops::Mul; @@ -260,7 +261,7 @@ impl pallet_assets::Config for Runtime { pub type AssetId = u32; pub struct MockDelegationManager; -impl tangle_primitives::traits::MultiAssetDelegationInfo +impl tangle_primitives::traits::MultiAssetDelegationInfo for MockDelegationManager { type AssetId = AssetId; @@ -308,6 +309,13 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo _percentage: sp_runtime::Percent, ) { } + + fn get_user_deposit_with_locks( + _who: &AccountId, + _asset_id: Asset, + ) -> Option> { + None + } } parameter_types! { diff --git a/pallets/services/src/tests.rs b/pallets/services/src/tests.rs index f071038c..384f8fec 100644 --- a/pallets/services/src/tests.rs +++ b/pallets/services/src/tests.rs @@ -21,7 +21,7 @@ use k256::ecdsa::{SigningKey, VerifyingKey}; use mock::*; use sp_core::{bounded_vec, ecdsa, ByteArray, Pair, U256}; use sp_runtime::{KeyTypeId, Percent}; -use tangle_primitives::{services::*, MultiAssetDelegationInfo}; +use tangle_primitives::{services::*, traits::MultiAssetDelegationInfo}; const ALICE: u8 = 1; const BOB: u8 = 2; diff --git a/precompiles/assets/src/mock.rs b/precompiles/assets/src/mock.rs index 799fdee7..17a8213a 100644 --- a/precompiles/assets/src/mock.rs +++ b/precompiles/assets/src/mock.rs @@ -278,7 +278,7 @@ impl pallet_timestamp::Config for Runtime { type WeightInfo = (); } -impl tangle_primitives::NextAssetId for Runtime { +impl tangle_primitives::traits::NextAssetId for Runtime { fn next_asset_id() -> Option { None } diff --git a/precompiles/multi-asset-delegation/fuzzer/call.rs b/precompiles/multi-asset-delegation/fuzzer/call.rs index b5116c4e..963d1614 100644 --- a/precompiles/multi-asset-delegation/fuzzer/call.rs +++ b/precompiles/multi-asset-delegation/fuzzer/call.rs @@ -171,7 +171,7 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator (0.into(), token.into()), }; let amount = random_ed_multiple(&mut rng).into(); - vec![(PCall::deposit { asset_id, amount, token_address }, who)] + vec![(PCall::deposit { asset_id, amount, token_address, lock_multiplier: 0 }, who)] }, _ if op == PCall::schedule_withdraw_selectors()[0] => { // Schedule withdraw @@ -224,7 +224,6 @@ fn random_calls(mut rng: &mut R) -> impl IntoIterator { + PCall::deposit { asset_id, amount, token_address, lock_multiplier: 0 } => { let (deposit_asset, amount) = match (asset_id.as_u32(), token_address.0 .0) { (0, erc20_token) if erc20_token != [0; 20] => { (Asset::Erc20(erc20_token.into()), amount) diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index f9b8f6a3..d3944374 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -218,6 +218,7 @@ where asset_id: U256, token_address: Address, amount: U256, + lock_multiplier: u8, ) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -233,6 +234,15 @@ where (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; + let lock_multiplier = match lock_multiplier { + 0 => None, + 1 => Some(LockMultiplier::OneMonth), + 2 => Some(LockMultiplier::TwoMonths), + 3 => Some(LockMultiplier::ThreeMonths), + 4 => Some(LockMultiplier::SixMonths), + _ => return Err(RevertReason::custom("Invalid lock multiplier").into()), + }; + RuntimeHelper::::try_dispatch( handle, Some(who).into(), @@ -242,6 +252,7 @@ where .try_into() .map_err(|_| RevertReason::value_is_too_large("amount"))?, evm_address: Some(caller), + lock_multiplier, }, )?; @@ -322,7 +333,6 @@ where token_address: Address, amount: U256, blueprint_selection: Vec, - lock_multiplier: u8, ) -> EvmResult { handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; @@ -338,15 +348,6 @@ where (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), amount), }; - let lock_multiplier = match lock_multiplier { - 0 => None, - 1 => Some(LockMultiplier::OneMonth), - 2 => Some(LockMultiplier::TwoMonths), - 3 => Some(LockMultiplier::ThreeMonths), - 4 => Some(LockMultiplier::SixMonths), - _ => return Err(RevertReason::custom("Invalid lock multiplier").into()), - }; - RuntimeHelper::::try_dispatch( handle, Some(who).into(), @@ -361,7 +362,6 @@ where RevertReason::custom("Too many blueprint ids for fixed selection") })?, ), - lock_multiplier, }, )?; diff --git a/precompiles/multi-asset-delegation/src/mock.rs b/precompiles/multi-asset-delegation/src/mock.rs index 6d5407aa..b6c79999 100644 --- a/precompiles/multi-asset-delegation/src/mock.rs +++ b/precompiles/multi-asset-delegation/src/mock.rs @@ -32,17 +32,17 @@ use sp_core::{ sr25519::{Public as sr25519Public, Signature}, ConstU32, H160, }; +use sp_runtime::DispatchError; use sp_runtime::{ traits::{IdentifyAccount, Verify}, AccountId32, BuildStorage, }; -use tangle_primitives::{ - services::{EvmAddressMapping, EvmGasWeightMapping}, - ServiceManager, -}; +use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping}; +use tangle_primitives::traits::{RewardsManager, ServiceManager}; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; pub type Balance = u64; +pub type BlockNumber = u64; type Block = frame_system::mocking::MockBlock; type AssetId = u128; @@ -307,6 +307,45 @@ parameter_types! { pub const MaxDelegations: u32 = 50; } +pub struct MockRewardsManager; + +impl RewardsManager for MockRewardsManager { + type Error = DispatchError; + + fn record_deposit( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + _lock_multiplier: Option, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn record_withdrawal( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn record_service_reward( + _account_id: &AccountId, + _asset: Asset, + _amount: Balance, + ) -> Result<(), Self::Error> { + Ok(()) + } + + fn get_asset_deposit_cap_remaining(_asset: Asset) -> Result { + Ok(100_000_u32.into()) + } + + fn get_asset_incentive_cap(_asset: Asset) -> Result { + Ok(0_u32.into()) + } +} + impl pallet_multi_asset_delegation::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -323,7 +362,6 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MinDelegateAmount = ConstU64<100>; type Fungibles = Assets; type AssetId = AssetId; - type VaultId = AssetId; type ForceOrigin = frame_system::EnsureRoot; type MaxDelegatorBlueprints = MaxDelegatorBlueprints; type MaxOperatorBlueprints = MaxOperatorBlueprints; @@ -332,6 +370,7 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MaxDelegations = MaxDelegations; type SlashedAmountRecipient = SlashedAmountRecipient; type PalletId = PID; + type RewardsManager = MockRewardsManager; type WeightInfo = (); } diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index a2fdac39..d891be11 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -80,7 +80,7 @@ fn test_delegate_assets_invalid_operator() { Balances::make_free_balance_be(&delegator_account, 500); create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()), None)); PrecompilesValue::get() .prepare_test( @@ -119,7 +119,8 @@ fn test_delegate_assets() { RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, - Some(TestAccount::Alex.into()) + Some(TestAccount::Alex.into()), + None )); assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // should lose deposit @@ -157,7 +158,7 @@ fn test_delegate_assets_insufficient_balance() { create_and_mint_tokens(1, delegator_account, 500); - assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()))); + assert_ok!(MultiAssetDelegation::deposit(RuntimeOrigin::signed(delegator_account), Asset::Custom(1), 200, Some(TestAccount::Alex.into()), None)); PrecompilesValue::get() .prepare_test( @@ -201,6 +202,7 @@ fn test_schedule_withdraw() { asset_id: U256::from(1), amount: U256::from(200), token_address: Default::default(), + lock_multiplier: 0, }, ) .execute_returns(()); @@ -235,10 +237,6 @@ fn test_schedule_withdraw() { ) .execute_returns(()); - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 200); // no change }); } @@ -265,6 +263,7 @@ fn test_execute_withdraw() { asset_id: U256::from(1), amount: U256::from(200), token_address: Default::default(), + lock_multiplier: 0, }, ) .execute_returns(()); @@ -298,10 +297,6 @@ fn test_execute_withdraw() { ) .execute_returns(()); - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - >::put(3); PrecompilesValue::get() @@ -339,6 +334,7 @@ fn test_execute_withdraw_before_due() { asset_id: U256::from(1), amount: U256::from(200), token_address: Default::default(), + lock_multiplier: 0, }, ) .execute_returns(()); @@ -408,6 +404,7 @@ fn test_cancel_withdraw() { asset_id: U256::from(1), amount: U256::from(200), token_address: Default::default(), + lock_multiplier: 0, }, ) .execute_returns(()); @@ -441,10 +438,6 @@ fn test_cancel_withdraw() { ) .execute_returns(()); - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - PrecompilesValue::get() .prepare_test( TestAccount::Alex, diff --git a/precompiles/rewards/fuzzer/Cargo.toml b/precompiles/rewards/fuzzer/Cargo.toml deleted file mode 100644 index ae78a690..00000000 --- a/precompiles/rewards/fuzzer/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "pallet-evm-precompile-multi-asset-delegation-fuzzer" -version = "2.0.0" -authors.workspace = true -edition.workspace = true -license = "Apache-2.0" -homepage.workspace = true -repository.workspace = true -description = "Fuzzer for pallet-multi-asset-delegation precompile" -publish = false - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -honggfuzz = { workspace = true } - - -pallet-multi-asset-delegation = { workspace = true, features = ["fuzzing"], default-features = true } -pallet-evm-precompile-multi-asset-delegation = { features = ["fuzzing"], workspace = true, default-features = true } - -frame-system = { workspace = true, default-features = true } -frame-support = { workspace = true, default-features = true } - -fp-evm = { workspace = true } -precompile-utils = { workspace = true, features = ["std", "testing"] } -pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } - -sp-runtime = { workspace = true, default-features = true } -sp-io = { workspace = true, default-features = true } -sp-tracing = { workspace = true, default-features = true } - -rand = { features = ["small_rng"], workspace = true, default-features = true } -log = { workspace = true, default-features = true } - -[[bin]] -name = "mad-precompile-fuzzer" -path = "call.rs" diff --git a/precompiles/rewards/fuzzer/call.rs b/precompiles/rewards/fuzzer/call.rs deleted file mode 100644 index 7507d2f0..00000000 --- a/precompiles/rewards/fuzzer/call.rs +++ /dev/null @@ -1,233 +0,0 @@ -// This file is part of Tangle. -// Copyright (C) 2022-2024 Tangle Foundation. -// -// Tangle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Tangle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Tangle. If not, see . - -//! # Running -//! Running this fuzzer can be done with `cargo hfuzz run rewards-fuzzer`. `honggfuzz` CLI -//! options can be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. -//! -//! # Debugging a panic -//! Once a panic is found, it can be debugged with -//! `cargo hfuzz run-debug rewards-fuzzer hfuzz_workspace/rewards-fuzzer/*.fuzz`. - -use fp_evm::Context; -use fp_evm::PrecompileSet; -use frame_support::traits::{Currency, Get}; -use honggfuzz::fuzz; -use pallet_evm::AddressMapping; -use pallet_evm_precompile_rewards::{ - mock::*, mock_evm::PrecompilesValue, RewardsPrecompileCall as RewardsCall, -}; -use pallet_rewards::pallet as rewards; -use precompile_utils::prelude::*; -use precompile_utils::testing::*; -use rand::{seq::SliceRandom, Rng}; -use sp_runtime::traits::{Scale, Zero, One}; -use sp_runtime::Percent; - -const MAX_APY: u32 = 1000; // 10% in basis points -const MAX_REWARDS: u128 = u128::MAX; -const MAX_VAULT_ID: u128 = 1000; -const MAX_BLUEPRINT_ID: u64 = 1000; - -type PCall = RewardsCall; - -fn random_address(rng: &mut R) -> Address { - Address(rng.gen::<[u8; 20]>().into()) -} - -/// Generate a random signed origin -fn random_signed_origin(rng: &mut R) -> (RuntimeOrigin, Address) { - let addr = random_address(rng); - let signer = >::into_account_id(addr.0); - (RuntimeOrigin::signed(signer), addr) -} - -/// Generate a random asset ID -fn random_asset(rng: &mut R) -> u128 { - rng.gen_range(1..u128::MAX) -} - -/// Generate a random APY value (max 10%) -fn random_apy(rng: &mut R) -> u32 { - rng.gen_range(1..=MAX_APY) -} - -/// Generate random rewards amount -fn random_rewards(rng: &mut R) -> u128 { - rng.gen_range(1..MAX_REWARDS) -} - -/// Generate a random vault ID -fn random_vault_id(rng: &mut R) -> u128 { - rng.gen_range(1..MAX_VAULT_ID) -} - -/// Generate a random blueprint ID -fn random_blueprint_id(rng: &mut R) -> u64 { - rng.gen_range(1..MAX_BLUEPRINT_ID) -} - -/// Update asset rewards call -fn update_asset_rewards_call(rng: &mut R) -> (PCall, Address) { - let (origin, who) = random_signed_origin(rng); - let asset_id = random_asset(rng).into(); - let rewards = random_rewards(rng).into(); - (PCall::update_asset_rewards { asset_id, rewards }, who) -} - -/// Update asset APY call -fn update_asset_apy_call(rng: &mut R) -> (PCall, Address) { - let (origin, who) = random_signed_origin(rng); - let asset_id = random_asset(rng).into(); - let apy = random_apy(rng); - (PCall::update_asset_apy { asset_id, apy }, who) -} - -/// Set incentive APY and cap call -fn set_incentive_apy_and_cap_call(rng: &mut R) -> (PCall, Address) { - let (origin, who) = random_signed_origin(rng); - let vault_id = random_vault_id(rng).into(); - let apy = random_apy(rng); - let cap = random_rewards(rng).into(); - (PCall::set_incentive_apy_and_cap { vault_id, apy, cap }, who) -} - -/// Whitelist blueprint call -fn whitelist_blueprint_call(rng: &mut R) -> (PCall, Address) { - let (origin, who) = random_signed_origin(rng); - let blueprint_id = random_blueprint_id(rng); - (PCall::whitelist_blueprint_for_rewards { blueprint_id }, who) -} - -/// Manage asset in vault call -fn manage_asset_in_vault_call(rng: &mut R) -> (PCall, Address) { - let (origin, who) = random_signed_origin(rng); - let vault_id = random_vault_id(rng).into(); - let asset_id = random_asset(rng).into(); - let action = rng.gen_range(0..=1); - (PCall::manage_asset_in_vault { vault_id, asset_id, action }, who) -} - -/// Generate random calls for fuzzing -fn random_calls(mut rng: &mut R) -> impl IntoIterator { - let op = PCall::selectors().choose(rng).cloned().unwrap(); - match op { - _ if op == PCall::update_asset_rewards_selectors()[0] => { - vec![update_asset_rewards_call(&mut rng)] - }, - _ if op == PCall::update_asset_apy_selectors()[0] => { - vec![update_asset_apy_call(&mut rng)] - }, - _ if op == PCall::set_incentive_apy_and_cap_selectors()[0] => { - vec![set_incentive_apy_and_cap_call(&mut rng)] - }, - _ if op == PCall::whitelist_blueprint_for_rewards_selectors()[0] => { - vec![whitelist_blueprint_call(&mut rng)] - }, - _ if op == PCall::manage_asset_in_vault_selectors()[0] => { - vec![manage_asset_in_vault_call(&mut rng)] - }, - _ => vec![], - } -} - -fn main() { - loop { - fuzz!(|data: &[u8]| { - let mut rng = rand::thread_rng(); - let calls = random_calls(&mut rng); - - // Create test externalities - let mut ext = ExtBuilder::default().build(); - ext.execute_with(|| { - let precompiles = PrecompilesValue::get(); - - // Execute each call - for (call, who) in calls { - let input = call.encode(); - let context = Context { - address: Default::default(), - caller: who.0, - apparent_value: Default::default(), - }; - - let info = call.estimate_gas(input.clone(), &mut EvmDataWriter::new(), context); - match info { - Ok((_, estimate)) => { - let mut gasometer = Gasometer::new(estimate); - let outcome = precompiles - .execute(&context.address, &mut gasometer, &context, &input) - .expect("Precompile failed"); - - // Perform sanity checks - do_sanity_checks(call, who, outcome); - }, - Err(e) => { - // Expected errors are ok - println!("Expected error: {:?}", e); - }, - } - } - }); - }); - } -} - -/// Perform sanity checks on the state after a call is executed successfully -fn do_sanity_checks(call: PCall, origin: Address, outcome: PrecompileOutput) { - match call { - PCall::update_asset_rewards { asset_id, rewards } => { - // Check that rewards were updated - assert_eq!(Rewards::asset_rewards(asset_id), rewards); - }, - PCall::update_asset_apy { asset_id, apy } => { - // Check that APY was updated and is within bounds - assert!(apy <= MAX_APY); - assert_eq!(Rewards::asset_apy(asset_id), apy); - }, - PCall::set_incentive_apy_and_cap { vault_id, apy, cap } => { - // Check APY is within bounds - assert!(apy <= MAX_APY); - - // Check config was updated - if let Some(config) = Rewards::reward_config() { - if let Some(vault_config) = config.configs.get(&vault_id) { - assert_eq!(vault_config.apy, Percent::from_parts(apy as u8)); - assert_eq!(vault_config.cap, cap); - } - } - }, - PCall::whitelist_blueprint_for_rewards { blueprint_id } => { - // Check blueprint was whitelisted - if let Some(config) = Rewards::reward_config() { - assert!(config.whitelisted_blueprints.contains(&blueprint_id)); - } - }, - PCall::manage_asset_in_vault { vault_id, asset_id, action } => { - // Check asset was added/removed from vault - if let Some(config) = Rewards::reward_config() { - if let Some(vault_config) = config.configs.get(&vault_id) { - match action { - 0 => assert!(vault_config.assets.contains(&asset_id)), - 1 => assert!(!vault_config.assets.contains(&asset_id)), - _ => panic!("Invalid action"), - } - } - } - }, - _ => {}, - } -} diff --git a/precompiles/rewards/src/lib.rs b/precompiles/rewards/src/lib.rs index 69b5f38e..6594b60e 100644 --- a/precompiles/rewards/src/lib.rs +++ b/precompiles/rewards/src/lib.rs @@ -15,215 +15,161 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(any(test, feature = "fuzzing"))] -pub mod mock; -#[cfg(test)] -mod tests; - -use fp_evm::PrecompileHandle; -use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - traits::Currency, +use core::marker::PhantomData; +use frame_support::traits::Currency; +use fp_evm::{PrecompileHandle, PrecompileOutput}; +use pallet_evm::Precompile; +use pallet_rewards::Config; +use precompile_utils::{ + prelude::*, + solidity::{ + codec::{Address, BoundedVec}, + modifier::FunctionModifier, + revert::InjectBacktrace, + }, }; -use pallet_evm::AddressMapping; -use precompile_utils::prelude::*; use sp_core::{H160, U256}; -use sp_runtime::traits::Dispatchable; -use sp_std::{marker::PhantomData, vec::Vec}; -use tangle_primitives::{ - services::Asset, - types::{rewards::{LockMultiplier, RewardType}, WrappedAccountId32}, -}; - -type BalanceOf = - <::Currency as Currency< - ::AccountId, - >>::Balance; +use sp_runtime::traits::StaticLookup; +use sp_std::{marker::PhantomData, prelude::*}; +use tangle_primitives::services::Asset; -type AssetIdOf = ::AssetId; +/// Solidity selector of the Transfer log, which is the Keccak of the Log signature. +pub const SELECTOR_LOG_REWARDS_CLAIMED: [u8; 32] = keccak256!("RewardsClaimed(address,uint256)"); +/// A precompile to wrap the functionality from pallet-rewards. pub struct RewardsPrecompile(PhantomData); #[precompile_utils::precompile] impl RewardsPrecompile where - Runtime: pallet_rewards::Config + pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: From>, - BalanceOf: TryFrom + Into + solidity::Codec, - AssetIdOf: TryFrom + Into + From, - Runtime::AccountId: From, + Runtime: Config + pallet_evm::Config, + Runtime::AccountId: From + Into, { - /// Set APY for an asset (admin only) - #[precompile::public("setAssetApy(uint256,address,uint256)")] - fn set_asset_apy( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - apy_basis_points: U256, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - let asset = if token_address == Address::zero() { - Asset::Custom( - asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, - ) - } else { - Asset::Erc20(token_address.into()) - }; - - let apy: u32 = apy_basis_points - .try_into() - .map_err(|_| revert("Invalid APY basis points"))?; - - let call = pallet_rewards::Call::::set_asset_apy { - asset, - apy_basis_points: apy, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - Ok(()) - } - - /// Claim rewards for a specific asset and reward type - #[precompile::public("claimRewards(uint256,address,uint8)")] - fn claim_rewards( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - reward_type: u8, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - let asset = if token_address == Address::zero() { - Asset::Custom( - asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, - ) - } else { - Asset::Erc20(token_address.into()) - }; - - let reward_type = match reward_type { - 0 => RewardType::Boost, - 1 => RewardType::Service, - 2 => RewardType::Restaking, - _ => return Err(revert("Invalid reward type")), - }; - - let call = pallet_rewards::Call::::claim_rewards { - asset, - reward_type, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - Ok(()) - } - - /// Get user's reward info for an asset - #[precompile::public("getUserRewards(address,uint256,address)")] - fn get_user_rewards( - handle: &mut impl PrecompileHandle, - user: Address, - asset_id: U256, - token_address: Address, - ) -> EvmResult<(U256, U256, U256, U256)> { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let user = Runtime::AddressMapping::into_account_id(user.into()); - let asset = if token_address == Address::zero() { - Asset::Custom( - asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, - ) - } else { - Asset::Erc20(token_address.into()) - }; - - let rewards = pallet_rewards::Pallet::::user_rewards(&user, asset); - - Ok(( - rewards.boost_rewards.amount.into(), - rewards.boost_rewards.expiry.into(), - rewards.service_rewards.into(), - rewards.restaking_rewards.into(), - )) - } - - /// Get asset APY and capacity - #[precompile::public("getAssetInfo(uint256,address)")] - fn get_asset_info( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - ) -> EvmResult<(U256, U256)> { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let asset = if token_address == Address::zero() { - Asset::Custom( - asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, - ) - } else { - Asset::Erc20(token_address.into()) - }; - - let apy = pallet_rewards::Pallet::::asset_apy(asset); - let capacity = pallet_rewards::Pallet::::asset_capacity(asset); - - Ok((apy.into(), capacity.into())) - } - - /// Update APY for an asset (admin only) - #[precompile::public("updateAssetApy(uint256,address,uint32)")] - fn update_asset_apy( - handle: &mut impl PrecompileHandle, - asset_id: U256, - token_address: Address, - apy_basis_points: u32, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_write_gas_cost())?; - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - - let asset = if token_address == Address::zero() { - Asset::Custom( - asset_id.try_into().map_err(|_| revert("Invalid asset ID"))?, - ) - } else { - Asset::Erc20(token_address.into()) - }; - - let call = pallet_rewards::Call::::update_asset_apy { - asset, - apy_basis_points, - }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - Ok(()) - } -} - -#[cfg(test)] -mod test { - use super::*; - use mock::*; - use precompile_utils::testing::*; - use sp_core::H160; - - fn precompiles() -> TestPrecompileSet { - PrecompilesValue::get() - } - - #[test] - fn test_solidity_interface_has_all_function_selectors_documented() { - for file in ["Rewards.sol"] { - precompiles() - .process_selectors(file, |fn_selector, fn_signature| { - assert!( - DOCUMENTED_FUNCTIONS.contains(&fn_selector), - "documented_functions must contain {fn_selector:?} ({fn_signature})", - ); - }); - } - } + #[precompile::public("claimRewards(uint256,address)")] + fn claim_rewards( + handle: &mut impl PrecompileHandle, + asset_id: U256, + token_address: Address, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let (asset, _) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), U256::zero()) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), U256::zero()), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_rewards::Call::::claim_rewards { asset }, + )?; + + Ok(()) + } + + #[precompile::public("forceClaimRewards(address,uint256,address)")] + fn force_claim_rewards( + handle: &mut impl PrecompileHandle, + account: Address, + asset_id: U256, + token_address: Address, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + let target = Runtime::AddressMapping::into_account_id(account.0); + + let (asset, _) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), U256::zero()) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), U256::zero()), + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_rewards::Call::::force_claim_rewards { account: target, asset }, + )?; + + Ok(()) + } + + #[precompile::public("updateVaultRewardConfig(uint256,uint8,uint256,uint256,uint32)")] + fn update_vault_reward_config( + handle: &mut impl PrecompileHandle, + vault_id: U256, + apy: u8, + deposit_cap: U256, + incentive_cap: U256, + boost_multiplier: u32, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let config = pallet_rewards::RewardConfigForAssetVault { + apy: sp_runtime::Percent::from_percent(apy.min(100)), + deposit_cap: deposit_cap.try_into().map_err(|_| RevertReason::value_is_too_large("deposit_cap"))?, + incentive_cap: incentive_cap.try_into().map_err(|_| RevertReason::value_is_too_large("incentive_cap"))?, + boost_multiplier: Some(boost_multiplier.min(500)), // Cap at 5x + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_rewards::Call::::udpate_vault_reward_config { + vault_id: vault_id.try_into().map_err(|_| RevertReason::value_is_too_large("vault_id"))?, + new_config: config, + }, + )?; + + Ok(()) + } + + #[precompile::public("manageAssetRewardVault(uint256,uint256,address,bool)")] + fn manage_asset_reward_vault( + handle: &mut impl PrecompileHandle, + vault_id: U256, + asset_id: U256, + token_address: Address, + add: bool, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let caller = handle.context().caller; + let who = Runtime::AddressMapping::into_account_id(caller); + + let (asset, _) = match (asset_id.as_u128(), token_address.0 .0) { + (0, erc20_token) if erc20_token != [0; 20] => { + (Asset::Erc20(erc20_token.into()), U256::zero()) + }, + (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), U256::zero()), + }; + + let action = if add { + pallet_rewards::AssetAction::Add + } else { + pallet_rewards::AssetAction::Remove + }; + + RuntimeHelper::::try_dispatch( + handle, + Some(who).into(), + pallet_rewards::Call::::manage_asset_reward_vault { + vault_id: vault_id.try_into().map_err(|_| RevertReason::value_is_too_large("vault_id"))?, + asset_id: asset, + action, + }, + )?; + + Ok(()) + } } diff --git a/precompiles/rewards/src/tests.rs b/precompiles/rewards/src/tests.rs index 3682c881..bfd81cd2 100644 --- a/precompiles/rewards/src/tests.rs +++ b/precompiles/rewards/src/tests.rs @@ -1,196 +1,297 @@ use super::*; -use frame_support::assert_ok; use mock::*; use precompile_utils::testing::*; -use sp_core::{H160, U256}; -use sp_runtime::traits::Zero; -use tangle_primitives::services::Asset; +use sp_core::H160; +use sp_runtime::Percent; +use frame_support::assert_ok; + +fn precompiles() -> TestPrecompileSet { + PrecompilesValue::get() +} + +#[test] +fn test_solidity_interface_has_all_function_selectors_documented() { + for file in ["Rewards.sol"] { + precompiles() + .process_selectors(file, |fn_selector, fn_signature| { + assert!( + DOCUMENTED_FUNCTIONS.contains(&fn_selector), + "documented_functions must contain {fn_selector:?} ({fn_signature})", + ); + }); + } +} #[test] -fn test_whitelist_asset() { +fn test_claim_rewards() { ExtBuilder::default().build().execute_with(|| { - let precompiles = precompiles(); - - // Test native asset - let asset_id = U256::from(1); - let token_address = Address::zero(); - - let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) - .write(asset_id) - .write(token_address) - .build(); - - let caller = H160::from_low_u64_be(1); - let context = Context { - address: Default::default(), - caller, - apparent_value: U256::zero(), + let vault_id = 1u32; + let asset_id = Asset::Custom(1); + let alice: AccountId = TestAccount::Alice.into(); + let deposit_amount = 1_000u128; + + // Setup vault and add asset + assert_ok!(Rewards::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset_id, + AssetAction::Add, + )); + + // Setup reward config + let config = RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: 1_000_000, + incentive_cap: 100_000, + boost_multiplier: Some(200), }; - - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Test ERC20 asset - let token_address = Address(H160::from_low_u64_be(2)); - let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) - .write(U256::zero()) - .write(token_address) - .build(); - - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); + assert_ok!(Rewards::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + config, + )); + + // Setup mock deposit + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert( + (alice.clone(), asset_id), + UserDepositWithLocks { unlocked_amount: deposit_amount, amount_with_locks: None }, + ); + }); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::claim_rewards { + asset_id: U256::from(1), + token_address: Address::zero(), + }, + ) + .execute_returns(()); + + // Check that rewards were claimed + let claimed = UserClaimedReward::::get(alice, vault_id); + assert!(claimed.is_some()); }); } #[test] -fn test_set_asset_apy() { +fn test_force_claim_rewards() { ExtBuilder::default().build().execute_with(|| { - let precompiles = precompiles(); - - // Whitelist asset first - let asset_id = U256::from(1); - let token_address = Address::zero(); - let apy = 500u32; // 5% APY - - // Whitelist the asset - let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) - .write(asset_id) - .write(token_address) - .build(); - - let caller = H160::from_low_u64_be(1); - let context = Context { - address: Default::default(), - caller, - apparent_value: U256::zero(), + let vault_id = 1u32; + let asset_id = Asset::Custom(1); + let alice: AccountId = TestAccount::Alice.into(); + let bob: AccountId = TestAccount::Bob.into(); + let deposit_amount = 1_000u128; + + // Setup vault and add asset + assert_ok!(Rewards::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset_id, + AssetAction::Add, + )); + + // Setup reward config + let config = RewardConfigForAssetVault { + apy: Percent::from_percent(10), + deposit_cap: 1_000_000, + incentive_cap: 100_000, + boost_multiplier: Some(200), }; + assert_ok!(Rewards::udpate_vault_reward_config( + RuntimeOrigin::root(), + vault_id, + config, + )); + + // Setup mock deposit for Bob + MOCK_DELEGATION_INFO.with(|m| { + m.borrow_mut().deposits.insert( + (bob.clone(), asset_id), + UserDepositWithLocks { unlocked_amount: deposit_amount, amount_with_locks: None }, + ); + }); + + // Alice force claims rewards for Bob + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::force_claim_rewards { + account: Address(TestAccount::Bob.into()), + asset_id: U256::from(1), + token_address: Address::zero(), + }, + ) + .execute_returns(()); + + // Check that rewards were claimed for Bob + let claimed = UserClaimedReward::::get(bob, vault_id); + assert!(claimed.is_some()); + }); +} - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Set APY - let input = EvmDataWriter::new_with_selector(Action::SetAssetApy) - .write(asset_id) - .write(token_address) - .write(apy) - .build(); - - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Verify APY was set - let input = EvmDataWriter::new_with_selector(Action::GetAssetInfo) - .write(asset_id) - .write(token_address) - .build(); - - let mut handle = MockHandle::new(context, input); - let result = precompiles.execute(&mut handle).unwrap(); - let (actual_apy, _) = EvmDataReader::new(&result) - .read::<(U256, U256)>() - .unwrap(); - assert_eq!(actual_apy, apy.into()); +#[test] +fn test_update_vault_reward_config() { + ExtBuilder::default().build().execute_with(|| { + let vault_id = 1u32; + + // Update vault config + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::update_vault_reward_config { + vault_id: U256::from(vault_id), + apy: 10, + deposit_cap: U256::from(1_000_000u128), + incentive_cap: U256::from(100_000u128), + boost_multiplier: 200, + }, + ) + .execute_returns(()); + + // Verify config was updated + let config = RewardConfigStorage::::get(vault_id); + assert!(config.is_some()); + let config = config.unwrap(); + assert_eq!(config.apy, Percent::from_percent(10)); + assert_eq!(config.deposit_cap, 1_000_000u128); + assert_eq!(config.incentive_cap, 100_000u128); + assert_eq!(config.boost_multiplier, Some(200)); }); } #[test] -fn test_update_asset_apy() { +fn test_manage_asset_reward_vault() { ExtBuilder::default().build().execute_with(|| { - let precompiles = precompiles(); - - // Whitelist asset first - let asset_id = U256::from(1); - let token_address = Address::zero(); - let initial_apy = 500u32; // 5% APY - let updated_apy = 1000u32; // 10% APY - - // Whitelist the asset - let input = EvmDataWriter::new_with_selector(Action::WhitelistAsset) - .write(asset_id) - .write(token_address) - .build(); - - let caller = H160::from_low_u64_be(1); - let context = Context { - address: Default::default(), - caller, - apparent_value: U256::zero(), - }; + let vault_id = 1u32; + let asset_id = 1u128; + + // Add asset to vault + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::manage_asset_reward_vault { + vault_id: U256::from(vault_id), + asset_id: U256::from(asset_id), + token_address: Address::zero(), + add: true, + }, + ) + .execute_returns(()); + + // Verify asset was added + let vault = AssetLookupRewardVaults::::get(Asset::Custom(asset_id)); + assert_eq!(vault, Some(vault_id)); + + // Remove asset from vault + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::manage_asset_reward_vault { + vault_id: U256::from(vault_id), + asset_id: U256::from(asset_id), + token_address: Address::zero(), + add: false, + }, + ) + .execute_returns(()); + + // Verify asset was removed + let vault = AssetLookupRewardVaults::::get(Asset::Custom(asset_id)); + assert_eq!(vault, None); + }); +} - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Set initial APY - let input = EvmDataWriter::new_with_selector(Action::SetAssetApy) - .write(asset_id) - .write(token_address) - .write(initial_apy) - .build(); - - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Update APY - let input = EvmDataWriter::new_with_selector(Action::UpdateAssetApy) - .write(asset_id) - .write(token_address) - .write(updated_apy) - .build(); - - let mut handle = MockHandle::new(context, input); - assert_ok!(precompiles.execute(&mut handle)); - - // Verify APY was updated - let input = EvmDataWriter::new_with_selector(Action::GetAssetInfo) - .write(asset_id) - .write(token_address) - .build(); - - let mut handle = MockHandle::new(context, input); - let result = precompiles.execute(&mut handle).unwrap(); - let (actual_apy, _) = EvmDataReader::new(&result) - .read::<(U256, U256)>() - .unwrap(); - assert_eq!(actual_apy, updated_apy.into()); +#[test] +fn test_claim_rewards_no_vault() { + ExtBuilder::default().build().execute_with(|| { + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::claim_rewards { + asset_id: U256::from(1), + token_address: Address::zero(), + }, + ) + .execute_reverts(|output| output == b"AssetNotInVault"); }); } #[test] -fn test_get_user_rewards() { +fn test_claim_rewards_no_deposit() { ExtBuilder::default().build().execute_with(|| { - let precompiles = precompiles(); - - // Setup test data - let user = Address(H160::from_low_u64_be(2)); - let asset_id = U256::from(1); - let token_address = Address::zero(); - - // Query rewards - let input = EvmDataWriter::new_with_selector(Action::GetUserRewards) - .write(user) - .write(asset_id) - .write(token_address) - .build(); - - let context = Context { - address: Default::default(), - caller: H160::from_low_u64_be(1), - apparent_value: U256::zero(), - }; + let vault_id = 1u32; + let asset_id = Asset::Custom(1); + + // Setup vault and add asset + assert_ok!(Rewards::manage_asset_reward_vault( + RuntimeOrigin::root(), + vault_id, + asset_id, + AssetAction::Add, + )); + + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::claim_rewards { + asset_id: U256::from(1), + token_address: Address::zero(), + }, + ) + .execute_reverts(|output| output == b"NoRewardsAvailable"); + }); +} - let mut handle = MockHandle::new(context, input); - let result = precompiles.execute(&mut handle).unwrap(); - - // Parse result - let (boost_amount, boost_expiry, service_rewards, restaking_rewards) = - EvmDataReader::new(&result) - .read::<(U256, U256, U256, U256)>() - .unwrap(); - - // Initially all rewards should be zero - assert!(boost_amount.is_zero()); - assert!(boost_expiry.is_zero()); - assert!(service_rewards.is_zero()); - assert!(restaking_rewards.is_zero()); +#[test] +fn test_update_vault_reward_config_invalid_values() { + ExtBuilder::default().build().execute_with(|| { + // Test APY > 100% + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::update_vault_reward_config { + vault_id: U256::from(1), + apy: 101, + deposit_cap: U256::from(1_000_000u128), + incentive_cap: U256::from(100_000u128), + boost_multiplier: 200, + }, + ) + .execute_returns(()); + + // Verify APY was capped at 100% + let config = RewardConfigStorage::::get(1); + assert!(config.is_some()); + assert_eq!(config.unwrap().apy, Percent::from_percent(100)); + + // Test boost multiplier > 500% + PrecompilesValue::get() + .prepare_test( + TestAccount::Alice, + H160::from_low_u64_be(1), + PrecompileCall::update_vault_reward_config { + vault_id: U256::from(1), + apy: 50, + deposit_cap: U256::from(1_000_000u128), + incentive_cap: U256::from(100_000u128), + boost_multiplier: 600, + }, + ) + .execute_returns(()); + + // Verify boost multiplier was capped at 500% + let config = RewardConfigStorage::::get(1); + assert!(config.is_some()); + assert_eq!(config.unwrap().boost_multiplier, Some(500)); }); } diff --git a/precompiles/services/src/mock.rs b/precompiles/services/src/mock.rs index 7ba2ddc8..ef41b084 100644 --- a/precompiles/services/src/mock.rs +++ b/precompiles/services/src/mock.rs @@ -41,6 +41,7 @@ use sp_runtime::{ testing::UintAuthorityId, traits::ConvertInto, AccountId32, BuildStorage, Perbill, }; use std::{collections::BTreeMap, sync::Arc}; +use tangle_primitives::rewards::UserDepositWithLocks; use tangle_primitives::services::{EvmAddressMapping, EvmGasWeightMapping, EvmRunner}; pub type AccountId = AccountId32; @@ -391,7 +392,7 @@ impl From for sp_core::sr25519::Public { pub type AssetId = u32; pub struct MockDelegationManager; -impl tangle_primitives::traits::MultiAssetDelegationInfo +impl tangle_primitives::traits::MultiAssetDelegationInfo for MockDelegationManager { type AssetId = AssetId; @@ -435,6 +436,13 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo _percentage: sp_runtime::Percent, ) { } + + fn get_user_deposit_with_locks( + _who: &AccountId, + _asset_id: Asset, + ) -> Option> { + None + } } parameter_types! { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index e8f95d30..8f44f6e3 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -30,13 +30,12 @@ use sp_runtime::{ #[cfg(not(feature = "std"))] extern crate alloc; +pub mod chain_identifier; +pub mod impls; pub mod services; pub mod types; pub use types::*; -pub mod chain_identifier; -pub mod impls; pub mod traits; -pub use traits::*; #[cfg(feature = "verifying")] pub mod verifier; diff --git a/primitives/src/traits/data_provider.rs b/primitives/src/traits/data_provider.rs index 485bc4fa..ec54535e 100644 --- a/primitives/src/traits/data_provider.rs +++ b/primitives/src/traits/data_provider.rs @@ -56,22 +56,22 @@ pub fn median(mut items: Vec) -> Option { macro_rules! create_median_value_data_provider { ($name:ident, $key:ty, $value:ty, $timestamped_value:ty, [$( $provider:ty ),*]) => { pub struct $name; - impl $crate::DataProvider<$key, $value> for $name { + impl $crate::traits::DataProvider<$key, $value> for $name { fn get(key: &$key) -> Option<$value> { let mut values = vec![]; $( - if let Some(v) = <$provider as $crate::DataProvider<$key, $value>>::get(&key) { + if let Some(v) = <$provider as $crate::traits::DataProvide<$key, $value>>::get(&key) { values.push(v); } )* $crate::data_provider::median(values) } } - impl $crate::DataProviderExtended<$key, $timestamped_value> for $name { + impl $crate::traits::DataProvideExtended<$key, $timestamped_value> for $name { fn get_no_op(key: &$key) -> Option<$timestamped_value> { let mut values = vec![]; $( - if let Some(v) = <$provider as $crate::DataProviderExtended<$key, $timestamped_value>>::get_no_op(&key) { + if let Some(v) = <$provider as $crate::traits::DataProvideExtended<$key, $timestamped_value>>::get_no_op(&key) { values.push(v); } )* @@ -80,7 +80,7 @@ macro_rules! create_median_value_data_provider { fn get_all_values() -> Vec<($key, Option<$timestamped_value>)> { let mut keys = sp_std::collections::btree_set::BTreeSet::new(); $( - <$provider as $crate::DataProviderExtended<$key, $timestamped_value>>::get_all_values() + <$provider as $crate::traits::DataProvideExtended<$key, $timestamped_value>>::get_all_values() .into_iter() .for_each(|(k, _)| { keys.insert(k); }); )* diff --git a/primitives/src/traits/rewards.rs b/primitives/src/traits/rewards.rs index 06bbea80..dff0a1fd 100644 --- a/primitives/src/traits/rewards.rs +++ b/primitives/src/traits/rewards.rs @@ -16,8 +16,6 @@ use crate::services::Asset; use crate::types::rewards::LockMultiplier; -use frame_support::traits::Currency; -use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::Zero; /// Trait for managing rewards in the Tangle network. @@ -73,7 +71,7 @@ pub trait RewardsManager { /// # Returns /// * `Ok(Balance)` - The maximum deposit cap for the asset /// * `Err(Self::Error)` - If there was an error retrieving the cap - fn get_asset_deposit_cap(asset: Asset) -> Result; + fn get_asset_deposit_cap_remaining(asset: Asset) -> Result; /// Gets the incentive cap for an asset at a given block number. /// This represents the minimum amount required to receive full incentives. @@ -119,7 +117,7 @@ where Ok(()) } - fn get_asset_deposit_cap(_asset: Asset) -> Result { + fn get_asset_deposit_cap_remaining(_asset: Asset) -> Result { Ok(Balance::zero()) } diff --git a/primitives/src/types/rewards.rs b/primitives/src/types/rewards.rs index d5273f2e..19912cb7 100644 --- a/primitives/src/types/rewards.rs +++ b/primitives/src/types/rewards.rs @@ -1,8 +1,7 @@ use super::*; use crate::services::Asset; -use frame_system::pallet_prelude::BlockNumberFor; use frame_system::Config; -use sp_runtime::Saturating; +use sp_std::vec::Vec; /// Represents different types of rewards a user can earn #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Eq)] diff --git a/runtime/mainnet/Cargo.toml b/runtime/mainnet/Cargo.toml index a1b2fbc6..6aadcbbc 100644 --- a/runtime/mainnet/Cargo.toml +++ b/runtime/mainnet/Cargo.toml @@ -91,6 +91,7 @@ pallet-services-rpc-runtime-api = { workspace = true } tangle-primitives = { workspace = true, features = ["verifying"] } tangle-crypto-primitives = { workspace = true } pallet-multi-asset-delegation = { workspace = true } +pallet-rewards = { workspace = true } # Frontier dependencies fp-rpc = { workspace = true } @@ -230,6 +231,7 @@ std = [ "pallet-services/std", "pallet-multi-asset-delegation/std", "pallet-services-rpc-runtime-api/std", + "pallet-rewards/std", # Frontier "fp-rpc/std", diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index 630f1961..ee398f9b 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -1204,7 +1204,7 @@ pub type AssetId = u128; #[cfg(feature = "runtime-benchmarks")] pub type AssetId = u32; -impl tangle_primitives::NextAssetId for Runtime { +impl tangle_primitives::traits::NextAssetId for Runtime { fn next_asset_id() -> Option { pallet_assets::NextAssetId::::get() } @@ -1265,7 +1265,6 @@ impl pallet_multi_asset_delegation::Config for Runtime { type AssetId = AssetId; type ForceOrigin = frame_system::EnsureRoot; type PalletId = PID; - type VaultId = AssetId; type SlashedAmountRecipient = TreasuryAccount; type MaxDelegatorBlueprints = MaxDelegatorBlueprints; type MaxOperatorBlueprints = MaxOperatorBlueprints; @@ -1273,6 +1272,7 @@ impl pallet_multi_asset_delegation::Config for Runtime { type MaxUnstakeRequests = MaxUnstakeRequests; type MaxDelegations = MaxDelegations; type EvmRunner = crate::tangle_services::PalletEvmRunner; + type RewardsManager = Rewards; type EvmGasWeightMapping = crate::tangle_services::PalletEVMGasWeightMapping; type EvmAddressMapping = crate::tangle_services::PalletEVMAddressMapping; type WeightInfo = (); @@ -1308,6 +1308,20 @@ impl pallet_tangle_lst::Config for Runtime { type MaxPointsToBalance = frame_support::traits::ConstU8<10>; } +parameter_types! { + pub const RewardsPID: PalletId = PalletId(*b"py/tnrew"); +} + +impl pallet_rewards::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssetId = AssetId; + type Currency = Balances; + type PalletId = RewardsPID; + type VaultId = u32; + type DelegationManager = MultiAssetDelegation; + type ForceOrigin = frame_system::EnsureRoot; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime { @@ -1368,6 +1382,7 @@ construct_runtime!( Assets: pallet_assets = 44, MultiAssetDelegation: pallet_multi_asset_delegation = 45, Services: pallet_services = 46, + Rewards: pallet_rewards = 47, } ); diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index ed132d86..48aef3de 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -89,6 +89,7 @@ pallet-utility = { workspace = true } pallet-multisig = { workspace = true } pallet-vesting = { workspace = true } pallet-tangle-lst = { workspace = true } +pallet-rewards = { workspace = true } # Tangle dependencies pallet-airdrop-claims = { workspace = true } @@ -256,6 +257,7 @@ std = [ "pallet-multi-asset-delegation/std", "pallet-tangle-lst/std", "pallet-services-rpc-runtime-api/std", + "pallet-rewards/std", # Frontier "fp-evm/std", diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 51c048b3..711944af 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -1216,6 +1216,20 @@ impl pallet_tangle_lst::Config for Runtime { type MaxPointsToBalance = frame_support::traits::ConstU8<10>; } +parameter_types! { + pub const RewardsPID: PalletId = PalletId(*b"py/tnrew"); +} + +impl pallet_rewards::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssetId = AssetId; + type Currency = Balances; + type PalletId = RewardsPID; + type VaultId = u32; + type DelegationManager = MultiAssetDelegation; + type ForceOrigin = frame_system::EnsureRoot; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime { @@ -1278,6 +1292,7 @@ construct_runtime!( MultiAssetDelegation: pallet_multi_asset_delegation = 45, Services: pallet_services = 51, Lst: pallet_tangle_lst = 52, + Rewards: pallet_rewards = 53, } ); @@ -1416,7 +1431,7 @@ pub type AssetId = u128; #[cfg(feature = "runtime-benchmarks")] pub type AssetId = u32; -impl tangle_primitives::NextAssetId for Runtime { +impl tangle_primitives::traits::NextAssetId for Runtime { fn next_asset_id() -> Option { pallet_assets::NextAssetId::::get() } @@ -1478,7 +1493,7 @@ impl pallet_multi_asset_delegation::Config for Runtime { type SlashedAmountRecipient = TreasuryAccount; type ForceOrigin = frame_system::EnsureRoot; type PalletId = PID; - type VaultId = AssetId; + type RewardsManager = Rewards; type MaxDelegatorBlueprints = MaxDelegatorBlueprints; type MaxOperatorBlueprints = MaxOperatorBlueprints; type MaxWithdrawRequests = MaxWithdrawRequests; From 67482329e9d3715adb1c904b258ed84e30dff0a0 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Tue, 7 Jan 2025 16:33:07 +0530 Subject: [PATCH 59/63] update tests --- pallets/rewards/src/mock_evm.rs | 11 +- pallets/rewards/src/tests.rs | 1 - .../MultiAssetDelegation.sol | 37 +-- precompiles/multi-asset-delegation/src/lib.rs | 4 +- .../multi-asset-delegation/src/tests.rs | 8 - precompiles/rewards/Rewards.sol | 59 +---- precompiles/rewards/src/lib.rs | 101 -------- precompiles/rewards/src/tests.rs | 220 ------------------ primitives/src/traits/data_provider.rs | 12 +- 9 files changed, 31 insertions(+), 422 deletions(-) diff --git a/pallets/rewards/src/mock_evm.rs b/pallets/rewards/src/mock_evm.rs index e528f8bf..93538421 100644 --- a/pallets/rewards/src/mock_evm.rs +++ b/pallets/rewards/src/mock_evm.rs @@ -18,12 +18,7 @@ use crate::mock::{ AccountId, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Timestamp, }; use fp_evm::FeeCalculator; -use frame_support::{ - parameter_types, - traits::{Currency, FindAuthor}, - weights::Weight, - PalletId, -}; +use frame_support::{parameter_types, traits::FindAuthor, weights::Weight, PalletId}; use pallet_ethereum::{EthereumBlockHashMapping, IntermediateStateRoot, PostLogContent, RawOrigin}; use pallet_evm::{ EnsureAddressNever, EnsureAddressRoot, HashedAddressMapping, OnChargeEVMTransaction, @@ -139,10 +134,6 @@ impl OnChargeEVMTransaction for FreeEVMExecution { fn pay_priority_fee(_tip: Self::LiquidityInfo) {} } -/// Type alias for negative imbalance during fees -type RuntimeNegativeImbalance = - ::AccountId>>::NegativeImbalance; - impl pallet_evm::Config for Runtime { type FeeCalculator = FixedGasPrice; type GasWeightMapping = pallet_evm::FixedGasWeightMapping; diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index d36dc1b6..a1389156 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -325,7 +325,6 @@ fn test_calculate_deposit_rewards_with_lock_multiplier() { #[test] fn test_calculate_deposit_rewards_with_expired_locks() { new_test_ext().execute_with(|| { - let account: AccountId32 = AccountId32::new([1u8; 32]); let vault_id = 1u32; let asset = Asset::Custom(vault_id as u128); let deposit = 100; diff --git a/precompiles/multi-asset-delegation/MultiAssetDelegation.sol b/precompiles/multi-asset-delegation/MultiAssetDelegation.sol index 7bdd2f9e..3029340c 100644 --- a/precompiles/multi-asset-delegation/MultiAssetDelegation.sol +++ b/precompiles/multi-asset-delegation/MultiAssetDelegation.sol @@ -14,57 +14,58 @@ MultiAssetDelegation constant MULTI_ASSET_DELEGATION_CONTRACT = MultiAssetDelega interface MultiAssetDelegation { /// @dev Join as an operator with a bond amount. /// @param bondAmount The amount to bond as an operator. - function joinOperators(uint256 bondAmount) external returns (uint8); + function joinOperators(uint256 bondAmount) external; /// @dev Schedule to leave as an operator. - function scheduleLeaveOperators() external returns (uint8); + function scheduleLeaveOperators() external; /// @dev Cancel the scheduled leave as an operator. - function cancelLeaveOperators() external returns (uint8); + function cancelLeaveOperators() external; /// @dev Execute the leave as an operator. - function executeLeaveOperators() external returns (uint8); + function executeLeaveOperators() external; /// @dev Bond more as an operator. /// @param additionalBond The additional amount to bond. - function operatorBondMore(uint256 additionalBond) external returns (uint8); + function operatorBondMore(uint256 additionalBond) external; /// @dev Schedule to unstake as an operator. /// @param unstakeAmount The amount to unstake. - function scheduleOperatorUnstake(uint256 unstakeAmount) external returns (uint8); + function scheduleOperatorUnstake(uint256 unstakeAmount) external; /// @dev Execute the unstake as an operator. - function executeOperatorUnstake() external returns (uint8); + function executeOperatorUnstake() external; /// @dev Cancel the scheduled unstake as an operator. - function cancelOperatorUnstake() external returns (uint8); + function cancelOperatorUnstake() external; /// @dev Go offline as an operator. - function goOffline() external returns (uint8); + function goOffline() external; /// @dev Go online as an operator. - function goOnline() external returns (uint8); + function goOnline() external; /// @dev Deposit an amount of an asset. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to deposit. - function deposit(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + /// @param lockMultiplier The lock multiplier. + function deposit(uint256 assetId, address tokenAddress, uint256 amount, uint8 lockMultiplier) external; /// @dev Schedule a withdrawal of an amount of an asset. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to withdraw. - function scheduleWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + function scheduleWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external; /// @dev Execute the scheduled withdrawal. - function executeWithdraw() external returns (uint8); + function executeWithdraw() external; /// @dev Cancel the scheduled withdrawal. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to cancel withdrawal. - function cancelWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + function cancelWithdraw(uint256 assetId, address tokenAddress, uint256 amount) external; /// @dev Delegate an amount of an asset to an operator. /// @param operator The address of the operator. @@ -72,22 +73,22 @@ interface MultiAssetDelegation { /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to delegate. /// @param blueprintSelection The blueprint selection. - function delegate(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount, uint64[] memory blueprintSelection) external returns (uint8); + function delegate(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount, uint64[] memory blueprintSelection) external; /// @dev Schedule an unstake of an amount of an asset as a delegator. /// @param operator The address of the operator. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to unstake. - function scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + function scheduleDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external; /// @dev Execute the scheduled unstake as a delegator. - function executeDelegatorUnstake() external returns (uint8); + function executeDelegatorUnstake() external; /// @dev Cancel the scheduled unstake as a delegator. /// @param operator The address of the operator. /// @param assetId The ID of the asset (0 for ERC20). /// @param tokenAddress The address of the ERC20 token (if assetId is 0). /// @param amount The amount to cancel unstake. - function cancelDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external returns (uint8); + function cancelDelegatorUnstake(bytes32 operator, uint256 assetId, address tokenAddress, uint256 amount) external; } \ No newline at end of file diff --git a/precompiles/multi-asset-delegation/src/lib.rs b/precompiles/multi-asset-delegation/src/lib.rs index d3944374..8add5db3 100644 --- a/precompiles/multi-asset-delegation/src/lib.rs +++ b/precompiles/multi-asset-delegation/src/lib.rs @@ -212,7 +212,7 @@ where Ok(()) } - #[precompile::public("deposit(uint256,address,uint256)")] + #[precompile::public("deposit(uint256,address,uint256,uint8)")] fn deposit( handle: &mut impl PrecompileHandle, asset_id: U256, @@ -325,7 +325,7 @@ where Ok(()) } - #[precompile::public("delegate(bytes32,uint256,address,uint256,uint64[],uint8)")] + #[precompile::public("delegate(bytes32,uint256,address,uint256,uint64[])")] fn delegate( handle: &mut impl PrecompileHandle, operator: H256, diff --git a/precompiles/multi-asset-delegation/src/tests.rs b/precompiles/multi-asset-delegation/src/tests.rs index d891be11..e3aaf323 100644 --- a/precompiles/multi-asset-delegation/src/tests.rs +++ b/precompiles/multi-asset-delegation/src/tests.rs @@ -303,10 +303,6 @@ fn test_execute_withdraw() { .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) .execute_returns(()); - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(metadata.withdraw_requests.is_empty()); - assert_eq!(Assets::balance(1, delegator_account), 500 - 100); // deposited 200, withdrew 100 }); } @@ -369,10 +365,6 @@ fn test_execute_withdraw_before_due() { ) .execute_returns(()); - let metadata = MultiAssetDelegation::delegators(delegator_account).unwrap(); - assert_eq!(metadata.deposits.get(&Asset::Custom(1)), None); - assert!(!metadata.withdraw_requests.is_empty()); - PrecompilesValue::get() .prepare_test(TestAccount::Alex, H160::from_low_u64_be(1), PCall::execute_withdraw {}) .execute_returns(()); // should not fail diff --git a/precompiles/rewards/Rewards.sol b/precompiles/rewards/Rewards.sol index 624865a3..4e8c09c9 100644 --- a/precompiles/rewards/Rewards.sol +++ b/precompiles/rewards/Rewards.sol @@ -12,61 +12,8 @@ Rewards constant REWARDS_CONTRACT = Rewards(REWARDS); /// @title The interface through which solidity contracts will interact with the Rewards pallet /// @custom:address 0x0000000000000000000000000000000000000823 interface Rewards { - /// @notice Updates the rewards for a specific asset - /// @dev Only callable by root/admin + /// @notice Claims rewards for a specific asset /// @param assetId The ID of the asset - /// @param rewards The new rewards amount - /// @return uint8 Returns 0 on success - function updateAssetRewards(uint256 assetId, uint256 rewards) external returns (uint8); - - /// @notice Updates the APY for a specific asset - /// @dev Only callable by root/admin. APY is capped at 10% - /// @param assetId The ID of the asset - /// @param apy The new APY value (in basis points, e.g. 1000 = 10%) - /// @return uint8 Returns 0 on success - function updateAssetApy(uint256 assetId, uint32 apy) external returns (uint8); - - /// @notice Calculates the reward score for given parameters - /// @param stake The stake amount - /// @param rewards The rewards amount - /// @param apy The APY value - /// @return uint256 The calculated reward score - function calculateRewardScore(uint256 stake, uint256 rewards, uint32 apy) external view returns (uint256); - - /// @notice Calculates the total reward score for an asset - /// @param assetId The ID of the asset - /// @return uint256 The total reward score - function calculateTotalRewardScore(uint256 assetId) external view returns (uint256); - - /// @notice Gets the current rewards for an asset - /// @param assetId The ID of the asset - /// @return uint256 The current rewards amount - function assetRewards(uint256 assetId) external view returns (uint256); - - /// @notice Gets the current APY for an asset - /// @param assetId The ID of the asset - /// @return uint32 The current APY value - function assetApy(uint256 assetId) external view returns (uint32); - - /// @notice Sets incentive APY and cap for a vault - /// @dev Only callable by force origin. APY is capped at 10% - /// @param vaultId The ID of the vault - /// @param apy The APY value (in basis points, max 1000 = 10%) - /// @param cap The cap amount for full APY distribution - /// @return uint8 Returns 0 on success - function setIncentiveApyAndCap(uint256 vaultId, uint32 apy, uint256 cap) external returns (uint8); - - /// @notice Whitelists a blueprint for rewards - /// @dev Only callable by force origin - /// @param blueprintId The ID of the blueprint to whitelist - /// @return uint8 Returns 0 on success - function whitelistBlueprintForRewards(uint64 blueprintId) external returns (uint8); - - /// @notice Manages assets in a vault - /// @dev Only callable by authorized accounts - /// @param vaultId The ID of the vault - /// @param assetId The ID of the asset - /// @param action 0 for Add, 1 for Remove - /// @return uint8 Returns 0 on success - function manageAssetInVault(uint256 vaultId, uint256 assetId, uint8 action) external returns (uint8); + /// @param tokenAddress The EVM address of the token (zero for native assets) + function claimRewards(uint256 assetId, address tokenAddress) external; } \ No newline at end of file diff --git a/precompiles/rewards/src/lib.rs b/precompiles/rewards/src/lib.rs index 6594b60e..857c6778 100644 --- a/precompiles/rewards/src/lib.rs +++ b/precompiles/rewards/src/lib.rs @@ -71,105 +71,4 @@ where Ok(()) } - - #[precompile::public("forceClaimRewards(address,uint256,address)")] - fn force_claim_rewards( - handle: &mut impl PrecompileHandle, - account: Address, - asset_id: U256, - token_address: Address, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - let target = Runtime::AddressMapping::into_account_id(account.0); - - let (asset, _) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), U256::zero()) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), U256::zero()), - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_rewards::Call::::force_claim_rewards { account: target, asset }, - )?; - - Ok(()) - } - - #[precompile::public("updateVaultRewardConfig(uint256,uint8,uint256,uint256,uint32)")] - fn update_vault_reward_config( - handle: &mut impl PrecompileHandle, - vault_id: U256, - apy: u8, - deposit_cap: U256, - incentive_cap: U256, - boost_multiplier: u32, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - let config = pallet_rewards::RewardConfigForAssetVault { - apy: sp_runtime::Percent::from_percent(apy.min(100)), - deposit_cap: deposit_cap.try_into().map_err(|_| RevertReason::value_is_too_large("deposit_cap"))?, - incentive_cap: incentive_cap.try_into().map_err(|_| RevertReason::value_is_too_large("incentive_cap"))?, - boost_multiplier: Some(boost_multiplier.min(500)), // Cap at 5x - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_rewards::Call::::udpate_vault_reward_config { - vault_id: vault_id.try_into().map_err(|_| RevertReason::value_is_too_large("vault_id"))?, - new_config: config, - }, - )?; - - Ok(()) - } - - #[precompile::public("manageAssetRewardVault(uint256,uint256,address,bool)")] - fn manage_asset_reward_vault( - handle: &mut impl PrecompileHandle, - vault_id: U256, - asset_id: U256, - token_address: Address, - add: bool, - ) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - - let caller = handle.context().caller; - let who = Runtime::AddressMapping::into_account_id(caller); - - let (asset, _) = match (asset_id.as_u128(), token_address.0 .0) { - (0, erc20_token) if erc20_token != [0; 20] => { - (Asset::Erc20(erc20_token.into()), U256::zero()) - }, - (other_asset_id, _) => (Asset::Custom(other_asset_id.into()), U256::zero()), - }; - - let action = if add { - pallet_rewards::AssetAction::Add - } else { - pallet_rewards::AssetAction::Remove - }; - - RuntimeHelper::::try_dispatch( - handle, - Some(who).into(), - pallet_rewards::Call::::manage_asset_reward_vault { - vault_id: vault_id.try_into().map_err(|_| RevertReason::value_is_too_large("vault_id"))?, - asset_id: asset, - action, - }, - )?; - - Ok(()) - } } diff --git a/precompiles/rewards/src/tests.rs b/precompiles/rewards/src/tests.rs index bfd81cd2..78acd785 100644 --- a/precompiles/rewards/src/tests.rs +++ b/precompiles/rewards/src/tests.rs @@ -75,223 +75,3 @@ fn test_claim_rewards() { assert!(claimed.is_some()); }); } - -#[test] -fn test_force_claim_rewards() { - ExtBuilder::default().build().execute_with(|| { - let vault_id = 1u32; - let asset_id = Asset::Custom(1); - let alice: AccountId = TestAccount::Alice.into(); - let bob: AccountId = TestAccount::Bob.into(); - let deposit_amount = 1_000u128; - - // Setup vault and add asset - assert_ok!(Rewards::manage_asset_reward_vault( - RuntimeOrigin::root(), - vault_id, - asset_id, - AssetAction::Add, - )); - - // Setup reward config - let config = RewardConfigForAssetVault { - apy: Percent::from_percent(10), - deposit_cap: 1_000_000, - incentive_cap: 100_000, - boost_multiplier: Some(200), - }; - assert_ok!(Rewards::udpate_vault_reward_config( - RuntimeOrigin::root(), - vault_id, - config, - )); - - // Setup mock deposit for Bob - MOCK_DELEGATION_INFO.with(|m| { - m.borrow_mut().deposits.insert( - (bob.clone(), asset_id), - UserDepositWithLocks { unlocked_amount: deposit_amount, amount_with_locks: None }, - ); - }); - - // Alice force claims rewards for Bob - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::force_claim_rewards { - account: Address(TestAccount::Bob.into()), - asset_id: U256::from(1), - token_address: Address::zero(), - }, - ) - .execute_returns(()); - - // Check that rewards were claimed for Bob - let claimed = UserClaimedReward::::get(bob, vault_id); - assert!(claimed.is_some()); - }); -} - -#[test] -fn test_update_vault_reward_config() { - ExtBuilder::default().build().execute_with(|| { - let vault_id = 1u32; - - // Update vault config - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::update_vault_reward_config { - vault_id: U256::from(vault_id), - apy: 10, - deposit_cap: U256::from(1_000_000u128), - incentive_cap: U256::from(100_000u128), - boost_multiplier: 200, - }, - ) - .execute_returns(()); - - // Verify config was updated - let config = RewardConfigStorage::::get(vault_id); - assert!(config.is_some()); - let config = config.unwrap(); - assert_eq!(config.apy, Percent::from_percent(10)); - assert_eq!(config.deposit_cap, 1_000_000u128); - assert_eq!(config.incentive_cap, 100_000u128); - assert_eq!(config.boost_multiplier, Some(200)); - }); -} - -#[test] -fn test_manage_asset_reward_vault() { - ExtBuilder::default().build().execute_with(|| { - let vault_id = 1u32; - let asset_id = 1u128; - - // Add asset to vault - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::manage_asset_reward_vault { - vault_id: U256::from(vault_id), - asset_id: U256::from(asset_id), - token_address: Address::zero(), - add: true, - }, - ) - .execute_returns(()); - - // Verify asset was added - let vault = AssetLookupRewardVaults::::get(Asset::Custom(asset_id)); - assert_eq!(vault, Some(vault_id)); - - // Remove asset from vault - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::manage_asset_reward_vault { - vault_id: U256::from(vault_id), - asset_id: U256::from(asset_id), - token_address: Address::zero(), - add: false, - }, - ) - .execute_returns(()); - - // Verify asset was removed - let vault = AssetLookupRewardVaults::::get(Asset::Custom(asset_id)); - assert_eq!(vault, None); - }); -} - -#[test] -fn test_claim_rewards_no_vault() { - ExtBuilder::default().build().execute_with(|| { - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::claim_rewards { - asset_id: U256::from(1), - token_address: Address::zero(), - }, - ) - .execute_reverts(|output| output == b"AssetNotInVault"); - }); -} - -#[test] -fn test_claim_rewards_no_deposit() { - ExtBuilder::default().build().execute_with(|| { - let vault_id = 1u32; - let asset_id = Asset::Custom(1); - - // Setup vault and add asset - assert_ok!(Rewards::manage_asset_reward_vault( - RuntimeOrigin::root(), - vault_id, - asset_id, - AssetAction::Add, - )); - - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::claim_rewards { - asset_id: U256::from(1), - token_address: Address::zero(), - }, - ) - .execute_reverts(|output| output == b"NoRewardsAvailable"); - }); -} - -#[test] -fn test_update_vault_reward_config_invalid_values() { - ExtBuilder::default().build().execute_with(|| { - // Test APY > 100% - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::update_vault_reward_config { - vault_id: U256::from(1), - apy: 101, - deposit_cap: U256::from(1_000_000u128), - incentive_cap: U256::from(100_000u128), - boost_multiplier: 200, - }, - ) - .execute_returns(()); - - // Verify APY was capped at 100% - let config = RewardConfigStorage::::get(1); - assert!(config.is_some()); - assert_eq!(config.unwrap().apy, Percent::from_percent(100)); - - // Test boost multiplier > 500% - PrecompilesValue::get() - .prepare_test( - TestAccount::Alice, - H160::from_low_u64_be(1), - PrecompileCall::update_vault_reward_config { - vault_id: U256::from(1), - apy: 50, - deposit_cap: U256::from(1_000_000u128), - incentive_cap: U256::from(100_000u128), - boost_multiplier: 600, - }, - ) - .execute_returns(()); - - // Verify boost multiplier was capped at 500% - let config = RewardConfigStorage::::get(1); - assert!(config.is_some()); - assert_eq!(config.unwrap().boost_multiplier, Some(500)); - }); -} diff --git a/primitives/src/traits/data_provider.rs b/primitives/src/traits/data_provider.rs index ec54535e..236ccd08 100644 --- a/primitives/src/traits/data_provider.rs +++ b/primitives/src/traits/data_provider.rs @@ -60,27 +60,27 @@ macro_rules! create_median_value_data_provider { fn get(key: &$key) -> Option<$value> { let mut values = vec![]; $( - if let Some(v) = <$provider as $crate::traits::DataProvide<$key, $value>>::get(&key) { + if let Some(v) = <$provider as $crate::traits::DataProvider<$key, $value>>::get(&key) { values.push(v); } )* - $crate::data_provider::median(values) + $crate::traits::data_provider::median(values) } } - impl $crate::traits::DataProvideExtended<$key, $timestamped_value> for $name { + impl $crate::traits::DataProviderExtended<$key, $timestamped_value> for $name { fn get_no_op(key: &$key) -> Option<$timestamped_value> { let mut values = vec![]; $( - if let Some(v) = <$provider as $crate::traits::DataProvideExtended<$key, $timestamped_value>>::get_no_op(&key) { + if let Some(v) = <$provider as $crate::traits::DataProviderExtended<$key, $timestamped_value>>::get_no_op(&key) { values.push(v); } )* - $crate::data_provider::median(values) + $crate::traits::data_provider::median(values) } fn get_all_values() -> Vec<($key, Option<$timestamped_value>)> { let mut keys = sp_std::collections::btree_set::BTreeSet::new(); $( - <$provider as $crate::traits::DataProvideExtended<$key, $timestamped_value>>::get_all_values() + <$provider as $crate::traits::DataProviderExtended<$key, $timestamped_value>>::get_all_values() .into_iter() .for_each(|(k, _)| { keys.insert(k); }); )* From f346f643bb94cc7ec56fcd3188e52bfe1737ae65 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 8 Jan 2025 01:34:00 +0530 Subject: [PATCH 60/63] cleanup clippy --- node/tests/evm_restaking.rs | 4 ++-- pallets/rewards/fuzzer/call.rs | 4 ++-- pallets/rewards/src/lib.rs | 2 +- pallets/rewards/src/tests.rs | 12 ++++++------ precompiles/rewards/src/tests.rs | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/node/tests/evm_restaking.rs b/node/tests/evm_restaking.rs index 94e9c364..3619e949 100644 --- a/node/tests/evm_restaking.rs +++ b/node/tests/evm_restaking.rs @@ -225,7 +225,7 @@ fn operator_join_delegator_delegate_erc20() { // Deposit and delegate let deposit_result = precompile - .deposit(U256::ZERO, *usdc.address(), delegate_amount) + .deposit(U256::ZERO, *usdc.address(), delegate_amount, 0) .from(bob.address()) .send() .await? @@ -314,7 +314,7 @@ fn operator_join_delegator_delegate_asset_id() { // Deposit and delegate using asset ID let deposit_result = precompile - .deposit(U256::from(t.usdc_asset_id), Address::ZERO, U256::from(delegate_amount)) + .deposit(U256::from(t.usdc_asset_id), Address::ZERO, U256::from(delegate_amount), 0) .from(bob.address()) .send() .await? diff --git a/pallets/rewards/fuzzer/call.rs b/pallets/rewards/fuzzer/call.rs index 925ec9da..121d1b1c 100644 --- a/pallets/rewards/fuzzer/call.rs +++ b/pallets/rewards/fuzzer/call.rs @@ -131,7 +131,7 @@ impl RewardsCallGenerator { incentive_cap, boost_multiplier: boost_multiplier.map(|m| m.min(500)), // Cap at 5x }; - RewardsCall::udpate_vault_reward_config { vault_id, new_config: config } + RewardsCall::update_vault_reward_config { vault_id, new_config: config } } } @@ -160,7 +160,7 @@ impl RewardsCallExecutor { incentive_cap, boost_multiplier: boost_multiplier.map(|m| m.min(500)), // Cap at 5x }; - Rewards::udpate_vault_reward_config(RuntimeOrigin::root(), vault_id, config) + Rewards::update_vault_reward_config(RuntimeOrigin::root(), vault_id, config) } } diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs index 4a69815f..46cf5236 100644 --- a/pallets/rewards/src/lib.rs +++ b/pallets/rewards/src/lib.rs @@ -319,7 +319,7 @@ pub mod pallet { /// * `BadOrigin` - If caller is not authorized through `ForceOrigin` #[pallet::call_index(3)] #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] - pub fn udpate_vault_reward_config( + pub fn update_vault_reward_config( origin: OriginFor, vault_id: T::VaultId, new_config: RewardConfigForAssetVault>, diff --git a/pallets/rewards/src/tests.rs b/pallets/rewards/src/tests.rs index a1389156..34c62f38 100644 --- a/pallets/rewards/src/tests.rs +++ b/pallets/rewards/src/tests.rs @@ -41,7 +41,7 @@ fn test_claim_rewards() { let incentive_cap = 1000; // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } @@ -104,7 +104,7 @@ fn test_claim_rewards_with_invalid_asset() { ); // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { @@ -139,7 +139,7 @@ fn test_claim_rewards_with_no_deposit() { let asset = Asset::Custom(vault_id as u128); // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { @@ -175,7 +175,7 @@ fn test_claim_rewards_multiple_times() { let deposit = 100; // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { @@ -248,7 +248,7 @@ fn test_calculate_deposit_rewards_with_lock_multiplier() { let incentive_cap = 1000; // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } @@ -334,7 +334,7 @@ fn test_calculate_deposit_rewards_with_expired_locks() { let incentive_cap = 1000; // Configure the reward vault - assert_ok!(RewardsPallet::::udpate_vault_reward_config( + assert_ok!(RewardsPallet::::update_vault_reward_config( RuntimeOrigin::root(), vault_id, RewardConfigForAssetVault { apy, deposit_cap, incentive_cap, boost_multiplier } diff --git a/precompiles/rewards/src/tests.rs b/precompiles/rewards/src/tests.rs index 78acd785..79852f32 100644 --- a/precompiles/rewards/src/tests.rs +++ b/precompiles/rewards/src/tests.rs @@ -45,7 +45,7 @@ fn test_claim_rewards() { incentive_cap: 100_000, boost_multiplier: Some(200), }; - assert_ok!(Rewards::udpate_vault_reward_config( + assert_ok!(Rewards::update_vault_reward_config( RuntimeOrigin::root(), vault_id, config, From 10c2b325acf3ed3654bddf643abd8894dd96fd76 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:38:49 +0530 Subject: [PATCH 61/63] update types --- types/src/interfaces/augment-api-errors.ts | 62 ++ types/src/interfaces/augment-api-events.ts | 37 +- types/src/interfaces/augment-api-query.ts | 45 +- types/src/interfaces/augment-api-tx.ts | 106 ++- types/src/interfaces/lookup.ts | 752 ++++++++++---------- types/src/interfaces/registry.ts | 13 +- types/src/interfaces/types-lookup.ts | 775 +++++++++++---------- types/src/metadata.json | 2 +- 8 files changed, 994 insertions(+), 798 deletions(-) diff --git a/types/src/interfaces/augment-api-errors.ts b/types/src/interfaces/augment-api-errors.ts index c31c8d44..5c611abb 100644 --- a/types/src/interfaces/augment-api-errors.ts +++ b/types/src/interfaces/augment-api-errors.ts @@ -1081,6 +1081,10 @@ declare module '@polkadot/api-base/types/errors' { * Cap exceeds total supply of asset **/ CapExceedsTotalSupply: AugmentedError; + /** + * Above deposit caps setup + **/ + DepositExceedsCapForAsset: AugmentedError; /** * Deposit amount overflow **/ @@ -1113,6 +1117,10 @@ declare module '@polkadot/api-base/types/errors' { * Leaving round not reached **/ LeavingRoundNotReached: AugmentedError; + /** + * Cannot unstake with locks + **/ + LockViolation: AugmentedError; /** * Maximum number of blueprints exceeded **/ @@ -1514,6 +1522,60 @@ declare module '@polkadot/api-base/types/errors' { **/ [key: string]: AugmentedError; }; + rewards: { + /** + * Arithmetic operation caused an overflow + **/ + ArithmeticError: AugmentedError; + /** + * Asset already exists in a reward vault + **/ + AssetAlreadyInVault: AugmentedError; + /** + * Asset is already whitelisted + **/ + AssetAlreadyWhitelisted: AugmentedError; + /** + * Asset not found in reward vault + **/ + AssetNotInVault: AugmentedError; + /** + * Asset is not whitelisted for rewards + **/ + AssetNotWhitelisted: AugmentedError; + /** + * Error returned when trying to remove a blueprint ID that doesn't exist. + **/ + BlueprintIdNotFound: AugmentedError; + /** + * Error returned when trying to add a blueprint ID that already exists. + **/ + DuplicateBlueprintId: AugmentedError; + /** + * Insufficient rewards balance in pallet account + **/ + InsufficientRewardsBalance: AugmentedError; + /** + * Invalid APY value + **/ + InvalidAPY: AugmentedError; + /** + * No rewards available to claim + **/ + NoRewardsAvailable: AugmentedError; + /** + * Error returned when the reward configuration for the vault is not found. + **/ + RewardConfigNotFound: AugmentedError; + /** + * The reward vault does not exist + **/ + VaultNotFound: AugmentedError; + /** + * Generic error + **/ + [key: string]: AugmentedError; + }; scheduler: { /** * Failed to schedule a call diff --git a/types/src/interfaces/augment-api-events.ts b/types/src/interfaces/augment-api-events.ts index e3155e87..3f0590e2 100644 --- a/types/src/interfaces/augment-api-events.ts +++ b/types/src/interfaces/augment-api-events.ts @@ -9,7 +9,7 @@ import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types'; import type { Bytes, Null, Option, Result, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec'; import type { ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, H160, H256, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, PalletAirdropClaimsUtilsMultiAddress, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletDemocracyVoteThreshold, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhasePhase, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsPoolState, PalletStakingForcing, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstPoolsPoolState, SpConsensusGrandpaAppPublic, SpNposElectionsElectionScore, SpRuntimeDispatchError, SpStakingExposure, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; +import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportTokensMiscBalanceStatus, PalletAirdropClaimsUtilsMultiAddress, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletDemocracyVoteThreshold, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhasePhase, PalletImOnlineSr25519AppSr25519Public, PalletMultisigTimepoint, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsPoolState, PalletRewardsAssetAction, PalletStakingForcing, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstPoolsPoolState, SpConsensusGrandpaAppPublic, SpNposElectionsElectionScore, SpRuntimeDispatchError, SpStakingExposure, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; export type __AugmentedEvent = AugmentedEvent; @@ -781,14 +781,6 @@ declare module '@polkadot/api-base/types/events' { [key: string]: AugmentedEvent; }; multiAssetDelegation: { - /** - * Asset has been updated to reward vault - **/ - AssetUpdatedInVault: AugmentedEvent; - /** - * Event emitted when a blueprint is whitelisted for rewards - **/ - BlueprintWhitelisted: AugmentedEvent; /** * A delegator unstake request has been cancelled. **/ @@ -821,10 +813,6 @@ declare module '@polkadot/api-base/types/events' { * An withdraw has been executed. **/ Executedwithdraw: AugmentedEvent; - /** - * Event emitted when an incentive APY and cap are set for a reward vault - **/ - IncentiveAPYAndCapSet: AugmentedEvent; /** * An operator has cancelled their stake decrease request. **/ @@ -1057,6 +1045,29 @@ declare module '@polkadot/api-base/types/events' { **/ [key: string]: AugmentedEvent; }; + rewards: { + /** + * Asset has been updated to reward vault + **/ + AssetUpdatedInVault: AugmentedEvent; + /** + * Event emitted when a blueprint is whitelisted for rewards + **/ + BlueprintWhitelisted: AugmentedEvent; + /** + * Event emitted when an incentive APY and cap are set for a reward vault + **/ + IncentiveAPYAndCapSet: AugmentedEvent; + /** + * Rewards have been claimed by an account + **/ + RewardsClaimed: AugmentedEvent; + VaultRewardConfigUpdated: AugmentedEvent; + /** + * Generic event + **/ + [key: string]: AugmentedEvent; + }; scheduler: { /** * The call for the provided hash was not found so the task has been aborted. diff --git a/types/src/interfaces/augment-api-query.ts b/types/src/interfaces/augment-api-query.ts index 2a062ac4..ed2bff8d 100644 --- a/types/src/interfaces/augment-api-query.ts +++ b/types/src/interfaces/augment-api-query.ts @@ -10,7 +10,7 @@ import type { Data } from '@polkadot/types'; import type { BTreeSet, Bytes, Null, Option, U256, U8aFixed, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec'; import type { AnyNumber, ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, Call, H160, H256, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumBlock, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportDispatchPerDispatchClassWeight, FrameSupportPreimagesBounded, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCodeUpgradeAuthorization, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReserveData, PalletBountiesBounty, PalletChildBountiesChildBounty, PalletCollectiveVotes, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEvmCodeMetadata, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityAuthorityProperties, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultisigMultisig, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsClaimPermission, PalletNominationPoolsPoolMember, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesUnappliedSlash, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstClaimPermission, PalletTangleLstPoolsPoolMember, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletVestingReleases, PalletVestingVestingInfo, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusGrandpaAppPublic, SpCoreCryptoKeyTypeId, SpNposElectionsElectionScore, SpRuntimeDigest, SpStakingExposure, SpStakingExposurePage, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, TanglePrimitivesServicesAsset, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TangleTestnetRuntimeOpaqueSessionKeys } from '@polkadot/types/lookup'; +import type { EthereumBlock, EthereumReceiptReceiptV3, EthereumTransactionTransactionV2, FpRpcTransactionStatus, FrameSupportDispatchPerDispatchClassWeight, FrameSupportPreimagesBounded, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCodeUpgradeAuthorization, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReserveData, PalletBountiesBounty, PalletChildBountiesChildBounty, PalletCollectiveVotes, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEvmCodeMetadata, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityAuthorityProperties, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineSr25519AppSr25519Public, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultisigMultisig, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsClaimPermission, PalletNominationPoolsPoolMember, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletRewardsRewardConfigForAssetVault, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesUnappliedSlash, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstClaimPermission, PalletTangleLstPoolsPoolMember, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletVestingReleases, PalletVestingVestingInfo, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusGrandpaAppPublic, SpCoreCryptoKeyTypeId, SpNposElectionsElectionScore, SpRuntimeDigest, SpStakingExposure, SpStakingExposurePage, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, TanglePrimitivesServicesAsset, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TangleTestnetRuntimeOpaqueSessionKeys } from '@polkadot/types/lookup'; import type { Observable } from '@polkadot/types/types'; export type __AugmentedQuery = AugmentedQuery unknown>; @@ -874,10 +874,6 @@ declare module '@polkadot/api-base/types/storage' { [key: string]: QueryableStorageEntry; }; multiAssetDelegation: { - /** - * Storage for the reward vaults - **/ - assetLookupRewardVaults: AugmentedQuery Observable>, [TanglePrimitivesServicesAsset]> & QueryableStorageEntry; /** * Snapshot of collator delegation stake at the start of the round. **/ @@ -894,15 +890,6 @@ declare module '@polkadot/api-base/types/storage' { * Storage for operator information. **/ operators: AugmentedQuery Observable>, [AccountId32]> & QueryableStorageEntry; - /** - * Storage for the reward configuration, which includes APY, cap for assets, and whitelisted - * blueprints. - **/ - rewardConfigStorage: AugmentedQuery Observable>, []> & QueryableStorageEntry; - /** - * Storage for the reward vaults - **/ - rewardVaults: AugmentedQuery Observable>>, [u128]> & QueryableStorageEntry; /** * Generic query **/ @@ -1086,6 +1073,36 @@ declare module '@polkadot/api-base/types/storage' { **/ [key: string]: QueryableStorageEntry; }; + rewards: { + /** + * Storage for the reward vaults + **/ + assetLookupRewardVaults: AugmentedQuery Observable>, [TanglePrimitivesServicesAsset]> & QueryableStorageEntry; + /** + * Storage for the reward configuration, which includes APY, cap for assets + **/ + rewardConfigStorage: AugmentedQuery Observable>, [u32]> & QueryableStorageEntry; + /** + * Storage for the reward vaults + **/ + rewardVaults: AugmentedQuery Observable>>, [u32]> & QueryableStorageEntry; + /** + * Stores the total score for each asset + **/ + totalRewardVaultScore: AugmentedQuery Observable, [u32]> & QueryableStorageEntry; + /** + * Stores the service reward for a given user + **/ + userClaimedReward: AugmentedQuery Observable>>, [AccountId32, u32]> & QueryableStorageEntry; + /** + * Stores the service reward for a given user + **/ + userServiceReward: AugmentedQuery Observable, [AccountId32, TanglePrimitivesServicesAsset]> & QueryableStorageEntry; + /** + * Generic query + **/ + [key: string]: QueryableStorageEntry; + }; scheduler: { /** * Items to be executed, indexed by the block number that they should be executed on. diff --git a/types/src/interfaces/augment-api-tx.ts b/types/src/interfaces/augment-api-tx.ts index 1970bbdc..3c76b140 100644 --- a/types/src/interfaces/augment-api-tx.ts +++ b/types/src/interfaces/augment-api-tx.ts @@ -10,7 +10,7 @@ import type { Data } from '@polkadot/types'; import type { Bytes, Compact, Null, Option, U256, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types-codec'; import type { AnyNumber, IMethod, ITuple } from '@polkadot/types-codec/types'; import type { AccountId32, Call, H160, H256, MultiAddress, Perbill, Percent, Permill } from '@polkadot/types/interfaces/runtime'; -import type { EthereumTransactionTransactionV2, FrameSupportPreimagesBounded, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletBalancesAdjustmentDirection, PalletDemocracyConviction, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationRewardsAssetAction, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsPoolState, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingRewardDestination, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletTangleLstBondExtra, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstPoolsPoolState, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeMultiSignature, SpSessionMembershipProof, SpWeightsWeightV2Weight, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesServiceBlueprint, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; +import type { EthereumTransactionTransactionV2, FrameSupportPreimagesBounded, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletBalancesAdjustmentDirection, PalletDemocracyConviction, PalletDemocracyMetadataOwner, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsPoolState, PalletRewardsAssetAction, PalletRewardsRewardConfigForAssetVault, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingRewardDestination, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletTangleLstBondExtra, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstPoolsPoolState, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeMultiSignature, SpSessionMembershipProof, SpWeightsWeightV2Weight, TanglePrimitivesRewardsLockMultiplier, TanglePrimitivesServicesAsset, TanglePrimitivesServicesField, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesServiceBlueprint, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType } from '@polkadot/types/lookup'; export type __AugmentedSubmittable = AugmentedSubmittable<() => unknown>; export type __SubmittableExtrinsic = SubmittableExtrinsic; @@ -2644,7 +2644,7 @@ declare module '@polkadot/api-base/types/submittable' { * * [`Error::DepositOverflow`] - Deposit would overflow tracking * * [`Error::InvalidAsset`] - Asset is not supported **/ - deposit: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array, evmAddress: Option | null | Uint8Array | H160 | string) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128, Option]>; + deposit: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array, evmAddress: Option | null | Uint8Array | H160 | string, lockMultiplier: Option | null | Uint8Array | TanglePrimitivesRewardsLockMultiplier | 'OneMonth' | 'TwoMonths' | 'ThreeMonths' | 'SixMonths' | number) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128, Option, Option]>; /** * Executes a scheduled request to reduce a delegator's stake. * @@ -2769,26 +2769,6 @@ declare module '@polkadot/api-base/types/submittable' { * * [`Error::StakeOverflow`] - Bond amount would overflow stake tracking **/ joinOperators: AugmentedSubmittable<(bondAmount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u128]>; - /** - * Manage asset id to vault rewards. - * - * # Permissions - * - * * Must be signed by an authorized account - * - * # Arguments - * - * * `origin` - Origin of the call - * * `vault_id` - ID of the vault - * * `asset_id` - ID of the asset - * * `action` - Action to perform (Add/Remove) - * - * # Errors - * - * * [`Error::AssetAlreadyInVault`] - Asset already exists in vault - * * [`Error::AssetNotInVault`] - Asset does not exist in vault - **/ - manageAssetInVault: AugmentedSubmittable<(vaultId: u128 | AnyNumber | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, action: PalletMultiAssetDelegationRewardsAssetAction | 'Add' | 'Remove' | number | Uint8Array) => SubmittableExtrinsic, [u128, TanglePrimitivesServicesAsset, PalletMultiAssetDelegationRewardsAssetAction]>; /** * Allows an operator to increase their stake. * @@ -2902,39 +2882,6 @@ declare module '@polkadot/api-base/types/submittable' { * * [`Error::PendingWithdrawRequestExists`] - Pending withdraw request exists **/ scheduleWithdraw: AugmentedSubmittable<(assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset, u128]>; - /** - * Sets the APY and cap for a specific asset. - * - * # Permissions - * - * * Must be called by the force origin - * - * # Arguments - * - * * `origin` - Origin of the call - * * `vault_id` - ID of the vault - * * `apy` - Annual percentage yield (max 10%) - * * `cap` - Required deposit amount for full APY - * - * # Errors - * - * * [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum - * * [`Error::CapCannotBeZero`] - Cap amount cannot be zero - **/ - setIncentiveApyAndCap: AugmentedSubmittable<(vaultId: u128 | AnyNumber | Uint8Array, apy: Percent | AnyNumber | Uint8Array, cap: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u128, Percent, u128]>; - /** - * Whitelists a blueprint for rewards. - * - * # Permissions - * - * * Must be called by the force origin - * - * # Arguments - * - * * `origin` - Origin of the call - * * `blueprint_id` - ID of blueprint to whitelist - **/ - whitelistBlueprintForRewards: AugmentedSubmittable<(blueprintId: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u64]>; /** * Generic tx **/ @@ -3576,6 +3523,55 @@ declare module '@polkadot/api-base/types/submittable' { **/ [key: string]: SubmittableExtrinsicFunction; }; + rewards: { + /** + * Claim rewards for a specific asset and reward type + **/ + claimRewards: AugmentedSubmittable<(asset: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array) => SubmittableExtrinsic, [TanglePrimitivesServicesAsset]>; + /** + * Manage asset id to vault rewards. + * + * # Permissions + * + * * Must be signed by an authorized account + * + * # Arguments + * + * * `origin` - Origin of the call + * * `vault_id` - ID of the vault + * * `asset_id` - ID of the asset + * * `action` - Action to perform (Add/Remove) + * + * # Errors + * + * * [`Error::AssetAlreadyInVault`] - Asset already exists in vault + * * [`Error::AssetNotInVault`] - Asset does not exist in vault + **/ + manageAssetRewardVault: AugmentedSubmittable<(vaultId: u32 | AnyNumber | Uint8Array, assetId: TanglePrimitivesServicesAsset | { Custom: any } | { Erc20: any } | string | Uint8Array, action: PalletRewardsAssetAction | 'Add' | 'Remove' | number | Uint8Array) => SubmittableExtrinsic, [u32, TanglePrimitivesServicesAsset, PalletRewardsAssetAction]>; + /** + * Updates the reward configuration for a specific vault. + * + * # Arguments + * * `origin` - Origin of the call, must pass `ForceOrigin` check + * * `vault_id` - The ID of the vault to update + * * `new_config` - The new reward configuration containing: + * * `apy` - Annual Percentage Yield for the vault + * * `deposit_cap` - Maximum amount that can be deposited + * * `incentive_cap` - Maximum amount of incentives that can be distributed + * * `boost_multiplier` - Optional multiplier to boost rewards + * + * # Events + * * `VaultRewardConfigUpdated` - Emitted when vault reward config is updated + * + * # Errors + * * `BadOrigin` - If caller is not authorized through `ForceOrigin` + **/ + updateVaultRewardConfig: AugmentedSubmittable<(vaultId: u32 | AnyNumber | Uint8Array, newConfig: PalletRewardsRewardConfigForAssetVault | { apy?: any; incentiveCap?: any; depositCap?: any; boostMultiplier?: any } | string | Uint8Array) => SubmittableExtrinsic, [u32, PalletRewardsRewardConfigForAssetVault]>; + /** + * Generic tx + **/ + [key: string]: SubmittableExtrinsicFunction; + }; scheduler: { /** * Cancel an anonymously scheduled task. diff --git a/types/src/interfaces/lookup.ts b/types/src/interfaces/lookup.ts index 11bb3ff2..0c63a794 100644 --- a/types/src/interfaces/lookup.ts +++ b/types/src/interfaces/lookup.ts @@ -1580,20 +1580,6 @@ export default { CancelledDelegatorBondLess: { who: 'AccountId32', }, - IncentiveAPYAndCapSet: { - vaultId: 'u128', - apy: 'Percent', - cap: 'u128', - }, - BlueprintWhitelisted: { - blueprintId: 'u64', - }, - AssetUpdatedInVault: { - who: 'AccountId32', - vaultId: 'u128', - assetId: 'TanglePrimitivesServicesAsset', - action: 'PalletMultiAssetDelegationRewardsAssetAction', - }, OperatorSlashed: { who: 'AccountId32', amount: 'u128', @@ -1620,13 +1606,7 @@ export default { } }, /** - * Lookup126: pallet_multi_asset_delegation::types::rewards::AssetAction - **/ - PalletMultiAssetDelegationRewardsAssetAction: { - _enum: ['Add', 'Remove'] - }, - /** - * Lookup127: pallet_services::module::Event + * Lookup125: pallet_services::module::Event **/ PalletServicesModuleEvent: { _enum: { @@ -1728,14 +1708,14 @@ export default { } }, /** - * Lookup128: tangle_primitives::services::OperatorPreferences + * Lookup126: tangle_primitives::services::OperatorPreferences **/ TanglePrimitivesServicesOperatorPreferences: { key: '[u8;65]', priceTargets: 'TanglePrimitivesServicesPriceTargets' }, /** - * Lookup130: tangle_primitives::services::PriceTargets + * Lookup128: tangle_primitives::services::PriceTargets **/ TanglePrimitivesServicesPriceTargets: { cpu: 'u64', @@ -1745,7 +1725,7 @@ export default { storageNvme: 'u64' }, /** - * Lookup132: tangle_primitives::services::field::Field + * Lookup130: tangle_primitives::services::field::Field **/ TanglePrimitivesServicesField: { _enum: { @@ -1853,7 +1833,7 @@ export default { } }, /** - * Lookup145: pallet_tangle_lst::pallet::Event + * Lookup143: pallet_tangle_lst::pallet::Event **/ PalletTangleLstEvent: { _enum: { @@ -1941,20 +1921,20 @@ export default { } }, /** - * Lookup146: pallet_tangle_lst::types::pools::PoolState + * Lookup144: pallet_tangle_lst::types::pools::PoolState **/ PalletTangleLstPoolsPoolState: { _enum: ['Open', 'Blocked', 'Destroying'] }, /** - * Lookup147: pallet_tangle_lst::types::commission::CommissionChangeRate + * Lookup145: pallet_tangle_lst::types::commission::CommissionChangeRate **/ PalletTangleLstCommissionCommissionChangeRate: { maxIncrease: 'Perbill', minDelay: 'u64' }, /** - * Lookup149: pallet_tangle_lst::types::commission::CommissionClaimPermission + * Lookup147: pallet_tangle_lst::types::commission::CommissionClaimPermission **/ PalletTangleLstCommissionCommissionClaimPermission: { _enum: { @@ -1963,7 +1943,41 @@ export default { } }, /** - * Lookup150: frame_system::Phase + * Lookup148: pallet_rewards::pallet::Event + **/ + PalletRewardsEvent: { + _enum: { + RewardsClaimed: { + account: 'AccountId32', + asset: 'TanglePrimitivesServicesAsset', + amount: 'u128', + }, + IncentiveAPYAndCapSet: { + vaultId: 'u32', + apy: 'Percent', + cap: 'u128', + }, + BlueprintWhitelisted: { + blueprintId: 'u64', + }, + AssetUpdatedInVault: { + vaultId: 'u32', + assetId: 'TanglePrimitivesServicesAsset', + action: 'PalletRewardsAssetAction', + }, + VaultRewardConfigUpdated: { + vaultId: 'u32' + } + } + }, + /** + * Lookup150: pallet_rewards::types::AssetAction + **/ + PalletRewardsAssetAction: { + _enum: ['Add', 'Remove'] + }, + /** + * Lookup151: frame_system::Phase **/ FrameSystemPhase: { _enum: { @@ -1973,21 +1987,21 @@ export default { } }, /** - * Lookup152: frame_system::LastRuntimeUpgradeInfo + * Lookup153: frame_system::LastRuntimeUpgradeInfo **/ FrameSystemLastRuntimeUpgradeInfo: { specVersion: 'Compact', specName: 'Text' }, /** - * Lookup154: frame_system::CodeUpgradeAuthorization + * Lookup155: frame_system::CodeUpgradeAuthorization **/ FrameSystemCodeUpgradeAuthorization: { codeHash: 'H256', checkVersion: 'bool' }, /** - * Lookup155: frame_system::pallet::Call + * Lookup156: frame_system::pallet::Call **/ FrameSystemCall: { _enum: { @@ -2032,7 +2046,7 @@ export default { } }, /** - * Lookup159: frame_system::limits::BlockWeights + * Lookup160: frame_system::limits::BlockWeights **/ FrameSystemLimitsBlockWeights: { baseBlock: 'SpWeightsWeightV2Weight', @@ -2040,7 +2054,7 @@ export default { perClass: 'FrameSupportDispatchPerDispatchClassWeightsPerClass' }, /** - * Lookup160: frame_support::dispatch::PerDispatchClass + * Lookup161: frame_support::dispatch::PerDispatchClass **/ FrameSupportDispatchPerDispatchClassWeightsPerClass: { normal: 'FrameSystemLimitsWeightsPerClass', @@ -2048,7 +2062,7 @@ export default { mandatory: 'FrameSystemLimitsWeightsPerClass' }, /** - * Lookup161: frame_system::limits::WeightsPerClass + * Lookup162: frame_system::limits::WeightsPerClass **/ FrameSystemLimitsWeightsPerClass: { baseExtrinsic: 'SpWeightsWeightV2Weight', @@ -2057,13 +2071,13 @@ export default { reserved: 'Option' }, /** - * Lookup163: frame_system::limits::BlockLength + * Lookup164: frame_system::limits::BlockLength **/ FrameSystemLimitsBlockLength: { max: 'FrameSupportDispatchPerDispatchClassU32' }, /** - * Lookup164: frame_support::dispatch::PerDispatchClass + * Lookup165: frame_support::dispatch::PerDispatchClass **/ FrameSupportDispatchPerDispatchClassU32: { normal: 'u32', @@ -2071,14 +2085,14 @@ export default { mandatory: 'u32' }, /** - * Lookup165: sp_weights::RuntimeDbWeight + * Lookup166: sp_weights::RuntimeDbWeight **/ SpWeightsRuntimeDbWeight: { read: 'u64', write: 'u64' }, /** - * Lookup166: sp_version::RuntimeVersion + * Lookup167: sp_version::RuntimeVersion **/ SpVersionRuntimeVersion: { specName: 'Text', @@ -2091,13 +2105,13 @@ export default { stateVersion: 'u8' }, /** - * Lookup171: frame_system::pallet::Error + * Lookup172: frame_system::pallet::Error **/ FrameSystemError: { _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered', 'MultiBlockMigrationsOngoing', 'NothingAuthorized', 'Unauthorized'] }, /** - * Lookup172: pallet_timestamp::pallet::Call + * Lookup173: pallet_timestamp::pallet::Call **/ PalletTimestampCall: { _enum: { @@ -2107,7 +2121,7 @@ export default { } }, /** - * Lookup173: pallet_sudo::pallet::Call + * Lookup174: pallet_sudo::pallet::Call **/ PalletSudoCall: { _enum: { @@ -2132,7 +2146,7 @@ export default { } }, /** - * Lookup175: pallet_assets::pallet::Call + * Lookup176: pallet_assets::pallet::Call **/ PalletAssetsCall: { _enum: { @@ -2284,7 +2298,7 @@ export default { } }, /** - * Lookup177: pallet_balances::pallet::Call + * Lookup178: pallet_balances::pallet::Call **/ PalletBalancesCall: { _enum: { @@ -2329,13 +2343,13 @@ export default { } }, /** - * Lookup178: pallet_balances::types::AdjustmentDirection + * Lookup179: pallet_balances::types::AdjustmentDirection **/ PalletBalancesAdjustmentDirection: { _enum: ['Increase', 'Decrease'] }, /** - * Lookup179: pallet_babe::pallet::Call + * Lookup180: pallet_babe::pallet::Call **/ PalletBabeCall: { _enum: { @@ -2353,7 +2367,7 @@ export default { } }, /** - * Lookup180: sp_consensus_slots::EquivocationProof, sp_consensus_babe::app::Public> + * Lookup181: sp_consensus_slots::EquivocationProof, sp_consensus_babe::app::Public> **/ SpConsensusSlotsEquivocationProof: { offender: 'SpConsensusBabeAppPublic', @@ -2362,7 +2376,7 @@ export default { secondHeader: 'SpRuntimeHeader' }, /** - * Lookup181: sp_runtime::generic::header::Header + * Lookup182: sp_runtime::generic::header::Header **/ SpRuntimeHeader: { parentHash: 'H256', @@ -2372,11 +2386,11 @@ export default { digest: 'SpRuntimeDigest' }, /** - * Lookup182: sp_consensus_babe::app::Public + * Lookup183: sp_consensus_babe::app::Public **/ SpConsensusBabeAppPublic: '[u8;32]', /** - * Lookup184: sp_session::MembershipProof + * Lookup185: sp_session::MembershipProof **/ SpSessionMembershipProof: { session: 'u32', @@ -2384,7 +2398,7 @@ export default { validatorCount: 'u32' }, /** - * Lookup185: sp_consensus_babe::digests::NextConfigDescriptor + * Lookup186: sp_consensus_babe::digests::NextConfigDescriptor **/ SpConsensusBabeDigestsNextConfigDescriptor: { _enum: { @@ -2396,13 +2410,13 @@ export default { } }, /** - * Lookup187: sp_consensus_babe::AllowedSlots + * Lookup188: sp_consensus_babe::AllowedSlots **/ SpConsensusBabeAllowedSlots: { _enum: ['PrimarySlots', 'PrimaryAndSecondaryPlainSlots', 'PrimaryAndSecondaryVRFSlots'] }, /** - * Lookup188: pallet_grandpa::pallet::Call + * Lookup189: pallet_grandpa::pallet::Call **/ PalletGrandpaCall: { _enum: { @@ -2421,14 +2435,14 @@ export default { } }, /** - * Lookup189: sp_consensus_grandpa::EquivocationProof + * Lookup190: sp_consensus_grandpa::EquivocationProof **/ SpConsensusGrandpaEquivocationProof: { setId: 'u64', equivocation: 'SpConsensusGrandpaEquivocation' }, /** - * Lookup190: sp_consensus_grandpa::Equivocation + * Lookup191: sp_consensus_grandpa::Equivocation **/ SpConsensusGrandpaEquivocation: { _enum: { @@ -2437,7 +2451,7 @@ export default { } }, /** - * Lookup191: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> + * Lookup192: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> **/ FinalityGrandpaEquivocationPrevote: { roundNumber: 'u64', @@ -2446,18 +2460,18 @@ export default { second: '(FinalityGrandpaPrevote,SpConsensusGrandpaAppSignature)' }, /** - * Lookup192: finality_grandpa::Prevote + * Lookup193: finality_grandpa::Prevote **/ FinalityGrandpaPrevote: { targetHash: 'H256', targetNumber: 'u64' }, /** - * Lookup193: sp_consensus_grandpa::app::Signature + * Lookup194: sp_consensus_grandpa::app::Signature **/ SpConsensusGrandpaAppSignature: '[u8;64]', /** - * Lookup196: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> + * Lookup197: finality_grandpa::Equivocation, sp_consensus_grandpa::app::Signature> **/ FinalityGrandpaEquivocationPrecommit: { roundNumber: 'u64', @@ -2466,18 +2480,18 @@ export default { second: '(FinalityGrandpaPrecommit,SpConsensusGrandpaAppSignature)' }, /** - * Lookup197: finality_grandpa::Precommit + * Lookup198: finality_grandpa::Precommit **/ FinalityGrandpaPrecommit: { targetHash: 'H256', targetNumber: 'u64' }, /** - * Lookup199: sp_core::Void + * Lookup200: sp_core::Void **/ SpCoreVoid: 'Null', /** - * Lookup200: pallet_indices::pallet::Call + * Lookup201: pallet_indices::pallet::Call **/ PalletIndicesCall: { _enum: { @@ -2508,7 +2522,7 @@ export default { } }, /** - * Lookup201: pallet_democracy::pallet::Call + * Lookup202: pallet_democracy::pallet::Call **/ PalletDemocracyCall: { _enum: { @@ -2577,7 +2591,7 @@ export default { } }, /** - * Lookup202: frame_support::traits::preimages::Bounded + * Lookup203: frame_support::traits::preimages::Bounded **/ FrameSupportPreimagesBounded: { _enum: { @@ -2598,17 +2612,17 @@ export default { } }, /** - * Lookup203: sp_runtime::traits::BlakeTwo256 + * Lookup204: sp_runtime::traits::BlakeTwo256 **/ SpRuntimeBlakeTwo256: 'Null', /** - * Lookup205: pallet_democracy::conviction::Conviction + * Lookup206: pallet_democracy::conviction::Conviction **/ PalletDemocracyConviction: { _enum: ['None', 'Locked1x', 'Locked2x', 'Locked3x', 'Locked4x', 'Locked5x', 'Locked6x'] }, /** - * Lookup208: pallet_collective::pallet::Call + * Lookup209: pallet_collective::pallet::Call **/ PalletCollectiveCall: { _enum: { @@ -2644,7 +2658,7 @@ export default { } }, /** - * Lookup209: pallet_vesting::pallet::Call + * Lookup210: pallet_vesting::pallet::Call **/ PalletVestingCall: { _enum: { @@ -2672,7 +2686,7 @@ export default { } }, /** - * Lookup210: pallet_vesting::vesting_info::VestingInfo + * Lookup211: pallet_vesting::vesting_info::VestingInfo **/ PalletVestingVestingInfo: { locked: 'u128', @@ -2680,7 +2694,7 @@ export default { startingBlock: 'u64' }, /** - * Lookup211: pallet_elections_phragmen::pallet::Call + * Lookup212: pallet_elections_phragmen::pallet::Call **/ PalletElectionsPhragmenCall: { _enum: { @@ -2707,7 +2721,7 @@ export default { } }, /** - * Lookup212: pallet_elections_phragmen::Renouncing + * Lookup213: pallet_elections_phragmen::Renouncing **/ PalletElectionsPhragmenRenouncing: { _enum: { @@ -2717,7 +2731,7 @@ export default { } }, /** - * Lookup213: pallet_election_provider_multi_phase::pallet::Call + * Lookup214: pallet_election_provider_multi_phase::pallet::Call **/ PalletElectionProviderMultiPhaseCall: { _enum: { @@ -2741,7 +2755,7 @@ export default { } }, /** - * Lookup214: pallet_election_provider_multi_phase::RawSolution + * Lookup215: pallet_election_provider_multi_phase::RawSolution **/ PalletElectionProviderMultiPhaseRawSolution: { solution: 'TangleTestnetRuntimeNposSolution16', @@ -2749,7 +2763,7 @@ export default { round: 'u32' }, /** - * Lookup215: tangle_testnet_runtime::NposSolution16 + * Lookup216: tangle_testnet_runtime::NposSolution16 **/ TangleTestnetRuntimeNposSolution16: { votes1: 'Vec<(Compact,Compact)>', @@ -2770,21 +2784,21 @@ export default { votes16: 'Vec<(Compact,[(Compact,Compact);15],Compact)>' }, /** - * Lookup266: pallet_election_provider_multi_phase::SolutionOrSnapshotSize + * Lookup267: pallet_election_provider_multi_phase::SolutionOrSnapshotSize **/ PalletElectionProviderMultiPhaseSolutionOrSnapshotSize: { voters: 'Compact', targets: 'Compact' }, /** - * Lookup270: sp_npos_elections::Support + * Lookup271: sp_npos_elections::Support **/ SpNposElectionsSupport: { total: 'u128', voters: 'Vec<(AccountId32,u128)>' }, /** - * Lookup271: pallet_staking::pallet::pallet::Call + * Lookup272: pallet_staking::pallet::pallet::Call **/ PalletStakingPalletCall: { _enum: { @@ -2893,7 +2907,7 @@ export default { } }, /** - * Lookup274: pallet_staking::pallet::pallet::ConfigOp + * Lookup275: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpU128: { _enum: { @@ -2903,7 +2917,7 @@ export default { } }, /** - * Lookup275: pallet_staking::pallet::pallet::ConfigOp + * Lookup276: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpU32: { _enum: { @@ -2913,7 +2927,7 @@ export default { } }, /** - * Lookup276: pallet_staking::pallet::pallet::ConfigOp + * Lookup277: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpPercent: { _enum: { @@ -2923,7 +2937,7 @@ export default { } }, /** - * Lookup277: pallet_staking::pallet::pallet::ConfigOp + * Lookup278: pallet_staking::pallet::pallet::ConfigOp **/ PalletStakingPalletConfigOpPerbill: { _enum: { @@ -2933,14 +2947,14 @@ export default { } }, /** - * Lookup282: pallet_staking::UnlockChunk + * Lookup283: pallet_staking::UnlockChunk **/ PalletStakingUnlockChunk: { value: 'Compact', era: 'Compact' }, /** - * Lookup284: pallet_session::pallet::Call + * Lookup285: pallet_session::pallet::Call **/ PalletSessionCall: { _enum: { @@ -2955,7 +2969,7 @@ export default { } }, /** - * Lookup285: tangle_testnet_runtime::opaque::SessionKeys + * Lookup286: tangle_testnet_runtime::opaque::SessionKeys **/ TangleTestnetRuntimeOpaqueSessionKeys: { babe: 'SpConsensusBabeAppPublic', @@ -2963,7 +2977,7 @@ export default { imOnline: 'PalletImOnlineSr25519AppSr25519Public' }, /** - * Lookup286: pallet_treasury::pallet::Call + * Lookup287: pallet_treasury::pallet::Call **/ PalletTreasuryCall: { _enum: { @@ -2995,7 +3009,7 @@ export default { } }, /** - * Lookup288: pallet_bounties::pallet::Call + * Lookup289: pallet_bounties::pallet::Call **/ PalletBountiesCall: { _enum: { @@ -3034,7 +3048,7 @@ export default { } }, /** - * Lookup289: pallet_child_bounties::pallet::Call + * Lookup290: pallet_child_bounties::pallet::Call **/ PalletChildBountiesCall: { _enum: { @@ -3073,7 +3087,7 @@ export default { } }, /** - * Lookup290: pallet_bags_list::pallet::Call + * Lookup291: pallet_bags_list::pallet::Call **/ PalletBagsListCall: { _enum: { @@ -3090,7 +3104,7 @@ export default { } }, /** - * Lookup291: pallet_nomination_pools::pallet::Call + * Lookup292: pallet_nomination_pools::pallet::Call **/ PalletNominationPoolsCall: { _enum: { @@ -3200,7 +3214,7 @@ export default { } }, /** - * Lookup292: pallet_nomination_pools::BondExtra + * Lookup293: pallet_nomination_pools::BondExtra **/ PalletNominationPoolsBondExtra: { _enum: { @@ -3209,7 +3223,7 @@ export default { } }, /** - * Lookup293: pallet_nomination_pools::ConfigOp + * Lookup294: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpU128: { _enum: { @@ -3219,7 +3233,7 @@ export default { } }, /** - * Lookup294: pallet_nomination_pools::ConfigOp + * Lookup295: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpU32: { _enum: { @@ -3229,7 +3243,7 @@ export default { } }, /** - * Lookup295: pallet_nomination_pools::ConfigOp + * Lookup296: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpPerbill: { _enum: { @@ -3239,7 +3253,7 @@ export default { } }, /** - * Lookup296: pallet_nomination_pools::ConfigOp + * Lookup297: pallet_nomination_pools::ConfigOp **/ PalletNominationPoolsConfigOpAccountId32: { _enum: { @@ -3249,13 +3263,13 @@ export default { } }, /** - * Lookup297: pallet_nomination_pools::ClaimPermission + * Lookup298: pallet_nomination_pools::ClaimPermission **/ PalletNominationPoolsClaimPermission: { _enum: ['Permissioned', 'PermissionlessCompound', 'PermissionlessWithdraw', 'PermissionlessAll'] }, /** - * Lookup298: pallet_scheduler::pallet::Call + * Lookup299: pallet_scheduler::pallet::Call **/ PalletSchedulerCall: { _enum: { @@ -3311,7 +3325,7 @@ export default { } }, /** - * Lookup300: pallet_preimage::pallet::Call + * Lookup301: pallet_preimage::pallet::Call **/ PalletPreimageCall: { _enum: { @@ -3342,7 +3356,7 @@ export default { } }, /** - * Lookup301: pallet_tx_pause::pallet::Call + * Lookup302: pallet_tx_pause::pallet::Call **/ PalletTxPauseCall: { _enum: { @@ -3355,7 +3369,7 @@ export default { } }, /** - * Lookup302: pallet_im_online::pallet::Call + * Lookup303: pallet_im_online::pallet::Call **/ PalletImOnlineCall: { _enum: { @@ -3366,7 +3380,7 @@ export default { } }, /** - * Lookup303: pallet_im_online::Heartbeat + * Lookup304: pallet_im_online::Heartbeat **/ PalletImOnlineHeartbeat: { blockNumber: 'u64', @@ -3375,11 +3389,11 @@ export default { validatorsLen: 'u32' }, /** - * Lookup304: pallet_im_online::sr25519::app_sr25519::Signature + * Lookup305: pallet_im_online::sr25519::app_sr25519::Signature **/ PalletImOnlineSr25519AppSr25519Signature: '[u8;64]', /** - * Lookup305: pallet_identity::pallet::Call + * Lookup306: pallet_identity::pallet::Call **/ PalletIdentityCall: { _enum: { @@ -3464,7 +3478,7 @@ export default { } }, /** - * Lookup306: pallet_identity::legacy::IdentityInfo + * Lookup307: pallet_identity::legacy::IdentityInfo **/ PalletIdentityLegacyIdentityInfo: { additional: 'Vec<(Data,Data)>', @@ -3478,7 +3492,7 @@ export default { twitter: 'Data' }, /** - * Lookup342: pallet_identity::types::Judgement + * Lookup343: pallet_identity::types::Judgement **/ PalletIdentityJudgement: { _enum: { @@ -3492,7 +3506,7 @@ export default { } }, /** - * Lookup344: sp_runtime::MultiSignature + * Lookup345: sp_runtime::MultiSignature **/ SpRuntimeMultiSignature: { _enum: { @@ -3502,7 +3516,7 @@ export default { } }, /** - * Lookup345: pallet_utility::pallet::Call + * Lookup346: pallet_utility::pallet::Call **/ PalletUtilityCall: { _enum: { @@ -3530,7 +3544,7 @@ export default { } }, /** - * Lookup347: tangle_testnet_runtime::OriginCaller + * Lookup348: tangle_testnet_runtime::OriginCaller **/ TangleTestnetRuntimeOriginCaller: { _enum: { @@ -3571,7 +3585,7 @@ export default { } }, /** - * Lookup348: frame_support::dispatch::RawOrigin + * Lookup349: frame_support::dispatch::RawOrigin **/ FrameSupportDispatchRawOrigin: { _enum: { @@ -3581,7 +3595,7 @@ export default { } }, /** - * Lookup349: pallet_collective::RawOrigin + * Lookup350: pallet_collective::RawOrigin **/ PalletCollectiveRawOrigin: { _enum: { @@ -3591,7 +3605,7 @@ export default { } }, /** - * Lookup350: pallet_ethereum::RawOrigin + * Lookup351: pallet_ethereum::RawOrigin **/ PalletEthereumRawOrigin: { _enum: { @@ -3599,7 +3613,7 @@ export default { } }, /** - * Lookup351: pallet_multisig::pallet::Call + * Lookup352: pallet_multisig::pallet::Call **/ PalletMultisigCall: { _enum: { @@ -3630,7 +3644,7 @@ export default { } }, /** - * Lookup353: pallet_ethereum::pallet::Call + * Lookup354: pallet_ethereum::pallet::Call **/ PalletEthereumCall: { _enum: { @@ -3640,7 +3654,7 @@ export default { } }, /** - * Lookup354: ethereum::transaction::TransactionV2 + * Lookup355: ethereum::transaction::TransactionV2 **/ EthereumTransactionTransactionV2: { _enum: { @@ -3650,7 +3664,7 @@ export default { } }, /** - * Lookup355: ethereum::transaction::LegacyTransaction + * Lookup356: ethereum::transaction::LegacyTransaction **/ EthereumTransactionLegacyTransaction: { nonce: 'U256', @@ -3662,7 +3676,7 @@ export default { signature: 'EthereumTransactionTransactionSignature' }, /** - * Lookup356: ethereum::transaction::TransactionAction + * Lookup357: ethereum::transaction::TransactionAction **/ EthereumTransactionTransactionAction: { _enum: { @@ -3671,7 +3685,7 @@ export default { } }, /** - * Lookup357: ethereum::transaction::TransactionSignature + * Lookup358: ethereum::transaction::TransactionSignature **/ EthereumTransactionTransactionSignature: { v: 'u64', @@ -3679,7 +3693,7 @@ export default { s: 'H256' }, /** - * Lookup359: ethereum::transaction::EIP2930Transaction + * Lookup360: ethereum::transaction::EIP2930Transaction **/ EthereumTransactionEip2930Transaction: { chainId: 'u64', @@ -3695,14 +3709,14 @@ export default { s: 'H256' }, /** - * Lookup361: ethereum::transaction::AccessListItem + * Lookup362: ethereum::transaction::AccessListItem **/ EthereumTransactionAccessListItem: { address: 'H160', storageKeys: 'Vec' }, /** - * Lookup362: ethereum::transaction::EIP1559Transaction + * Lookup363: ethereum::transaction::EIP1559Transaction **/ EthereumTransactionEip1559Transaction: { chainId: 'u64', @@ -3719,7 +3733,7 @@ export default { s: 'H256' }, /** - * Lookup363: pallet_evm::pallet::Call + * Lookup364: pallet_evm::pallet::Call **/ PalletEvmCall: { _enum: { @@ -3762,7 +3776,7 @@ export default { } }, /** - * Lookup367: pallet_dynamic_fee::pallet::Call + * Lookup368: pallet_dynamic_fee::pallet::Call **/ PalletDynamicFeeCall: { _enum: { @@ -3772,7 +3786,7 @@ export default { } }, /** - * Lookup368: pallet_base_fee::pallet::Call + * Lookup369: pallet_base_fee::pallet::Call **/ PalletBaseFeeCall: { _enum: { @@ -3785,7 +3799,7 @@ export default { } }, /** - * Lookup369: pallet_hotfix_sufficients::pallet::Call + * Lookup370: pallet_hotfix_sufficients::pallet::Call **/ PalletHotfixSufficientsCall: { _enum: { @@ -3795,7 +3809,7 @@ export default { } }, /** - * Lookup371: pallet_airdrop_claims::pallet::Call + * Lookup372: pallet_airdrop_claims::pallet::Call **/ PalletAirdropClaimsCall: { _enum: { @@ -3834,7 +3848,7 @@ export default { } }, /** - * Lookup373: pallet_airdrop_claims::utils::MultiAddressSignature + * Lookup374: pallet_airdrop_claims::utils::MultiAddressSignature **/ PalletAirdropClaimsUtilsMultiAddressSignature: { _enum: { @@ -3843,21 +3857,21 @@ export default { } }, /** - * Lookup374: pallet_airdrop_claims::utils::ethereum_address::EcdsaSignature + * Lookup375: pallet_airdrop_claims::utils::ethereum_address::EcdsaSignature **/ PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature: '[u8;65]', /** - * Lookup375: pallet_airdrop_claims::utils::Sr25519Signature + * Lookup376: pallet_airdrop_claims::utils::Sr25519Signature **/ PalletAirdropClaimsUtilsSr25519Signature: '[u8;64]', /** - * Lookup381: pallet_airdrop_claims::StatementKind + * Lookup382: pallet_airdrop_claims::StatementKind **/ PalletAirdropClaimsStatementKind: { _enum: ['Regular', 'Safe'] }, /** - * Lookup382: pallet_proxy::pallet::Call + * Lookup383: pallet_proxy::pallet::Call **/ PalletProxyCall: { _enum: { @@ -3910,7 +3924,7 @@ export default { } }, /** - * Lookup384: pallet_multi_asset_delegation::pallet::Call + * Lookup385: pallet_multi_asset_delegation::pallet::Call **/ PalletMultiAssetDelegationCall: { _enum: { @@ -3934,6 +3948,7 @@ export default { assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', evmAddress: 'Option', + lockMultiplier: 'Option', }, schedule_withdraw: { assetId: 'TanglePrimitivesServicesAsset', @@ -3963,19 +3978,9 @@ export default { assetId: 'TanglePrimitivesServicesAsset', amount: 'u128', }, - set_incentive_apy_and_cap: { - vaultId: 'u128', - apy: 'Percent', - cap: 'u128', - }, - whitelist_blueprint_for_rewards: { - blueprintId: 'u64', - }, - manage_asset_in_vault: { - vaultId: 'u128', - assetId: 'TanglePrimitivesServicesAsset', - action: 'PalletMultiAssetDelegationRewardsAssetAction', - }, + __Unused18: 'Null', + __Unused19: 'Null', + __Unused20: 'Null', __Unused21: 'Null', add_blueprint_id: { blueprintId: 'u64', @@ -3986,7 +3991,13 @@ export default { } }, /** - * Lookup386: pallet_multi_asset_delegation::types::delegator::DelegatorBlueprintSelection + * Lookup388: tangle_primitives::types::rewards::LockMultiplier + **/ + TanglePrimitivesRewardsLockMultiplier: { + _enum: ['__Unused0', 'OneMonth', 'TwoMonths', 'ThreeMonths', '__Unused4', '__Unused5', 'SixMonths'] + }, + /** + * Lookup389: pallet_multi_asset_delegation::types::delegator::DelegatorBlueprintSelection **/ PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection: { _enum: { @@ -3995,11 +4006,11 @@ export default { } }, /** - * Lookup387: tangle_testnet_runtime::MaxDelegatorBlueprints + * Lookup390: tangle_testnet_runtime::MaxDelegatorBlueprints **/ TangleTestnetRuntimeMaxDelegatorBlueprints: 'Null', /** - * Lookup390: pallet_services::module::Call + * Lookup393: pallet_services::module::Call **/ PalletServicesModuleCall: { _enum: { @@ -4068,7 +4079,7 @@ export default { } }, /** - * Lookup391: tangle_primitives::services::ServiceBlueprint + * Lookup394: tangle_primitives::services::ServiceBlueprint **/ TanglePrimitivesServicesServiceBlueprint: { metadata: 'TanglePrimitivesServicesServiceMetadata', @@ -4080,7 +4091,7 @@ export default { gadget: 'TanglePrimitivesServicesGadget' }, /** - * Lookup392: tangle_primitives::services::ServiceMetadata + * Lookup395: tangle_primitives::services::ServiceMetadata **/ TanglePrimitivesServicesServiceMetadata: { name: 'Bytes', @@ -4093,7 +4104,7 @@ export default { license: 'Option' }, /** - * Lookup397: tangle_primitives::services::JobDefinition + * Lookup400: tangle_primitives::services::JobDefinition **/ TanglePrimitivesServicesJobDefinition: { metadata: 'TanglePrimitivesServicesJobMetadata', @@ -4101,14 +4112,14 @@ export default { result: 'Vec' }, /** - * Lookup398: tangle_primitives::services::JobMetadata + * Lookup401: tangle_primitives::services::JobMetadata **/ TanglePrimitivesServicesJobMetadata: { name: 'Bytes', description: 'Option' }, /** - * Lookup400: tangle_primitives::services::field::FieldType + * Lookup403: tangle_primitives::services::field::FieldType **/ TanglePrimitivesServicesFieldFieldType: { _enum: { @@ -4216,7 +4227,7 @@ export default { } }, /** - * Lookup406: tangle_primitives::services::BlueprintServiceManager + * Lookup409: tangle_primitives::services::BlueprintServiceManager **/ TanglePrimitivesServicesBlueprintServiceManager: { _enum: { @@ -4224,7 +4235,7 @@ export default { } }, /** - * Lookup407: tangle_primitives::services::MasterBlueprintServiceManagerRevision + * Lookup410: tangle_primitives::services::MasterBlueprintServiceManagerRevision **/ TanglePrimitivesServicesMasterBlueprintServiceManagerRevision: { _enum: { @@ -4233,7 +4244,7 @@ export default { } }, /** - * Lookup408: tangle_primitives::services::Gadget + * Lookup411: tangle_primitives::services::Gadget **/ TanglePrimitivesServicesGadget: { _enum: { @@ -4243,26 +4254,26 @@ export default { } }, /** - * Lookup409: tangle_primitives::services::WasmGadget + * Lookup412: tangle_primitives::services::WasmGadget **/ TanglePrimitivesServicesWasmGadget: { runtime: 'TanglePrimitivesServicesWasmRuntime', sources: 'Vec' }, /** - * Lookup410: tangle_primitives::services::WasmRuntime + * Lookup413: tangle_primitives::services::WasmRuntime **/ TanglePrimitivesServicesWasmRuntime: { _enum: ['Wasmtime', 'Wasmer'] }, /** - * Lookup412: tangle_primitives::services::GadgetSource + * Lookup415: tangle_primitives::services::GadgetSource **/ TanglePrimitivesServicesGadgetSource: { fetcher: 'TanglePrimitivesServicesGadgetSourceFetcher' }, /** - * Lookup413: tangle_primitives::services::GadgetSourceFetcher + * Lookup416: tangle_primitives::services::GadgetSourceFetcher **/ TanglePrimitivesServicesGadgetSourceFetcher: { _enum: { @@ -4273,7 +4284,7 @@ export default { } }, /** - * Lookup415: tangle_primitives::services::GithubFetcher + * Lookup418: tangle_primitives::services::GithubFetcher **/ TanglePrimitivesServicesGithubFetcher: { owner: 'Bytes', @@ -4282,7 +4293,7 @@ export default { binaries: 'Vec' }, /** - * Lookup423: tangle_primitives::services::GadgetBinary + * Lookup426: tangle_primitives::services::GadgetBinary **/ TanglePrimitivesServicesGadgetBinary: { arch: 'TanglePrimitivesServicesArchitecture', @@ -4291,19 +4302,19 @@ export default { sha256: '[u8;32]' }, /** - * Lookup424: tangle_primitives::services::Architecture + * Lookup427: tangle_primitives::services::Architecture **/ TanglePrimitivesServicesArchitecture: { _enum: ['Wasm', 'Wasm64', 'Wasi', 'Wasi64', 'Amd', 'Amd64', 'Arm', 'Arm64', 'RiscV', 'RiscV64'] }, /** - * Lookup425: tangle_primitives::services::OperatingSystem + * Lookup428: tangle_primitives::services::OperatingSystem **/ TanglePrimitivesServicesOperatingSystem: { _enum: ['Unknown', 'Linux', 'Windows', 'MacOS', 'BSD'] }, /** - * Lookup429: tangle_primitives::services::ImageRegistryFetcher + * Lookup432: tangle_primitives::services::ImageRegistryFetcher **/ TanglePrimitivesServicesImageRegistryFetcher: { _alias: { @@ -4314,7 +4325,7 @@ export default { tag: 'Bytes' }, /** - * Lookup436: tangle_primitives::services::TestFetcher + * Lookup439: tangle_primitives::services::TestFetcher **/ TanglePrimitivesServicesTestFetcher: { cargoPackage: 'Bytes', @@ -4322,19 +4333,19 @@ export default { basePath: 'Bytes' }, /** - * Lookup438: tangle_primitives::services::NativeGadget + * Lookup441: tangle_primitives::services::NativeGadget **/ TanglePrimitivesServicesNativeGadget: { sources: 'Vec' }, /** - * Lookup439: tangle_primitives::services::ContainerGadget + * Lookup442: tangle_primitives::services::ContainerGadget **/ TanglePrimitivesServicesContainerGadget: { sources: 'Vec' }, /** - * Lookup442: pallet_tangle_lst::pallet::Call + * Lookup445: pallet_tangle_lst::pallet::Call **/ PalletTangleLstCall: { _enum: { @@ -4437,7 +4448,7 @@ export default { } }, /** - * Lookup443: pallet_tangle_lst::types::BondExtra + * Lookup446: pallet_tangle_lst::types::BondExtra **/ PalletTangleLstBondExtra: { _enum: { @@ -4445,7 +4456,7 @@ export default { } }, /** - * Lookup448: pallet_tangle_lst::types::ConfigOp + * Lookup451: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpU128: { _enum: { @@ -4455,7 +4466,7 @@ export default { } }, /** - * Lookup449: pallet_tangle_lst::types::ConfigOp + * Lookup452: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpU32: { _enum: { @@ -4465,7 +4476,7 @@ export default { } }, /** - * Lookup450: pallet_tangle_lst::types::ConfigOp + * Lookup453: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpPerbill: { _enum: { @@ -4475,7 +4486,7 @@ export default { } }, /** - * Lookup451: pallet_tangle_lst::types::ConfigOp + * Lookup454: pallet_tangle_lst::types::ConfigOp **/ PalletTangleLstConfigOpAccountId32: { _enum: { @@ -4485,13 +4496,42 @@ export default { } }, /** - * Lookup452: pallet_sudo::pallet::Error + * Lookup455: pallet_rewards::pallet::Call + **/ + PalletRewardsCall: { + _enum: { + __Unused0: 'Null', + claim_rewards: { + asset: 'TanglePrimitivesServicesAsset', + }, + manage_asset_reward_vault: { + vaultId: 'u32', + assetId: 'TanglePrimitivesServicesAsset', + action: 'PalletRewardsAssetAction', + }, + update_vault_reward_config: { + vaultId: 'u32', + newConfig: 'PalletRewardsRewardConfigForAssetVault' + } + } + }, + /** + * Lookup456: pallet_rewards::types::RewardConfigForAssetVault + **/ + PalletRewardsRewardConfigForAssetVault: { + apy: 'Percent', + incentiveCap: 'u128', + depositCap: 'u128', + boostMultiplier: 'Option' + }, + /** + * Lookup457: pallet_sudo::pallet::Error **/ PalletSudoError: { _enum: ['RequireSudo'] }, /** - * Lookup454: pallet_assets::types::AssetDetails + * Lookup459: pallet_assets::types::AssetDetails **/ PalletAssetsAssetDetails: { owner: 'AccountId32', @@ -4508,13 +4548,13 @@ export default { status: 'PalletAssetsAssetStatus' }, /** - * Lookup455: pallet_assets::types::AssetStatus + * Lookup460: pallet_assets::types::AssetStatus **/ PalletAssetsAssetStatus: { _enum: ['Live', 'Frozen', 'Destroying'] }, /** - * Lookup457: pallet_assets::types::AssetAccount + * Lookup462: pallet_assets::types::AssetAccount **/ PalletAssetsAssetAccount: { balance: 'u128', @@ -4523,13 +4563,13 @@ export default { extra: 'Null' }, /** - * Lookup458: pallet_assets::types::AccountStatus + * Lookup463: pallet_assets::types::AccountStatus **/ PalletAssetsAccountStatus: { _enum: ['Liquid', 'Frozen', 'Blocked'] }, /** - * Lookup459: pallet_assets::types::ExistenceReason + * Lookup464: pallet_assets::types::ExistenceReason **/ PalletAssetsExistenceReason: { _enum: { @@ -4541,14 +4581,14 @@ export default { } }, /** - * Lookup461: pallet_assets::types::Approval + * Lookup466: pallet_assets::types::Approval **/ PalletAssetsApproval: { amount: 'u128', deposit: 'u128' }, /** - * Lookup462: pallet_assets::types::AssetMetadata> + * Lookup467: pallet_assets::types::AssetMetadata> **/ PalletAssetsAssetMetadata: { deposit: 'u128', @@ -4558,13 +4598,13 @@ export default { isFrozen: 'bool' }, /** - * Lookup464: pallet_assets::pallet::Error + * Lookup469: pallet_assets::pallet::Error **/ PalletAssetsError: { _enum: ['BalanceLow', 'NoAccount', 'NoPermission', 'Unknown', 'Frozen', 'InUse', 'BadWitness', 'MinBalanceZero', 'UnavailableConsumer', 'BadMetadata', 'Unapproved', 'WouldDie', 'AlreadyExists', 'NoDeposit', 'WouldBurn', 'LiveAsset', 'AssetNotLive', 'IncorrectStatus', 'NotFrozen', 'CallbackFailed', 'BadAssetId'] }, /** - * Lookup466: pallet_balances::types::BalanceLock + * Lookup471: pallet_balances::types::BalanceLock **/ PalletBalancesBalanceLock: { id: '[u8;8]', @@ -4572,27 +4612,27 @@ export default { reasons: 'PalletBalancesReasons' }, /** - * Lookup467: pallet_balances::types::Reasons + * Lookup472: pallet_balances::types::Reasons **/ PalletBalancesReasons: { _enum: ['Fee', 'Misc', 'All'] }, /** - * Lookup470: pallet_balances::types::ReserveData + * Lookup475: pallet_balances::types::ReserveData **/ PalletBalancesReserveData: { id: '[u8;8]', amount: 'u128' }, /** - * Lookup473: frame_support::traits::tokens::misc::IdAmount + * Lookup478: frame_support::traits::tokens::misc::IdAmount **/ FrameSupportTokensMiscIdAmountRuntimeHoldReason: { id: 'TangleTestnetRuntimeRuntimeHoldReason', amount: 'u128' }, /** - * Lookup474: tangle_testnet_runtime::RuntimeHoldReason + * Lookup479: tangle_testnet_runtime::RuntimeHoldReason **/ TangleTestnetRuntimeRuntimeHoldReason: { _enum: { @@ -4626,20 +4666,20 @@ export default { } }, /** - * Lookup475: pallet_preimage::pallet::HoldReason + * Lookup480: pallet_preimage::pallet::HoldReason **/ PalletPreimageHoldReason: { _enum: ['Preimage'] }, /** - * Lookup478: frame_support::traits::tokens::misc::IdAmount + * Lookup483: frame_support::traits::tokens::misc::IdAmount **/ FrameSupportTokensMiscIdAmountRuntimeFreezeReason: { id: 'TangleTestnetRuntimeRuntimeFreezeReason', amount: 'u128' }, /** - * Lookup479: tangle_testnet_runtime::RuntimeFreezeReason + * Lookup484: tangle_testnet_runtime::RuntimeFreezeReason **/ TangleTestnetRuntimeRuntimeFreezeReason: { _enum: { @@ -4699,31 +4739,31 @@ export default { } }, /** - * Lookup480: pallet_nomination_pools::pallet::FreezeReason + * Lookup485: pallet_nomination_pools::pallet::FreezeReason **/ PalletNominationPoolsFreezeReason: { _enum: ['PoolMinBalance'] }, /** - * Lookup481: pallet_tangle_lst::pallet::FreezeReason + * Lookup486: pallet_tangle_lst::pallet::FreezeReason **/ PalletTangleLstFreezeReason: { _enum: ['PoolMinBalance'] }, /** - * Lookup483: pallet_balances::pallet::Error + * Lookup488: pallet_balances::pallet::Error **/ PalletBalancesError: { _enum: ['VestingBalance', 'LiquidityRestrictions', 'InsufficientBalance', 'ExistentialDeposit', 'Expendability', 'ExistingVestingSchedule', 'DeadAccount', 'TooManyReserves', 'TooManyHolds', 'TooManyFreezes', 'IssuanceDeactivated', 'DeltaZero'] }, /** - * Lookup485: pallet_transaction_payment::Releases + * Lookup490: pallet_transaction_payment::Releases **/ PalletTransactionPaymentReleases: { _enum: ['V1Ancient', 'V2'] }, /** - * Lookup492: sp_consensus_babe::digests::PreDigest + * Lookup497: sp_consensus_babe::digests::PreDigest **/ SpConsensusBabeDigestsPreDigest: { _enum: { @@ -4734,7 +4774,7 @@ export default { } }, /** - * Lookup493: sp_consensus_babe::digests::PrimaryPreDigest + * Lookup498: sp_consensus_babe::digests::PrimaryPreDigest **/ SpConsensusBabeDigestsPrimaryPreDigest: { authorityIndex: 'u32', @@ -4742,21 +4782,21 @@ export default { vrfSignature: 'SpCoreSr25519VrfVrfSignature' }, /** - * Lookup494: sp_core::sr25519::vrf::VrfSignature + * Lookup499: sp_core::sr25519::vrf::VrfSignature **/ SpCoreSr25519VrfVrfSignature: { preOutput: '[u8;32]', proof: '[u8;64]' }, /** - * Lookup495: sp_consensus_babe::digests::SecondaryPlainPreDigest + * Lookup500: sp_consensus_babe::digests::SecondaryPlainPreDigest **/ SpConsensusBabeDigestsSecondaryPlainPreDigest: { authorityIndex: 'u32', slot: 'u64' }, /** - * Lookup496: sp_consensus_babe::digests::SecondaryVRFPreDigest + * Lookup501: sp_consensus_babe::digests::SecondaryVRFPreDigest **/ SpConsensusBabeDigestsSecondaryVRFPreDigest: { authorityIndex: 'u32', @@ -4764,20 +4804,20 @@ export default { vrfSignature: 'SpCoreSr25519VrfVrfSignature' }, /** - * Lookup497: sp_consensus_babe::BabeEpochConfiguration + * Lookup502: sp_consensus_babe::BabeEpochConfiguration **/ SpConsensusBabeBabeEpochConfiguration: { c: '(u64,u64)', allowedSlots: 'SpConsensusBabeAllowedSlots' }, /** - * Lookup499: pallet_babe::pallet::Error + * Lookup504: pallet_babe::pallet::Error **/ PalletBabeError: { _enum: ['InvalidEquivocationProof', 'InvalidKeyOwnershipProof', 'DuplicateOffenceReport', 'InvalidConfiguration'] }, /** - * Lookup500: pallet_grandpa::StoredState + * Lookup505: pallet_grandpa::StoredState **/ PalletGrandpaStoredState: { _enum: { @@ -4794,7 +4834,7 @@ export default { } }, /** - * Lookup501: pallet_grandpa::StoredPendingChange + * Lookup506: pallet_grandpa::StoredPendingChange **/ PalletGrandpaStoredPendingChange: { scheduledAt: 'u64', @@ -4803,19 +4843,19 @@ export default { forced: 'Option' }, /** - * Lookup503: pallet_grandpa::pallet::Error + * Lookup508: pallet_grandpa::pallet::Error **/ PalletGrandpaError: { _enum: ['PauseFailed', 'ResumeFailed', 'ChangePending', 'TooSoon', 'InvalidKeyOwnershipProof', 'InvalidEquivocationProof', 'DuplicateOffenceReport'] }, /** - * Lookup505: pallet_indices::pallet::Error + * Lookup510: pallet_indices::pallet::Error **/ PalletIndicesError: { _enum: ['NotAssigned', 'NotOwner', 'InUse', 'NotTransfer', 'Permanent'] }, /** - * Lookup510: pallet_democracy::types::ReferendumInfo, Balance> + * Lookup515: pallet_democracy::types::ReferendumInfo, Balance> **/ PalletDemocracyReferendumInfo: { _enum: { @@ -4827,7 +4867,7 @@ export default { } }, /** - * Lookup511: pallet_democracy::types::ReferendumStatus, Balance> + * Lookup516: pallet_democracy::types::ReferendumStatus, Balance> **/ PalletDemocracyReferendumStatus: { end: 'u64', @@ -4837,7 +4877,7 @@ export default { tally: 'PalletDemocracyTally' }, /** - * Lookup512: pallet_democracy::types::Tally + * Lookup517: pallet_democracy::types::Tally **/ PalletDemocracyTally: { ayes: 'u128', @@ -4845,7 +4885,7 @@ export default { turnout: 'u128' }, /** - * Lookup513: pallet_democracy::vote::Voting + * Lookup518: pallet_democracy::vote::Voting **/ PalletDemocracyVoteVoting: { _enum: { @@ -4864,24 +4904,24 @@ export default { } }, /** - * Lookup517: pallet_democracy::types::Delegations + * Lookup522: pallet_democracy::types::Delegations **/ PalletDemocracyDelegations: { votes: 'u128', capital: 'u128' }, /** - * Lookup518: pallet_democracy::vote::PriorLock + * Lookup523: pallet_democracy::vote::PriorLock **/ PalletDemocracyVotePriorLock: '(u64,u128)', /** - * Lookup521: pallet_democracy::pallet::Error + * Lookup526: pallet_democracy::pallet::Error **/ PalletDemocracyError: { _enum: ['ValueLow', 'ProposalMissing', 'AlreadyCanceled', 'DuplicateProposal', 'ProposalBlacklisted', 'NotSimpleMajority', 'InvalidHash', 'NoProposal', 'AlreadyVetoed', 'ReferendumInvalid', 'NoneWaiting', 'NotVoter', 'NoPermission', 'AlreadyDelegating', 'InsufficientFunds', 'NotDelegating', 'VotesExist', 'InstantNotAllowed', 'Nonsense', 'WrongUpperBound', 'MaxVotesReached', 'TooMany', 'VotingPeriodLow', 'PreimageNotExist'] }, /** - * Lookup523: pallet_collective::Votes + * Lookup528: pallet_collective::Votes **/ PalletCollectiveVotes: { index: 'u32', @@ -4891,25 +4931,25 @@ export default { end: 'u64' }, /** - * Lookup524: pallet_collective::pallet::Error + * Lookup529: pallet_collective::pallet::Error **/ PalletCollectiveError: { _enum: ['NotMember', 'DuplicateProposal', 'ProposalMissing', 'WrongIndex', 'DuplicateVote', 'AlreadyInitialized', 'TooEarly', 'TooManyProposals', 'WrongProposalWeight', 'WrongProposalLength', 'PrimeAccountNotMember'] }, /** - * Lookup527: pallet_vesting::Releases + * Lookup532: pallet_vesting::Releases **/ PalletVestingReleases: { _enum: ['V0', 'V1'] }, /** - * Lookup528: pallet_vesting::pallet::Error + * Lookup533: pallet_vesting::pallet::Error **/ PalletVestingError: { _enum: ['NotVesting', 'AtMaxVestingSchedules', 'AmountLow', 'ScheduleIndexOutOfBounds', 'InvalidScheduleParams'] }, /** - * Lookup530: pallet_elections_phragmen::SeatHolder + * Lookup535: pallet_elections_phragmen::SeatHolder **/ PalletElectionsPhragmenSeatHolder: { who: 'AccountId32', @@ -4917,7 +4957,7 @@ export default { deposit: 'u128' }, /** - * Lookup531: pallet_elections_phragmen::Voter + * Lookup536: pallet_elections_phragmen::Voter **/ PalletElectionsPhragmenVoter: { votes: 'Vec', @@ -4925,13 +4965,13 @@ export default { deposit: 'u128' }, /** - * Lookup532: pallet_elections_phragmen::pallet::Error + * Lookup537: pallet_elections_phragmen::pallet::Error **/ PalletElectionsPhragmenError: { _enum: ['UnableToVote', 'NoVotes', 'TooManyVotes', 'MaximumVotesExceeded', 'LowBalance', 'UnableToPayBond', 'MustBeVoter', 'DuplicatedCandidate', 'TooManyCandidates', 'MemberSubmit', 'RunnerUpSubmit', 'InsufficientCandidateFunds', 'NotMember', 'InvalidWitnessData', 'InvalidVoteCount', 'InvalidRenouncing', 'InvalidReplacement'] }, /** - * Lookup533: pallet_election_provider_multi_phase::ReadySolution + * Lookup538: pallet_election_provider_multi_phase::ReadySolution **/ PalletElectionProviderMultiPhaseReadySolution: { supports: 'Vec<(AccountId32,SpNposElectionsSupport)>', @@ -4939,14 +4979,14 @@ export default { compute: 'PalletElectionProviderMultiPhaseElectionCompute' }, /** - * Lookup535: pallet_election_provider_multi_phase::RoundSnapshot + * Lookup540: pallet_election_provider_multi_phase::RoundSnapshot **/ PalletElectionProviderMultiPhaseRoundSnapshot: { voters: 'Vec<(AccountId32,u64,Vec)>', targets: 'Vec' }, /** - * Lookup542: pallet_election_provider_multi_phase::signed::SignedSubmission + * Lookup547: pallet_election_provider_multi_phase::signed::SignedSubmission **/ PalletElectionProviderMultiPhaseSignedSignedSubmission: { who: 'AccountId32', @@ -4955,13 +4995,13 @@ export default { callFee: 'u128' }, /** - * Lookup543: pallet_election_provider_multi_phase::pallet::Error + * Lookup548: pallet_election_provider_multi_phase::pallet::Error **/ PalletElectionProviderMultiPhaseError: { _enum: ['PreDispatchEarlySubmission', 'PreDispatchWrongWinnerCount', 'PreDispatchWeakSubmission', 'SignedQueueFull', 'SignedCannotPayDeposit', 'SignedInvalidWitness', 'SignedTooMuchWeight', 'OcwCallWrongEra', 'MissingSnapshotMetadata', 'InvalidSubmissionIndex', 'CallNotAllowed', 'FallbackFailed', 'BoundNotMet', 'TooManyWinners', 'PreDispatchDifferentRound'] }, /** - * Lookup544: pallet_staking::StakingLedger + * Lookup549: pallet_staking::StakingLedger **/ PalletStakingStakingLedger: { stash: 'AccountId32', @@ -4971,7 +5011,7 @@ export default { legacyClaimedRewards: 'Vec' }, /** - * Lookup546: pallet_staking::Nominations + * Lookup551: pallet_staking::Nominations **/ PalletStakingNominations: { targets: 'Vec', @@ -4979,14 +5019,14 @@ export default { suppressed: 'bool' }, /** - * Lookup547: pallet_staking::ActiveEraInfo + * Lookup552: pallet_staking::ActiveEraInfo **/ PalletStakingActiveEraInfo: { index: 'u32', start: 'Option' }, /** - * Lookup549: sp_staking::PagedExposureMetadata + * Lookup554: sp_staking::PagedExposureMetadata **/ SpStakingPagedExposureMetadata: { total: 'Compact', @@ -4995,21 +5035,21 @@ export default { pageCount: 'u32' }, /** - * Lookup551: sp_staking::ExposurePage + * Lookup556: sp_staking::ExposurePage **/ SpStakingExposurePage: { pageTotal: 'Compact', others: 'Vec' }, /** - * Lookup552: pallet_staking::EraRewardPoints + * Lookup557: pallet_staking::EraRewardPoints **/ PalletStakingEraRewardPoints: { total: 'u32', individual: 'BTreeMap' }, /** - * Lookup557: pallet_staking::UnappliedSlash + * Lookup562: pallet_staking::UnappliedSlash **/ PalletStakingUnappliedSlash: { validator: 'AccountId32', @@ -5019,7 +5059,7 @@ export default { payout: 'u128' }, /** - * Lookup561: pallet_staking::slashing::SlashingSpans + * Lookup566: pallet_staking::slashing::SlashingSpans **/ PalletStakingSlashingSlashingSpans: { spanIndex: 'u32', @@ -5028,30 +5068,30 @@ export default { prior: 'Vec' }, /** - * Lookup562: pallet_staking::slashing::SpanRecord + * Lookup567: pallet_staking::slashing::SpanRecord **/ PalletStakingSlashingSpanRecord: { slashed: 'u128', paidOut: 'u128' }, /** - * Lookup563: pallet_staking::pallet::pallet::Error + * Lookup568: pallet_staking::pallet::pallet::Error **/ PalletStakingPalletError: { _enum: ['NotController', 'NotStash', 'AlreadyBonded', 'AlreadyPaired', 'EmptyTargets', 'DuplicateIndex', 'InvalidSlashIndex', 'InsufficientBond', 'NoMoreChunks', 'NoUnlockChunk', 'FundedTarget', 'InvalidEraToReward', 'InvalidNumberOfNominations', 'NotSortedAndUnique', 'AlreadyClaimed', 'InvalidPage', 'IncorrectHistoryDepth', 'IncorrectSlashingSpans', 'BadState', 'TooManyTargets', 'BadTarget', 'CannotChillOther', 'TooManyNominators', 'TooManyValidators', 'CommissionTooLow', 'BoundNotMet', 'ControllerDeprecated', 'CannotRestoreLedger', 'RewardDestinationRestricted', 'NotEnoughFunds', 'VirtualStakerNotAllowed'] }, /** - * Lookup567: sp_core::crypto::KeyTypeId + * Lookup572: sp_core::crypto::KeyTypeId **/ SpCoreCryptoKeyTypeId: '[u8;4]', /** - * Lookup568: pallet_session::pallet::Error + * Lookup573: pallet_session::pallet::Error **/ PalletSessionError: { _enum: ['InvalidProof', 'NoAssociatedValidatorId', 'DuplicatedKey', 'NoKeys', 'NoAccount'] }, /** - * Lookup570: pallet_treasury::Proposal + * Lookup575: pallet_treasury::Proposal **/ PalletTreasuryProposal: { proposer: 'AccountId32', @@ -5060,7 +5100,7 @@ export default { bond: 'u128' }, /** - * Lookup572: pallet_treasury::SpendStatus + * Lookup577: pallet_treasury::SpendStatus **/ PalletTreasurySpendStatus: { assetKind: 'Null', @@ -5071,7 +5111,7 @@ export default { status: 'PalletTreasuryPaymentState' }, /** - * Lookup573: pallet_treasury::PaymentState + * Lookup578: pallet_treasury::PaymentState **/ PalletTreasuryPaymentState: { _enum: { @@ -5083,17 +5123,17 @@ export default { } }, /** - * Lookup574: frame_support::PalletId + * Lookup579: frame_support::PalletId **/ FrameSupportPalletId: '[u8;8]', /** - * Lookup575: pallet_treasury::pallet::Error + * Lookup580: pallet_treasury::pallet::Error **/ PalletTreasuryError: { _enum: ['InvalidIndex', 'TooManyApprovals', 'InsufficientPermission', 'ProposalNotApproved', 'FailedToConvertBalance', 'SpendExpired', 'EarlyPayout', 'AlreadyAttempted', 'PayoutError', 'NotAttempted', 'Inconclusive'] }, /** - * Lookup576: pallet_bounties::Bounty + * Lookup581: pallet_bounties::Bounty **/ PalletBountiesBounty: { proposer: 'AccountId32', @@ -5104,7 +5144,7 @@ export default { status: 'PalletBountiesBountyStatus' }, /** - * Lookup577: pallet_bounties::BountyStatus + * Lookup582: pallet_bounties::BountyStatus **/ PalletBountiesBountyStatus: { _enum: { @@ -5126,13 +5166,13 @@ export default { } }, /** - * Lookup579: pallet_bounties::pallet::Error + * Lookup584: pallet_bounties::pallet::Error **/ PalletBountiesError: { _enum: ['InsufficientProposersBalance', 'InvalidIndex', 'ReasonTooBig', 'UnexpectedStatus', 'RequireCurator', 'InvalidValue', 'InvalidFee', 'PendingPayout', 'Premature', 'HasActiveChildBounty', 'TooManyQueued'] }, /** - * Lookup580: pallet_child_bounties::ChildBounty + * Lookup585: pallet_child_bounties::ChildBounty **/ PalletChildBountiesChildBounty: { parentBounty: 'u32', @@ -5142,7 +5182,7 @@ export default { status: 'PalletChildBountiesChildBountyStatus' }, /** - * Lookup581: pallet_child_bounties::ChildBountyStatus + * Lookup586: pallet_child_bounties::ChildBountyStatus **/ PalletChildBountiesChildBountyStatus: { _enum: { @@ -5161,13 +5201,13 @@ export default { } }, /** - * Lookup582: pallet_child_bounties::pallet::Error + * Lookup587: pallet_child_bounties::pallet::Error **/ PalletChildBountiesError: { _enum: ['ParentBountyNotActive', 'InsufficientBountyBalance', 'TooManyChildBounties'] }, /** - * Lookup583: pallet_bags_list::list::Node + * Lookup588: pallet_bags_list::list::Node **/ PalletBagsListListNode: { id: 'AccountId32', @@ -5177,14 +5217,14 @@ export default { score: 'u64' }, /** - * Lookup584: pallet_bags_list::list::Bag + * Lookup589: pallet_bags_list::list::Bag **/ PalletBagsListListBag: { head: 'Option', tail: 'Option' }, /** - * Lookup585: pallet_bags_list::pallet::Error + * Lookup590: pallet_bags_list::pallet::Error **/ PalletBagsListError: { _enum: { @@ -5192,13 +5232,13 @@ export default { } }, /** - * Lookup586: pallet_bags_list::list::ListError + * Lookup591: pallet_bags_list::list::ListError **/ PalletBagsListListListError: { _enum: ['Duplicate', 'NotHeavier', 'NotInSameBag', 'NodeNotFound'] }, /** - * Lookup587: pallet_nomination_pools::PoolMember + * Lookup592: pallet_nomination_pools::PoolMember **/ PalletNominationPoolsPoolMember: { poolId: 'u32', @@ -5207,7 +5247,7 @@ export default { unbondingEras: 'BTreeMap' }, /** - * Lookup592: pallet_nomination_pools::BondedPoolInner + * Lookup597: pallet_nomination_pools::BondedPoolInner **/ PalletNominationPoolsBondedPoolInner: { commission: 'PalletNominationPoolsCommission', @@ -5217,7 +5257,7 @@ export default { state: 'PalletNominationPoolsPoolState' }, /** - * Lookup593: pallet_nomination_pools::Commission + * Lookup598: pallet_nomination_pools::Commission **/ PalletNominationPoolsCommission: { current: 'Option<(Perbill,AccountId32)>', @@ -5227,7 +5267,7 @@ export default { claimPermission: 'Option' }, /** - * Lookup596: pallet_nomination_pools::PoolRoles + * Lookup601: pallet_nomination_pools::PoolRoles **/ PalletNominationPoolsPoolRoles: { depositor: 'AccountId32', @@ -5236,7 +5276,7 @@ export default { bouncer: 'Option' }, /** - * Lookup597: pallet_nomination_pools::RewardPool + * Lookup602: pallet_nomination_pools::RewardPool **/ PalletNominationPoolsRewardPool: { lastRecordedRewardCounter: 'u128', @@ -5246,21 +5286,21 @@ export default { totalCommissionClaimed: 'u128' }, /** - * Lookup598: pallet_nomination_pools::SubPools + * Lookup603: pallet_nomination_pools::SubPools **/ PalletNominationPoolsSubPools: { noEra: 'PalletNominationPoolsUnbondPool', withEra: 'BTreeMap' }, /** - * Lookup599: pallet_nomination_pools::UnbondPool + * Lookup604: pallet_nomination_pools::UnbondPool **/ PalletNominationPoolsUnbondPool: { points: 'u128', balance: 'u128' }, /** - * Lookup604: pallet_nomination_pools::pallet::Error + * Lookup609: pallet_nomination_pools::pallet::Error **/ PalletNominationPoolsError: { _enum: { @@ -5304,13 +5344,13 @@ export default { } }, /** - * Lookup605: pallet_nomination_pools::pallet::DefensiveError + * Lookup610: pallet_nomination_pools::pallet::DefensiveError **/ PalletNominationPoolsDefensiveError: { _enum: ['NotEnoughSpaceInUnbondPool', 'PoolNotFound', 'RewardPoolNotFound', 'SubPoolsNotFound', 'BondedStashKilledPrematurely', 'DelegationUnsupported', 'SlashNotApplied'] }, /** - * Lookup608: pallet_scheduler::Scheduled, BlockNumber, tangle_testnet_runtime::OriginCaller, sp_core::crypto::AccountId32> + * Lookup613: pallet_scheduler::Scheduled, BlockNumber, tangle_testnet_runtime::OriginCaller, sp_core::crypto::AccountId32> **/ PalletSchedulerScheduled: { maybeId: 'Option<[u8;32]>', @@ -5320,7 +5360,7 @@ export default { origin: 'TangleTestnetRuntimeOriginCaller' }, /** - * Lookup610: pallet_scheduler::RetryConfig + * Lookup615: pallet_scheduler::RetryConfig **/ PalletSchedulerRetryConfig: { totalRetries: 'u8', @@ -5328,13 +5368,13 @@ export default { period: 'u64' }, /** - * Lookup611: pallet_scheduler::pallet::Error + * Lookup616: pallet_scheduler::pallet::Error **/ PalletSchedulerError: { _enum: ['FailedToSchedule', 'NotFound', 'TargetBlockNumberInPast', 'RescheduleNoChange', 'Named'] }, /** - * Lookup612: pallet_preimage::OldRequestStatus + * Lookup617: pallet_preimage::OldRequestStatus **/ PalletPreimageOldRequestStatus: { _enum: { @@ -5350,7 +5390,7 @@ export default { } }, /** - * Lookup614: pallet_preimage::RequestStatus + * Lookup619: pallet_preimage::RequestStatus **/ PalletPreimageRequestStatus: { _enum: { @@ -5366,32 +5406,32 @@ export default { } }, /** - * Lookup618: pallet_preimage::pallet::Error + * Lookup623: pallet_preimage::pallet::Error **/ PalletPreimageError: { _enum: ['TooBig', 'AlreadyNoted', 'NotAuthorized', 'NotNoted', 'Requested', 'NotRequested', 'TooMany', 'TooFew', 'NoCost'] }, /** - * Lookup619: sp_staking::offence::OffenceDetails + * Lookup624: sp_staking::offence::OffenceDetails **/ SpStakingOffenceOffenceDetails: { offender: '(AccountId32,SpStakingExposure)', reporters: 'Vec' }, /** - * Lookup621: pallet_tx_pause::pallet::Error + * Lookup626: pallet_tx_pause::pallet::Error **/ PalletTxPauseError: { _enum: ['IsPaused', 'IsUnpaused', 'Unpausable', 'NotFound'] }, /** - * Lookup624: pallet_im_online::pallet::Error + * Lookup629: pallet_im_online::pallet::Error **/ PalletImOnlineError: { _enum: ['InvalidKey', 'DuplicatedHeartbeat'] }, /** - * Lookup626: pallet_identity::types::Registration> + * Lookup631: pallet_identity::types::Registration> **/ PalletIdentityRegistration: { judgements: 'Vec<(u32,PalletIdentityJudgement)>', @@ -5399,7 +5439,7 @@ export default { info: 'PalletIdentityLegacyIdentityInfo' }, /** - * Lookup635: pallet_identity::types::RegistrarInfo + * Lookup640: pallet_identity::types::RegistrarInfo **/ PalletIdentityRegistrarInfo: { account: 'AccountId32', @@ -5407,26 +5447,26 @@ export default { fields: 'u64' }, /** - * Lookup637: pallet_identity::types::AuthorityProperties> + * Lookup642: pallet_identity::types::AuthorityProperties> **/ PalletIdentityAuthorityProperties: { suffix: 'Bytes', allocation: 'u32' }, /** - * Lookup640: pallet_identity::pallet::Error + * Lookup645: pallet_identity::pallet::Error **/ PalletIdentityError: { _enum: ['TooManySubAccounts', 'NotFound', 'NotNamed', 'EmptyIndex', 'FeeChanged', 'NoIdentity', 'StickyJudgement', 'JudgementGiven', 'InvalidJudgement', 'InvalidIndex', 'InvalidTarget', 'TooManyRegistrars', 'AlreadyClaimed', 'NotSub', 'NotOwned', 'JudgementForDifferentIdentity', 'JudgementPaymentFailed', 'InvalidSuffix', 'NotUsernameAuthority', 'NoAllocation', 'InvalidSignature', 'RequiresSignature', 'InvalidUsername', 'UsernameTaken', 'NoUsername', 'NotExpired'] }, /** - * Lookup641: pallet_utility::pallet::Error + * Lookup646: pallet_utility::pallet::Error **/ PalletUtilityError: { _enum: ['TooManyCalls'] }, /** - * Lookup643: pallet_multisig::Multisig + * Lookup648: pallet_multisig::Multisig **/ PalletMultisigMultisig: { when: 'PalletMultisigTimepoint', @@ -5435,13 +5475,13 @@ export default { approvals: 'Vec' }, /** - * Lookup644: pallet_multisig::pallet::Error + * Lookup649: pallet_multisig::pallet::Error **/ PalletMultisigError: { _enum: ['MinimumThreshold', 'AlreadyApproved', 'NoApprovalsNeeded', 'TooFewSignatories', 'TooManySignatories', 'SignatoriesOutOfOrder', 'SenderInSignatories', 'NotFound', 'NotOwner', 'NoTimepoint', 'WrongTimepoint', 'UnexpectedTimepoint', 'MaxWeightTooLow', 'AlreadyStored'] }, /** - * Lookup647: fp_rpc::TransactionStatus + * Lookup652: fp_rpc::TransactionStatus **/ FpRpcTransactionStatus: { transactionHash: 'H256', @@ -5453,11 +5493,11 @@ export default { logsBloom: 'EthbloomBloom' }, /** - * Lookup649: ethbloom::Bloom + * Lookup654: ethbloom::Bloom **/ EthbloomBloom: '[u8;256]', /** - * Lookup651: ethereum::receipt::ReceiptV3 + * Lookup656: ethereum::receipt::ReceiptV3 **/ EthereumReceiptReceiptV3: { _enum: { @@ -5467,7 +5507,7 @@ export default { } }, /** - * Lookup652: ethereum::receipt::EIP658ReceiptData + * Lookup657: ethereum::receipt::EIP658ReceiptData **/ EthereumReceiptEip658ReceiptData: { statusCode: 'u8', @@ -5476,7 +5516,7 @@ export default { logs: 'Vec' }, /** - * Lookup653: ethereum::block::Block + * Lookup658: ethereum::block::Block **/ EthereumBlock: { header: 'EthereumHeader', @@ -5484,7 +5524,7 @@ export default { ommers: 'Vec' }, /** - * Lookup654: ethereum::header::Header + * Lookup659: ethereum::header::Header **/ EthereumHeader: { parentHash: 'H256', @@ -5504,17 +5544,17 @@ export default { nonce: 'EthereumTypesHashH64' }, /** - * Lookup655: ethereum_types::hash::H64 + * Lookup660: ethereum_types::hash::H64 **/ EthereumTypesHashH64: '[u8;8]', /** - * Lookup660: pallet_ethereum::pallet::Error + * Lookup665: pallet_ethereum::pallet::Error **/ PalletEthereumError: { _enum: ['InvalidSignature', 'PreLogExists'] }, /** - * Lookup661: pallet_evm::CodeMetadata + * Lookup666: pallet_evm::CodeMetadata **/ PalletEvmCodeMetadata: { _alias: { @@ -5525,25 +5565,25 @@ export default { hash_: 'H256' }, /** - * Lookup663: pallet_evm::pallet::Error + * Lookup668: pallet_evm::pallet::Error **/ PalletEvmError: { _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce', 'GasLimitTooLow', 'GasLimitTooHigh', 'InvalidChainId', 'InvalidSignature', 'Reentrancy', 'TransactionMustComeFromEOA', 'Undefined'] }, /** - * Lookup664: pallet_hotfix_sufficients::pallet::Error + * Lookup669: pallet_hotfix_sufficients::pallet::Error **/ PalletHotfixSufficientsError: { _enum: ['MaxAddressCountExceeded'] }, /** - * Lookup666: pallet_airdrop_claims::pallet::Error + * Lookup671: pallet_airdrop_claims::pallet::Error **/ PalletAirdropClaimsError: { _enum: ['InvalidEthereumSignature', 'InvalidNativeSignature', 'InvalidNativeAccount', 'SignerHasNoClaim', 'SenderHasNoClaim', 'PotUnderflow', 'InvalidStatement', 'VestedBalanceExists'] }, /** - * Lookup669: pallet_proxy::ProxyDefinition + * Lookup674: pallet_proxy::ProxyDefinition **/ PalletProxyProxyDefinition: { delegate: 'AccountId32', @@ -5551,7 +5591,7 @@ export default { delay: 'u64' }, /** - * Lookup673: pallet_proxy::Announcement + * Lookup678: pallet_proxy::Announcement **/ PalletProxyAnnouncement: { real: 'AccountId32', @@ -5559,13 +5599,13 @@ export default { height: 'u64' }, /** - * Lookup675: pallet_proxy::pallet::Error + * Lookup680: pallet_proxy::pallet::Error **/ PalletProxyError: { _enum: ['TooMany', 'NotFound', 'NotProxy', 'Unproxyable', 'Duplicate', 'NoPermission', 'Unannounced', 'NoSelfProxy'] }, /** - * Lookup676: pallet_multi_asset_delegation::types::operator::OperatorMetadata + * Lookup681: pallet_multi_asset_delegation::types::operator::OperatorMetadata **/ PalletMultiAssetDelegationOperatorOperatorMetadata: { stake: 'u128', @@ -5576,22 +5616,22 @@ export default { blueprintIds: 'Vec' }, /** - * Lookup677: tangle_testnet_runtime::MaxDelegations + * Lookup682: tangle_testnet_runtime::MaxDelegations **/ TangleTestnetRuntimeMaxDelegations: 'Null', /** - * Lookup678: tangle_testnet_runtime::MaxOperatorBlueprints + * Lookup683: tangle_testnet_runtime::MaxOperatorBlueprints **/ TangleTestnetRuntimeMaxOperatorBlueprints: 'Null', /** - * Lookup680: pallet_multi_asset_delegation::types::operator::OperatorBondLessRequest + * Lookup685: pallet_multi_asset_delegation::types::operator::OperatorBondLessRequest **/ PalletMultiAssetDelegationOperatorOperatorBondLessRequest: { amount: 'u128', requestTime: 'u32' }, /** - * Lookup682: pallet_multi_asset_delegation::types::operator::DelegatorBond + * Lookup687: pallet_multi_asset_delegation::types::operator::DelegatorBond **/ PalletMultiAssetDelegationOperatorDelegatorBond: { delegator: 'AccountId32', @@ -5599,7 +5639,7 @@ export default { assetId: 'TanglePrimitivesServicesAsset' }, /** - * Lookup684: pallet_multi_asset_delegation::types::operator::OperatorStatus + * Lookup689: pallet_multi_asset_delegation::types::operator::OperatorStatus **/ PalletMultiAssetDelegationOperatorOperatorStatus: { _enum: { @@ -5609,32 +5649,48 @@ export default { } }, /** - * Lookup686: pallet_multi_asset_delegation::types::operator::OperatorSnapshot + * Lookup691: pallet_multi_asset_delegation::types::operator::OperatorSnapshot **/ PalletMultiAssetDelegationOperatorOperatorSnapshot: { stake: 'u128', delegations: 'Vec' }, /** - * Lookup687: pallet_multi_asset_delegation::types::delegator::DelegatorMetadata + * Lookup692: pallet_multi_asset_delegation::types::delegator::DelegatorMetadata **/ PalletMultiAssetDelegationDelegatorDelegatorMetadata: { - deposits: 'BTreeMap', + deposits: 'BTreeMap', withdrawRequests: 'Vec', delegations: 'Vec', delegatorUnstakeRequests: 'Vec', status: 'PalletMultiAssetDelegationDelegatorDelegatorStatus' }, /** - * Lookup688: tangle_testnet_runtime::MaxWithdrawRequests + * Lookup693: tangle_testnet_runtime::MaxWithdrawRequests **/ TangleTestnetRuntimeMaxWithdrawRequests: 'Null', /** - * Lookup689: tangle_testnet_runtime::MaxUnstakeRequests + * Lookup694: tangle_testnet_runtime::MaxUnstakeRequests **/ TangleTestnetRuntimeMaxUnstakeRequests: 'Null', /** - * Lookup694: pallet_multi_asset_delegation::types::delegator::WithdrawRequest + * Lookup696: pallet_multi_asset_delegation::types::delegator::Deposit + **/ + PalletMultiAssetDelegationDelegatorDeposit: { + amount: 'u128', + delegatedAmount: 'u128', + locks: 'Option>' + }, + /** + * Lookup699: tangle_primitives::types::rewards::LockInfo + **/ + TanglePrimitivesRewardsLockInfo: { + amount: 'u128', + lockMultiplier: 'TanglePrimitivesRewardsLockMultiplier', + expiryBlock: 'u64' + }, + /** + * Lookup704: pallet_multi_asset_delegation::types::delegator::WithdrawRequest **/ PalletMultiAssetDelegationDelegatorWithdrawRequest: { assetId: 'TanglePrimitivesServicesAsset', @@ -5642,7 +5698,7 @@ export default { requestedRound: 'u32' }, /** - * Lookup697: pallet_multi_asset_delegation::types::delegator::BondInfoDelegator + * Lookup707: pallet_multi_asset_delegation::types::delegator::BondInfoDelegator **/ PalletMultiAssetDelegationDelegatorBondInfoDelegator: { operator: 'AccountId32', @@ -5651,7 +5707,7 @@ export default { blueprintSelection: 'PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection' }, /** - * Lookup700: pallet_multi_asset_delegation::types::delegator::BondLessRequest + * Lookup710: pallet_multi_asset_delegation::types::delegator::BondLessRequest **/ PalletMultiAssetDelegationDelegatorBondLessRequest: { operator: 'AccountId32', @@ -5661,7 +5717,7 @@ export default { blueprintSelection: 'PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection' }, /** - * Lookup702: pallet_multi_asset_delegation::types::delegator::DelegatorStatus + * Lookup712: pallet_multi_asset_delegation::types::delegator::DelegatorStatus **/ PalletMultiAssetDelegationDelegatorDelegatorStatus: { _enum: { @@ -5670,27 +5726,13 @@ export default { } }, /** - * Lookup704: pallet_multi_asset_delegation::types::rewards::RewardConfig - **/ - PalletMultiAssetDelegationRewardsRewardConfig: { - configs: 'BTreeMap', - whitelistedBlueprintIds: 'Vec' - }, - /** - * Lookup706: pallet_multi_asset_delegation::types::rewards::RewardConfigForAssetVault - **/ - PalletMultiAssetDelegationRewardsRewardConfigForAssetVault: { - apy: 'Percent', - cap: 'u128' - }, - /** - * Lookup709: pallet_multi_asset_delegation::pallet::Error + * Lookup713: pallet_multi_asset_delegation::pallet::Error **/ PalletMultiAssetDelegationError: { - _enum: ['AlreadyOperator', 'BondTooLow', 'NotAnOperator', 'CannotExit', 'AlreadyLeaving', 'NotLeavingOperator', 'NotLeavingRound', 'LeavingRoundNotReached', 'NoScheduledBondLess', 'BondLessRequestNotSatisfied', 'NotActiveOperator', 'NotOfflineOperator', 'AlreadyDelegator', 'NotDelegator', 'WithdrawRequestAlreadyExists', 'InsufficientBalance', 'NoWithdrawRequest', 'NoBondLessRequest', 'BondLessNotReady', 'BondLessRequestAlreadyExists', 'ActiveServicesUsingAsset', 'NoActiveDelegation', 'AssetNotWhitelisted', 'NotAuthorized', 'MaxBlueprintsExceeded', 'AssetNotFound', 'BlueprintAlreadyWhitelisted', 'NowithdrawRequests', 'NoMatchingwithdrawRequest', 'AssetAlreadyInVault', 'AssetNotInVault', 'VaultNotFound', 'DuplicateBlueprintId', 'BlueprintIdNotFound', 'NotInFixedMode', 'MaxDelegationsExceeded', 'MaxUnstakeRequestsExceeded', 'MaxWithdrawRequestsExceeded', 'DepositOverflow', 'UnstakeAmountTooLarge', 'StakeOverflow', 'InsufficientStakeRemaining', 'APYExceedsMaximum', 'CapCannotBeZero', 'CapExceedsTotalSupply', 'PendingUnstakeRequestExists', 'BlueprintNotSelected', 'ERC20TransferFailed', 'EVMAbiEncode', 'EVMAbiDecode'] + _enum: ['AlreadyOperator', 'BondTooLow', 'NotAnOperator', 'CannotExit', 'AlreadyLeaving', 'NotLeavingOperator', 'NotLeavingRound', 'LeavingRoundNotReached', 'NoScheduledBondLess', 'BondLessRequestNotSatisfied', 'NotActiveOperator', 'NotOfflineOperator', 'AlreadyDelegator', 'NotDelegator', 'WithdrawRequestAlreadyExists', 'InsufficientBalance', 'NoWithdrawRequest', 'NoBondLessRequest', 'BondLessNotReady', 'BondLessRequestAlreadyExists', 'ActiveServicesUsingAsset', 'NoActiveDelegation', 'AssetNotWhitelisted', 'NotAuthorized', 'MaxBlueprintsExceeded', 'AssetNotFound', 'BlueprintAlreadyWhitelisted', 'NowithdrawRequests', 'NoMatchingwithdrawRequest', 'AssetAlreadyInVault', 'AssetNotInVault', 'VaultNotFound', 'DuplicateBlueprintId', 'BlueprintIdNotFound', 'NotInFixedMode', 'MaxDelegationsExceeded', 'MaxUnstakeRequestsExceeded', 'MaxWithdrawRequestsExceeded', 'DepositOverflow', 'UnstakeAmountTooLarge', 'StakeOverflow', 'InsufficientStakeRemaining', 'APYExceedsMaximum', 'CapCannotBeZero', 'CapExceedsTotalSupply', 'PendingUnstakeRequestExists', 'BlueprintNotSelected', 'ERC20TransferFailed', 'EVMAbiEncode', 'EVMAbiDecode', 'LockViolation', 'DepositExceedsCapForAsset'] }, /** - * Lookup712: tangle_primitives::services::ServiceRequest + * Lookup716: tangle_primitives::services::ServiceRequest **/ TanglePrimitivesServicesServiceRequest: { blueprint: 'u64', @@ -5702,7 +5744,7 @@ export default { operatorsWithApprovalState: 'Vec<(AccountId32,TanglePrimitivesServicesApprovalState)>' }, /** - * Lookup718: tangle_primitives::services::ApprovalState + * Lookup722: tangle_primitives::services::ApprovalState **/ TanglePrimitivesServicesApprovalState: { _enum: { @@ -5714,7 +5756,7 @@ export default { } }, /** - * Lookup720: tangle_primitives::services::Service + * Lookup724: tangle_primitives::services::Service **/ TanglePrimitivesServicesService: { id: 'u64', @@ -5726,7 +5768,7 @@ export default { ttl: 'u64' }, /** - * Lookup726: tangle_primitives::services::JobCall + * Lookup730: tangle_primitives::services::JobCall **/ TanglePrimitivesServicesJobCall: { serviceId: 'u64', @@ -5734,7 +5776,7 @@ export default { args: 'Vec' }, /** - * Lookup727: tangle_primitives::services::JobCallResult + * Lookup731: tangle_primitives::services::JobCallResult **/ TanglePrimitivesServicesJobCallResult: { serviceId: 'u64', @@ -5742,7 +5784,7 @@ export default { result: 'Vec' }, /** - * Lookup728: pallet_services::types::UnappliedSlash + * Lookup732: pallet_services::types::UnappliedSlash **/ PalletServicesUnappliedSlash: { serviceId: 'u64', @@ -5753,14 +5795,14 @@ export default { payout: 'u128' }, /** - * Lookup730: tangle_primitives::services::OperatorProfile + * Lookup734: tangle_primitives::services::OperatorProfile **/ TanglePrimitivesServicesOperatorProfile: { services: 'BTreeSet', blueprints: 'BTreeSet' }, /** - * Lookup733: tangle_primitives::services::StagingServicePayment + * Lookup737: tangle_primitives::services::StagingServicePayment **/ TanglePrimitivesServicesStagingServicePayment: { requestId: 'u64', @@ -5769,7 +5811,7 @@ export default { amount: 'u128' }, /** - * Lookup734: tangle_primitives::types::Account + * Lookup738: tangle_primitives::types::Account **/ TanglePrimitivesAccount: { _enum: { @@ -5778,7 +5820,7 @@ export default { } }, /** - * Lookup735: pallet_services::module::Error + * Lookup739: pallet_services::module::Error **/ PalletServicesModuleError: { _enum: { @@ -5828,7 +5870,7 @@ export default { } }, /** - * Lookup736: tangle_primitives::services::TypeCheckError + * Lookup740: tangle_primitives::services::TypeCheckError **/ TanglePrimitivesServicesTypeCheckError: { _enum: { @@ -5849,7 +5891,7 @@ export default { } }, /** - * Lookup737: pallet_tangle_lst::types::bonded_pool::BondedPoolInner + * Lookup741: pallet_tangle_lst::types::bonded_pool::BondedPoolInner **/ PalletTangleLstBondedPoolBondedPoolInner: { commission: 'PalletTangleLstCommission', @@ -5858,7 +5900,7 @@ export default { metadata: 'PalletTangleLstBondedPoolPoolMetadata' }, /** - * Lookup738: pallet_tangle_lst::types::commission::Commission + * Lookup742: pallet_tangle_lst::types::commission::Commission **/ PalletTangleLstCommission: { current: 'Option<(Perbill,AccountId32)>', @@ -5868,7 +5910,7 @@ export default { claimPermission: 'Option' }, /** - * Lookup740: pallet_tangle_lst::types::pools::PoolRoles + * Lookup744: pallet_tangle_lst::types::pools::PoolRoles **/ PalletTangleLstPoolsPoolRoles: { depositor: 'AccountId32', @@ -5877,14 +5919,14 @@ export default { bouncer: 'Option' }, /** - * Lookup741: pallet_tangle_lst::types::bonded_pool::PoolMetadata + * Lookup745: pallet_tangle_lst::types::bonded_pool::PoolMetadata **/ PalletTangleLstBondedPoolPoolMetadata: { name: 'Option', icon: 'Option' }, /** - * Lookup742: pallet_tangle_lst::types::sub_pools::RewardPool + * Lookup746: pallet_tangle_lst::types::sub_pools::RewardPool **/ PalletTangleLstSubPoolsRewardPool: { lastRecordedRewardCounter: 'u128', @@ -5894,33 +5936,33 @@ export default { totalCommissionClaimed: 'u128' }, /** - * Lookup743: pallet_tangle_lst::types::sub_pools::SubPools + * Lookup747: pallet_tangle_lst::types::sub_pools::SubPools **/ PalletTangleLstSubPools: { noEra: 'PalletTangleLstSubPoolsUnbondPool', withEra: 'BTreeMap' }, /** - * Lookup744: pallet_tangle_lst::types::sub_pools::UnbondPool + * Lookup748: pallet_tangle_lst::types::sub_pools::UnbondPool **/ PalletTangleLstSubPoolsUnbondPool: { points: 'u128', balance: 'u128' }, /** - * Lookup750: pallet_tangle_lst::types::pools::PoolMember + * Lookup754: pallet_tangle_lst::types::pools::PoolMember **/ PalletTangleLstPoolsPoolMember: { unbondingEras: 'BTreeMap' }, /** - * Lookup755: pallet_tangle_lst::types::ClaimPermission + * Lookup759: pallet_tangle_lst::types::ClaimPermission **/ PalletTangleLstClaimPermission: { _enum: ['Permissioned', 'PermissionlessCompound', 'PermissionlessWithdraw', 'PermissionlessAll'] }, /** - * Lookup756: pallet_tangle_lst::pallet::Error + * Lookup760: pallet_tangle_lst::pallet::Error **/ PalletTangleLstError: { _enum: { @@ -5960,53 +6002,59 @@ export default { } }, /** - * Lookup757: pallet_tangle_lst::pallet::DefensiveError + * Lookup761: pallet_tangle_lst::pallet::DefensiveError **/ PalletTangleLstDefensiveError: { _enum: ['NotEnoughSpaceInUnbondPool', 'PoolNotFound', 'RewardPoolNotFound', 'SubPoolsNotFound', 'BondedStashKilledPrematurely'] }, /** - * Lookup760: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender + * Lookup765: pallet_rewards::pallet::Error + **/ + PalletRewardsError: { + _enum: ['NoRewardsAvailable', 'InsufficientRewardsBalance', 'AssetNotWhitelisted', 'AssetAlreadyWhitelisted', 'InvalidAPY', 'AssetAlreadyInVault', 'AssetNotInVault', 'VaultNotFound', 'DuplicateBlueprintId', 'BlueprintIdNotFound', 'RewardConfigNotFound', 'ArithmeticError'] + }, + /** + * Lookup768: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender **/ FrameSystemExtensionsCheckNonZeroSender: 'Null', /** - * Lookup761: frame_system::extensions::check_spec_version::CheckSpecVersion + * Lookup769: frame_system::extensions::check_spec_version::CheckSpecVersion **/ FrameSystemExtensionsCheckSpecVersion: 'Null', /** - * Lookup762: frame_system::extensions::check_tx_version::CheckTxVersion + * Lookup770: frame_system::extensions::check_tx_version::CheckTxVersion **/ FrameSystemExtensionsCheckTxVersion: 'Null', /** - * Lookup763: frame_system::extensions::check_genesis::CheckGenesis + * Lookup771: frame_system::extensions::check_genesis::CheckGenesis **/ FrameSystemExtensionsCheckGenesis: 'Null', /** - * Lookup766: frame_system::extensions::check_nonce::CheckNonce + * Lookup774: frame_system::extensions::check_nonce::CheckNonce **/ FrameSystemExtensionsCheckNonce: 'Compact', /** - * Lookup767: frame_system::extensions::check_weight::CheckWeight + * Lookup775: frame_system::extensions::check_weight::CheckWeight **/ FrameSystemExtensionsCheckWeight: 'Null', /** - * Lookup768: pallet_transaction_payment::ChargeTransactionPayment + * Lookup776: pallet_transaction_payment::ChargeTransactionPayment **/ PalletTransactionPaymentChargeTransactionPayment: 'Compact', /** - * Lookup769: frame_metadata_hash_extension::CheckMetadataHash + * Lookup777: frame_metadata_hash_extension::CheckMetadataHash **/ FrameMetadataHashExtensionCheckMetadataHash: { mode: 'FrameMetadataHashExtensionMode' }, /** - * Lookup770: frame_metadata_hash_extension::Mode + * Lookup778: frame_metadata_hash_extension::Mode **/ FrameMetadataHashExtensionMode: { _enum: ['Disabled', 'Enabled'] }, /** - * Lookup772: tangle_testnet_runtime::Runtime + * Lookup780: tangle_testnet_runtime::Runtime **/ TangleTestnetRuntimeRuntime: 'Null' }; diff --git a/types/src/interfaces/registry.ts b/types/src/interfaces/registry.ts index b821e16c..849527d2 100644 --- a/types/src/interfaces/registry.ts +++ b/types/src/interfaces/registry.ts @@ -5,7 +5,7 @@ // this is required to allow for ambient/previous definitions import '@polkadot/types/types/registry'; -import type { EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FinalityGrandpaEquivocationPrecommit, FinalityGrandpaEquivocationPrevote, FinalityGrandpaPrecommit, FinalityGrandpaPrevote, FpRpcTransactionStatus, FrameMetadataHashExtensionCheckMetadataHash, FrameMetadataHashExtensionMode, FrameSupportDispatchDispatchClass, FrameSupportDispatchDispatchInfo, FrameSupportDispatchPays, FrameSupportDispatchPerDispatchClassU32, FrameSupportDispatchPerDispatchClassWeight, FrameSupportDispatchPerDispatchClassWeightsPerClass, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportPreimagesBounded, FrameSupportTokensMiscBalanceStatus, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCall, FrameSystemCodeUpgradeAuthorization, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonZeroSender, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckTxVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, PalletAirdropClaimsCall, PalletAirdropClaimsError, PalletAirdropClaimsEvent, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsEthereumAddress, PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletAirdropClaimsUtilsSr25519Signature, PalletAssetsAccountStatus, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAssetsAssetStatus, PalletAssetsCall, PalletAssetsError, PalletAssetsEvent, PalletAssetsExistenceReason, PalletBabeCall, PalletBabeError, PalletBagsListCall, PalletBagsListError, PalletBagsListEvent, PalletBagsListListBag, PalletBagsListListListError, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesAdjustmentDirection, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReserveData, PalletBaseFeeCall, PalletBaseFeeEvent, PalletBountiesBounty, PalletBountiesBountyStatus, PalletBountiesCall, PalletBountiesError, PalletBountiesEvent, PalletChildBountiesCall, PalletChildBountiesChildBounty, PalletChildBountiesChildBountyStatus, PalletChildBountiesError, PalletChildBountiesEvent, PalletCollectiveCall, PalletCollectiveError, PalletCollectiveEvent, PalletCollectiveRawOrigin, PalletCollectiveVotes, PalletDemocracyCall, PalletDemocracyConviction, PalletDemocracyDelegations, PalletDemocracyError, PalletDemocracyEvent, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyTally, PalletDemocracyVoteAccountVote, PalletDemocracyVotePriorLock, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletDynamicFeeCall, PalletElectionProviderMultiPhaseCall, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhaseError, PalletElectionProviderMultiPhaseEvent, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenCall, PalletElectionsPhragmenError, PalletElectionsPhragmenEvent, PalletElectionsPhragmenRenouncing, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumRawOrigin, PalletEvmCall, PalletEvmCodeMetadata, PalletEvmError, PalletEvmEvent, PalletGrandpaCall, PalletGrandpaError, PalletGrandpaEvent, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletHotfixSufficientsCall, PalletHotfixSufficientsError, PalletIdentityAuthorityProperties, PalletIdentityCall, PalletIdentityError, PalletIdentityEvent, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineCall, PalletImOnlineError, PalletImOnlineEvent, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Public, PalletImOnlineSr25519AppSr25519Signature, PalletIndicesCall, PalletIndicesError, PalletIndicesEvent, PalletMultiAssetDelegationCall, PalletMultiAssetDelegationDelegatorBondInfoDelegator, PalletMultiAssetDelegationDelegatorBondLessRequest, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationDelegatorDelegatorStatus, PalletMultiAssetDelegationDelegatorWithdrawRequest, PalletMultiAssetDelegationError, PalletMultiAssetDelegationEvent, PalletMultiAssetDelegationOperatorDelegatorBond, PalletMultiAssetDelegationOperatorOperatorBondLessRequest, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationOperatorOperatorStatus, PalletMultiAssetDelegationRewardsAssetAction, PalletMultiAssetDelegationRewardsRewardConfig, PalletMultiAssetDelegationRewardsRewardConfigForAssetVault, PalletMultisigCall, PalletMultisigError, PalletMultisigEvent, PalletMultisigMultisig, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsCall, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsDefensiveError, PalletNominationPoolsError, PalletNominationPoolsEvent, PalletNominationPoolsFreezeReason, PalletNominationPoolsPoolMember, PalletNominationPoolsPoolRoles, PalletNominationPoolsPoolState, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletNominationPoolsUnbondPool, PalletOffencesEvent, PalletPreimageCall, PalletPreimageError, PalletPreimageEvent, PalletPreimageHoldReason, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyCall, PalletProxyError, PalletProxyEvent, PalletProxyProxyDefinition, PalletSchedulerCall, PalletSchedulerError, PalletSchedulerEvent, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesModuleCall, PalletServicesModuleError, PalletServicesModuleEvent, PalletServicesUnappliedSlash, PalletSessionCall, PalletSessionError, PalletSessionEvent, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingPalletCall, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingPalletError, PalletStakingPalletEvent, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTangleLstBondExtra, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstBondedPoolPoolMetadata, PalletTangleLstCall, PalletTangleLstClaimPermission, PalletTangleLstCommission, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstDefensiveError, PalletTangleLstError, PalletTangleLstEvent, PalletTangleLstFreezeReason, PalletTangleLstPoolsPoolMember, PalletTangleLstPoolsPoolRoles, PalletTangleLstPoolsPoolState, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTangleLstSubPoolsUnbondPool, PalletTimestampCall, PalletTransactionPaymentChargeTransactionPayment, PalletTransactionPaymentEvent, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryPaymentState, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletTxPauseCall, PalletTxPauseError, PalletTxPauseEvent, PalletUtilityCall, PalletUtilityError, PalletUtilityEvent, PalletVestingCall, PalletVestingError, PalletVestingEvent, PalletVestingReleases, PalletVestingVestingInfo, SpArithmeticArithmeticError, SpConsensusBabeAllowedSlots, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusBabeDigestsPrimaryPreDigest, SpConsensusBabeDigestsSecondaryPlainPreDigest, SpConsensusBabeDigestsSecondaryVRFPreDigest, SpConsensusGrandpaAppPublic, SpConsensusGrandpaAppSignature, SpConsensusGrandpaEquivocation, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreCryptoKeyTypeId, SpCoreSr25519VrfVrfSignature, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeBlakeTwo256, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeHeader, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpSessionMembershipProof, SpStakingExposure, SpStakingExposurePage, SpStakingIndividualExposure, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, SpVersionRuntimeVersion, SpWeightsRuntimeDbWeight, SpWeightsWeightV2Weight, TanglePrimitivesAccount, TanglePrimitivesServicesApprovalState, TanglePrimitivesServicesArchitecture, TanglePrimitivesServicesAsset, TanglePrimitivesServicesBlueprintServiceManager, TanglePrimitivesServicesContainerGadget, TanglePrimitivesServicesField, TanglePrimitivesServicesFieldFieldType, TanglePrimitivesServicesGadget, TanglePrimitivesServicesGadgetBinary, TanglePrimitivesServicesGadgetSource, TanglePrimitivesServicesGadgetSourceFetcher, TanglePrimitivesServicesGithubFetcher, TanglePrimitivesServicesImageRegistryFetcher, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesJobDefinition, TanglePrimitivesServicesJobMetadata, TanglePrimitivesServicesMasterBlueprintServiceManagerRevision, TanglePrimitivesServicesNativeGadget, TanglePrimitivesServicesOperatingSystem, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceMetadata, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TanglePrimitivesServicesTestFetcher, TanglePrimitivesServicesTypeCheckError, TanglePrimitivesServicesWasmGadget, TanglePrimitivesServicesWasmRuntime, TangleTestnetRuntimeMaxDelegations, TangleTestnetRuntimeMaxDelegatorBlueprints, TangleTestnetRuntimeMaxOperatorBlueprints, TangleTestnetRuntimeMaxUnstakeRequests, TangleTestnetRuntimeMaxWithdrawRequests, TangleTestnetRuntimeNposSolution16, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType, TangleTestnetRuntimeRuntime, TangleTestnetRuntimeRuntimeFreezeReason, TangleTestnetRuntimeRuntimeHoldReason } from '@polkadot/types/lookup'; +import type { EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FinalityGrandpaEquivocationPrecommit, FinalityGrandpaEquivocationPrevote, FinalityGrandpaPrecommit, FinalityGrandpaPrevote, FpRpcTransactionStatus, FrameMetadataHashExtensionCheckMetadataHash, FrameMetadataHashExtensionMode, FrameSupportDispatchDispatchClass, FrameSupportDispatchDispatchInfo, FrameSupportDispatchPays, FrameSupportDispatchPerDispatchClassU32, FrameSupportDispatchPerDispatchClassWeight, FrameSupportDispatchPerDispatchClassWeightsPerClass, FrameSupportDispatchRawOrigin, FrameSupportPalletId, FrameSupportPreimagesBounded, FrameSupportTokensMiscBalanceStatus, FrameSupportTokensMiscIdAmountRuntimeFreezeReason, FrameSupportTokensMiscIdAmountRuntimeHoldReason, FrameSystemAccountInfo, FrameSystemCall, FrameSystemCodeUpgradeAuthorization, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonZeroSender, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckTxVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, PalletAirdropClaimsCall, PalletAirdropClaimsError, PalletAirdropClaimsEvent, PalletAirdropClaimsStatementKind, PalletAirdropClaimsUtilsEthereumAddress, PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature, PalletAirdropClaimsUtilsMultiAddress, PalletAirdropClaimsUtilsMultiAddressSignature, PalletAirdropClaimsUtilsSr25519Signature, PalletAssetsAccountStatus, PalletAssetsApproval, PalletAssetsAssetAccount, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAssetsAssetStatus, PalletAssetsCall, PalletAssetsError, PalletAssetsEvent, PalletAssetsExistenceReason, PalletBabeCall, PalletBabeError, PalletBagsListCall, PalletBagsListError, PalletBagsListEvent, PalletBagsListListBag, PalletBagsListListListError, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesAdjustmentDirection, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReserveData, PalletBaseFeeCall, PalletBaseFeeEvent, PalletBountiesBounty, PalletBountiesBountyStatus, PalletBountiesCall, PalletBountiesError, PalletBountiesEvent, PalletChildBountiesCall, PalletChildBountiesChildBounty, PalletChildBountiesChildBountyStatus, PalletChildBountiesError, PalletChildBountiesEvent, PalletCollectiveCall, PalletCollectiveError, PalletCollectiveEvent, PalletCollectiveRawOrigin, PalletCollectiveVotes, PalletDemocracyCall, PalletDemocracyConviction, PalletDemocracyDelegations, PalletDemocracyError, PalletDemocracyEvent, PalletDemocracyMetadataOwner, PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyTally, PalletDemocracyVoteAccountVote, PalletDemocracyVotePriorLock, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletDynamicFeeCall, PalletElectionProviderMultiPhaseCall, PalletElectionProviderMultiPhaseElectionCompute, PalletElectionProviderMultiPhaseError, PalletElectionProviderMultiPhaseEvent, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenCall, PalletElectionsPhragmenError, PalletElectionsPhragmenEvent, PalletElectionsPhragmenRenouncing, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumRawOrigin, PalletEvmCall, PalletEvmCodeMetadata, PalletEvmError, PalletEvmEvent, PalletGrandpaCall, PalletGrandpaError, PalletGrandpaEvent, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletHotfixSufficientsCall, PalletHotfixSufficientsError, PalletIdentityAuthorityProperties, PalletIdentityCall, PalletIdentityError, PalletIdentityEvent, PalletIdentityJudgement, PalletIdentityLegacyIdentityInfo, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineCall, PalletImOnlineError, PalletImOnlineEvent, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Public, PalletImOnlineSr25519AppSr25519Signature, PalletIndicesCall, PalletIndicesError, PalletIndicesEvent, PalletMultiAssetDelegationCall, PalletMultiAssetDelegationDelegatorBondInfoDelegator, PalletMultiAssetDelegationDelegatorBondLessRequest, PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection, PalletMultiAssetDelegationDelegatorDelegatorMetadata, PalletMultiAssetDelegationDelegatorDelegatorStatus, PalletMultiAssetDelegationDelegatorDeposit, PalletMultiAssetDelegationDelegatorWithdrawRequest, PalletMultiAssetDelegationError, PalletMultiAssetDelegationEvent, PalletMultiAssetDelegationOperatorDelegatorBond, PalletMultiAssetDelegationOperatorOperatorBondLessRequest, PalletMultiAssetDelegationOperatorOperatorMetadata, PalletMultiAssetDelegationOperatorOperatorSnapshot, PalletMultiAssetDelegationOperatorOperatorStatus, PalletMultisigCall, PalletMultisigError, PalletMultisigEvent, PalletMultisigMultisig, PalletMultisigTimepoint, PalletNominationPoolsBondExtra, PalletNominationPoolsBondedPoolInner, PalletNominationPoolsCall, PalletNominationPoolsClaimPermission, PalletNominationPoolsCommission, PalletNominationPoolsCommissionChangeRate, PalletNominationPoolsCommissionClaimPermission, PalletNominationPoolsConfigOpAccountId32, PalletNominationPoolsConfigOpPerbill, PalletNominationPoolsConfigOpU128, PalletNominationPoolsConfigOpU32, PalletNominationPoolsDefensiveError, PalletNominationPoolsError, PalletNominationPoolsEvent, PalletNominationPoolsFreezeReason, PalletNominationPoolsPoolMember, PalletNominationPoolsPoolRoles, PalletNominationPoolsPoolState, PalletNominationPoolsRewardPool, PalletNominationPoolsSubPools, PalletNominationPoolsUnbondPool, PalletOffencesEvent, PalletPreimageCall, PalletPreimageError, PalletPreimageEvent, PalletPreimageHoldReason, PalletPreimageOldRequestStatus, PalletPreimageRequestStatus, PalletProxyAnnouncement, PalletProxyCall, PalletProxyError, PalletProxyEvent, PalletProxyProxyDefinition, PalletRewardsAssetAction, PalletRewardsCall, PalletRewardsError, PalletRewardsEvent, PalletRewardsRewardConfigForAssetVault, PalletSchedulerCall, PalletSchedulerError, PalletSchedulerEvent, PalletSchedulerRetryConfig, PalletSchedulerScheduled, PalletServicesModuleCall, PalletServicesModuleError, PalletServicesModuleEvent, PalletServicesUnappliedSlash, PalletSessionCall, PalletSessionError, PalletSessionEvent, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingForcing, PalletStakingNominations, PalletStakingPalletCall, PalletStakingPalletConfigOpPerbill, PalletStakingPalletConfigOpPercent, PalletStakingPalletConfigOpU128, PalletStakingPalletConfigOpU32, PalletStakingPalletError, PalletStakingPalletEvent, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingUnlockChunk, PalletStakingValidatorPrefs, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTangleLstBondExtra, PalletTangleLstBondedPoolBondedPoolInner, PalletTangleLstBondedPoolPoolMetadata, PalletTangleLstCall, PalletTangleLstClaimPermission, PalletTangleLstCommission, PalletTangleLstCommissionCommissionChangeRate, PalletTangleLstCommissionCommissionClaimPermission, PalletTangleLstConfigOpAccountId32, PalletTangleLstConfigOpPerbill, PalletTangleLstConfigOpU128, PalletTangleLstConfigOpU32, PalletTangleLstDefensiveError, PalletTangleLstError, PalletTangleLstEvent, PalletTangleLstFreezeReason, PalletTangleLstPoolsPoolMember, PalletTangleLstPoolsPoolRoles, PalletTangleLstPoolsPoolState, PalletTangleLstSubPools, PalletTangleLstSubPoolsRewardPool, PalletTangleLstSubPoolsUnbondPool, PalletTimestampCall, PalletTransactionPaymentChargeTransactionPayment, PalletTransactionPaymentEvent, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryPaymentState, PalletTreasuryProposal, PalletTreasurySpendStatus, PalletTxPauseCall, PalletTxPauseError, PalletTxPauseEvent, PalletUtilityCall, PalletUtilityError, PalletUtilityEvent, PalletVestingCall, PalletVestingError, PalletVestingEvent, PalletVestingReleases, PalletVestingVestingInfo, SpArithmeticArithmeticError, SpConsensusBabeAllowedSlots, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusBabeDigestsPreDigest, SpConsensusBabeDigestsPrimaryPreDigest, SpConsensusBabeDigestsSecondaryPlainPreDigest, SpConsensusBabeDigestsSecondaryVRFPreDigest, SpConsensusGrandpaAppPublic, SpConsensusGrandpaAppSignature, SpConsensusGrandpaEquivocation, SpConsensusGrandpaEquivocationProof, SpConsensusSlotsEquivocationProof, SpCoreCryptoKeyTypeId, SpCoreSr25519VrfVrfSignature, SpCoreVoid, SpNposElectionsElectionScore, SpNposElectionsSupport, SpRuntimeBlakeTwo256, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeHeader, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpSessionMembershipProof, SpStakingExposure, SpStakingExposurePage, SpStakingIndividualExposure, SpStakingOffenceOffenceDetails, SpStakingPagedExposureMetadata, SpVersionRuntimeVersion, SpWeightsRuntimeDbWeight, SpWeightsWeightV2Weight, TanglePrimitivesAccount, TanglePrimitivesRewardsLockInfo, TanglePrimitivesRewardsLockMultiplier, TanglePrimitivesServicesApprovalState, TanglePrimitivesServicesArchitecture, TanglePrimitivesServicesAsset, TanglePrimitivesServicesBlueprintServiceManager, TanglePrimitivesServicesContainerGadget, TanglePrimitivesServicesField, TanglePrimitivesServicesFieldFieldType, TanglePrimitivesServicesGadget, TanglePrimitivesServicesGadgetBinary, TanglePrimitivesServicesGadgetSource, TanglePrimitivesServicesGadgetSourceFetcher, TanglePrimitivesServicesGithubFetcher, TanglePrimitivesServicesImageRegistryFetcher, TanglePrimitivesServicesJobCall, TanglePrimitivesServicesJobCallResult, TanglePrimitivesServicesJobDefinition, TanglePrimitivesServicesJobMetadata, TanglePrimitivesServicesMasterBlueprintServiceManagerRevision, TanglePrimitivesServicesNativeGadget, TanglePrimitivesServicesOperatingSystem, TanglePrimitivesServicesOperatorPreferences, TanglePrimitivesServicesOperatorProfile, TanglePrimitivesServicesPriceTargets, TanglePrimitivesServicesService, TanglePrimitivesServicesServiceBlueprint, TanglePrimitivesServicesServiceMetadata, TanglePrimitivesServicesServiceRequest, TanglePrimitivesServicesStagingServicePayment, TanglePrimitivesServicesTestFetcher, TanglePrimitivesServicesTypeCheckError, TanglePrimitivesServicesWasmGadget, TanglePrimitivesServicesWasmRuntime, TangleTestnetRuntimeMaxDelegations, TangleTestnetRuntimeMaxDelegatorBlueprints, TangleTestnetRuntimeMaxOperatorBlueprints, TangleTestnetRuntimeMaxUnstakeRequests, TangleTestnetRuntimeMaxWithdrawRequests, TangleTestnetRuntimeNposSolution16, TangleTestnetRuntimeOpaqueSessionKeys, TangleTestnetRuntimeOriginCaller, TangleTestnetRuntimeProxyType, TangleTestnetRuntimeRuntime, TangleTestnetRuntimeRuntimeFreezeReason, TangleTestnetRuntimeRuntimeHoldReason } from '@polkadot/types/lookup'; declare module '@polkadot/types/types/registry' { interface InterfaceTypes { @@ -184,6 +184,7 @@ declare module '@polkadot/types/types/registry' { PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; PalletMultiAssetDelegationDelegatorDelegatorMetadata: PalletMultiAssetDelegationDelegatorDelegatorMetadata; PalletMultiAssetDelegationDelegatorDelegatorStatus: PalletMultiAssetDelegationDelegatorDelegatorStatus; + PalletMultiAssetDelegationDelegatorDeposit: PalletMultiAssetDelegationDelegatorDeposit; PalletMultiAssetDelegationDelegatorWithdrawRequest: PalletMultiAssetDelegationDelegatorWithdrawRequest; PalletMultiAssetDelegationError: PalletMultiAssetDelegationError; PalletMultiAssetDelegationEvent: PalletMultiAssetDelegationEvent; @@ -192,9 +193,6 @@ declare module '@polkadot/types/types/registry' { PalletMultiAssetDelegationOperatorOperatorMetadata: PalletMultiAssetDelegationOperatorOperatorMetadata; PalletMultiAssetDelegationOperatorOperatorSnapshot: PalletMultiAssetDelegationOperatorOperatorSnapshot; PalletMultiAssetDelegationOperatorOperatorStatus: PalletMultiAssetDelegationOperatorOperatorStatus; - PalletMultiAssetDelegationRewardsAssetAction: PalletMultiAssetDelegationRewardsAssetAction; - PalletMultiAssetDelegationRewardsRewardConfig: PalletMultiAssetDelegationRewardsRewardConfig; - PalletMultiAssetDelegationRewardsRewardConfigForAssetVault: PalletMultiAssetDelegationRewardsRewardConfigForAssetVault; PalletMultisigCall: PalletMultisigCall; PalletMultisigError: PalletMultisigError; PalletMultisigEvent: PalletMultisigEvent; @@ -233,6 +231,11 @@ declare module '@polkadot/types/types/registry' { PalletProxyError: PalletProxyError; PalletProxyEvent: PalletProxyEvent; PalletProxyProxyDefinition: PalletProxyProxyDefinition; + PalletRewardsAssetAction: PalletRewardsAssetAction; + PalletRewardsCall: PalletRewardsCall; + PalletRewardsError: PalletRewardsError; + PalletRewardsEvent: PalletRewardsEvent; + PalletRewardsRewardConfigForAssetVault: PalletRewardsRewardConfigForAssetVault; PalletSchedulerCall: PalletSchedulerCall; PalletSchedulerError: PalletSchedulerError; PalletSchedulerEvent: PalletSchedulerEvent; @@ -347,6 +350,8 @@ declare module '@polkadot/types/types/registry' { SpWeightsRuntimeDbWeight: SpWeightsRuntimeDbWeight; SpWeightsWeightV2Weight: SpWeightsWeightV2Weight; TanglePrimitivesAccount: TanglePrimitivesAccount; + TanglePrimitivesRewardsLockInfo: TanglePrimitivesRewardsLockInfo; + TanglePrimitivesRewardsLockMultiplier: TanglePrimitivesRewardsLockMultiplier; TanglePrimitivesServicesApprovalState: TanglePrimitivesServicesApprovalState; TanglePrimitivesServicesArchitecture: TanglePrimitivesServicesArchitecture; TanglePrimitivesServicesAsset: TanglePrimitivesServicesAsset; diff --git a/types/src/interfaces/types-lookup.ts b/types/src/interfaces/types-lookup.ts index 9e57db66..65a4f0eb 100644 --- a/types/src/interfaces/types-lookup.ts +++ b/types/src/interfaces/types-lookup.ts @@ -1736,23 +1736,6 @@ declare module '@polkadot/types/lookup' { readonly asCancelledDelegatorBondLess: { readonly who: AccountId32; } & Struct; - readonly isIncentiveAPYAndCapSet: boolean; - readonly asIncentiveAPYAndCapSet: { - readonly vaultId: u128; - readonly apy: Percent; - readonly cap: u128; - } & Struct; - readonly isBlueprintWhitelisted: boolean; - readonly asBlueprintWhitelisted: { - readonly blueprintId: u64; - } & Struct; - readonly isAssetUpdatedInVault: boolean; - readonly asAssetUpdatedInVault: { - readonly who: AccountId32; - readonly vaultId: u128; - readonly assetId: TanglePrimitivesServicesAsset; - readonly action: PalletMultiAssetDelegationRewardsAssetAction; - } & Struct; readonly isOperatorSlashed: boolean; readonly asOperatorSlashed: { readonly who: AccountId32; @@ -1770,7 +1753,7 @@ declare module '@polkadot/types/lookup' { readonly data: Bytes; readonly reason: Bytes; } & Struct; - readonly type: 'OperatorJoined' | 'OperatorLeavingScheduled' | 'OperatorLeaveCancelled' | 'OperatorLeaveExecuted' | 'OperatorBondMore' | 'OperatorBondLessScheduled' | 'OperatorBondLessExecuted' | 'OperatorBondLessCancelled' | 'OperatorWentOffline' | 'OperatorWentOnline' | 'Deposited' | 'Scheduledwithdraw' | 'Executedwithdraw' | 'Cancelledwithdraw' | 'Delegated' | 'ScheduledDelegatorBondLess' | 'ExecutedDelegatorBondLess' | 'CancelledDelegatorBondLess' | 'IncentiveAPYAndCapSet' | 'BlueprintWhitelisted' | 'AssetUpdatedInVault' | 'OperatorSlashed' | 'DelegatorSlashed' | 'EvmReverted'; + readonly type: 'OperatorJoined' | 'OperatorLeavingScheduled' | 'OperatorLeaveCancelled' | 'OperatorLeaveExecuted' | 'OperatorBondMore' | 'OperatorBondLessScheduled' | 'OperatorBondLessExecuted' | 'OperatorBondLessCancelled' | 'OperatorWentOffline' | 'OperatorWentOnline' | 'Deposited' | 'Scheduledwithdraw' | 'Executedwithdraw' | 'Cancelledwithdraw' | 'Delegated' | 'ScheduledDelegatorBondLess' | 'ExecutedDelegatorBondLess' | 'CancelledDelegatorBondLess' | 'OperatorSlashed' | 'DelegatorSlashed' | 'EvmReverted'; } /** @name TanglePrimitivesServicesAsset (124) */ @@ -1782,14 +1765,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Custom' | 'Erc20'; } - /** @name PalletMultiAssetDelegationRewardsAssetAction (126) */ - interface PalletMultiAssetDelegationRewardsAssetAction extends Enum { - readonly isAdd: boolean; - readonly isRemove: boolean; - readonly type: 'Add' | 'Remove'; - } - - /** @name PalletServicesModuleEvent (127) */ + /** @name PalletServicesModuleEvent (125) */ interface PalletServicesModuleEvent extends Enum { readonly isBlueprintCreated: boolean; readonly asBlueprintCreated: { @@ -1905,13 +1881,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'BlueprintCreated' | 'PreRegistration' | 'Registered' | 'Unregistered' | 'PriceTargetsUpdated' | 'ServiceRequested' | 'ServiceRequestApproved' | 'ServiceRequestRejected' | 'ServiceInitiated' | 'ServiceTerminated' | 'JobCalled' | 'JobResultSubmitted' | 'EvmReverted' | 'UnappliedSlash' | 'SlashDiscarded' | 'MasterBlueprintServiceManagerRevised'; } - /** @name TanglePrimitivesServicesOperatorPreferences (128) */ + /** @name TanglePrimitivesServicesOperatorPreferences (126) */ interface TanglePrimitivesServicesOperatorPreferences extends Struct { readonly key: U8aFixed; readonly priceTargets: TanglePrimitivesServicesPriceTargets; } - /** @name TanglePrimitivesServicesPriceTargets (130) */ + /** @name TanglePrimitivesServicesPriceTargets (128) */ interface TanglePrimitivesServicesPriceTargets extends Struct { readonly cpu: u64; readonly mem: u64; @@ -1920,7 +1896,7 @@ declare module '@polkadot/types/lookup' { readonly storageNvme: u64; } - /** @name TanglePrimitivesServicesField (132) */ + /** @name TanglePrimitivesServicesField (130) */ interface TanglePrimitivesServicesField extends Enum { readonly isNone: boolean; readonly isBool: boolean; @@ -1956,7 +1932,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'None' | 'Bool' | 'Uint8' | 'Int8' | 'Uint16' | 'Int16' | 'Uint32' | 'Int32' | 'Uint64' | 'Int64' | 'String' | 'Bytes' | 'Array' | 'List' | 'Struct' | 'AccountId'; } - /** @name PalletTangleLstEvent (145) */ + /** @name PalletTangleLstEvent (143) */ interface PalletTangleLstEvent extends Enum { readonly isCreated: boolean; readonly asCreated: { @@ -2060,7 +2036,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Created' | 'Bonded' | 'PaidOut' | 'Unbonded' | 'Withdrawn' | 'Destroyed' | 'StateChanged' | 'MemberRemoved' | 'RolesUpdated' | 'PoolSlashed' | 'UnbondingPoolSlashed' | 'PoolCommissionUpdated' | 'PoolMaxCommissionUpdated' | 'PoolCommissionChangeRateUpdated' | 'PoolCommissionClaimPermissionUpdated' | 'PoolCommissionClaimed' | 'MinBalanceDeficitAdjusted' | 'MinBalanceExcessAdjusted'; } - /** @name PalletTangleLstPoolsPoolState (146) */ + /** @name PalletTangleLstPoolsPoolState (144) */ interface PalletTangleLstPoolsPoolState extends Enum { readonly isOpen: boolean; readonly isBlocked: boolean; @@ -2068,13 +2044,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Open' | 'Blocked' | 'Destroying'; } - /** @name PalletTangleLstCommissionCommissionChangeRate (147) */ + /** @name PalletTangleLstCommissionCommissionChangeRate (145) */ interface PalletTangleLstCommissionCommissionChangeRate extends Struct { readonly maxIncrease: Perbill; readonly minDelay: u64; } - /** @name PalletTangleLstCommissionCommissionClaimPermission (149) */ + /** @name PalletTangleLstCommissionCommissionClaimPermission (147) */ interface PalletTangleLstCommissionCommissionClaimPermission extends Enum { readonly isPermissionless: boolean; readonly isAccount: boolean; @@ -2082,7 +2058,45 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissionless' | 'Account'; } - /** @name FrameSystemPhase (150) */ + /** @name PalletRewardsEvent (148) */ + interface PalletRewardsEvent extends Enum { + readonly isRewardsClaimed: boolean; + readonly asRewardsClaimed: { + readonly account: AccountId32; + readonly asset: TanglePrimitivesServicesAsset; + readonly amount: u128; + } & Struct; + readonly isIncentiveAPYAndCapSet: boolean; + readonly asIncentiveAPYAndCapSet: { + readonly vaultId: u32; + readonly apy: Percent; + readonly cap: u128; + } & Struct; + readonly isBlueprintWhitelisted: boolean; + readonly asBlueprintWhitelisted: { + readonly blueprintId: u64; + } & Struct; + readonly isAssetUpdatedInVault: boolean; + readonly asAssetUpdatedInVault: { + readonly vaultId: u32; + readonly assetId: TanglePrimitivesServicesAsset; + readonly action: PalletRewardsAssetAction; + } & Struct; + readonly isVaultRewardConfigUpdated: boolean; + readonly asVaultRewardConfigUpdated: { + readonly vaultId: u32; + } & Struct; + readonly type: 'RewardsClaimed' | 'IncentiveAPYAndCapSet' | 'BlueprintWhitelisted' | 'AssetUpdatedInVault' | 'VaultRewardConfigUpdated'; + } + + /** @name PalletRewardsAssetAction (150) */ + interface PalletRewardsAssetAction extends Enum { + readonly isAdd: boolean; + readonly isRemove: boolean; + readonly type: 'Add' | 'Remove'; + } + + /** @name FrameSystemPhase (151) */ interface FrameSystemPhase extends Enum { readonly isApplyExtrinsic: boolean; readonly asApplyExtrinsic: u32; @@ -2091,19 +2105,19 @@ declare module '@polkadot/types/lookup' { readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization'; } - /** @name FrameSystemLastRuntimeUpgradeInfo (152) */ + /** @name FrameSystemLastRuntimeUpgradeInfo (153) */ interface FrameSystemLastRuntimeUpgradeInfo extends Struct { readonly specVersion: Compact; readonly specName: Text; } - /** @name FrameSystemCodeUpgradeAuthorization (154) */ + /** @name FrameSystemCodeUpgradeAuthorization (155) */ interface FrameSystemCodeUpgradeAuthorization extends Struct { readonly codeHash: H256; readonly checkVersion: bool; } - /** @name FrameSystemCall (155) */ + /** @name FrameSystemCall (156) */ interface FrameSystemCall extends Enum { readonly isRemark: boolean; readonly asRemark: { @@ -2153,21 +2167,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent' | 'AuthorizeUpgrade' | 'AuthorizeUpgradeWithoutChecks' | 'ApplyAuthorizedUpgrade'; } - /** @name FrameSystemLimitsBlockWeights (159) */ + /** @name FrameSystemLimitsBlockWeights (160) */ interface FrameSystemLimitsBlockWeights extends Struct { readonly baseBlock: SpWeightsWeightV2Weight; readonly maxBlock: SpWeightsWeightV2Weight; readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass; } - /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (160) */ + /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (161) */ interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct { readonly normal: FrameSystemLimitsWeightsPerClass; readonly operational: FrameSystemLimitsWeightsPerClass; readonly mandatory: FrameSystemLimitsWeightsPerClass; } - /** @name FrameSystemLimitsWeightsPerClass (161) */ + /** @name FrameSystemLimitsWeightsPerClass (162) */ interface FrameSystemLimitsWeightsPerClass extends Struct { readonly baseExtrinsic: SpWeightsWeightV2Weight; readonly maxExtrinsic: Option; @@ -2175,25 +2189,25 @@ declare module '@polkadot/types/lookup' { readonly reserved: Option; } - /** @name FrameSystemLimitsBlockLength (163) */ + /** @name FrameSystemLimitsBlockLength (164) */ interface FrameSystemLimitsBlockLength extends Struct { readonly max: FrameSupportDispatchPerDispatchClassU32; } - /** @name FrameSupportDispatchPerDispatchClassU32 (164) */ + /** @name FrameSupportDispatchPerDispatchClassU32 (165) */ interface FrameSupportDispatchPerDispatchClassU32 extends Struct { readonly normal: u32; readonly operational: u32; readonly mandatory: u32; } - /** @name SpWeightsRuntimeDbWeight (165) */ + /** @name SpWeightsRuntimeDbWeight (166) */ interface SpWeightsRuntimeDbWeight extends Struct { readonly read: u64; readonly write: u64; } - /** @name SpVersionRuntimeVersion (166) */ + /** @name SpVersionRuntimeVersion (167) */ interface SpVersionRuntimeVersion extends Struct { readonly specName: Text; readonly implName: Text; @@ -2205,7 +2219,7 @@ declare module '@polkadot/types/lookup' { readonly stateVersion: u8; } - /** @name FrameSystemError (171) */ + /** @name FrameSystemError (172) */ interface FrameSystemError extends Enum { readonly isInvalidSpecName: boolean; readonly isSpecVersionNeedsToIncrease: boolean; @@ -2219,7 +2233,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered' | 'MultiBlockMigrationsOngoing' | 'NothingAuthorized' | 'Unauthorized'; } - /** @name PalletTimestampCall (172) */ + /** @name PalletTimestampCall (173) */ interface PalletTimestampCall extends Enum { readonly isSet: boolean; readonly asSet: { @@ -2228,7 +2242,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Set'; } - /** @name PalletSudoCall (173) */ + /** @name PalletSudoCall (174) */ interface PalletSudoCall extends Enum { readonly isSudo: boolean; readonly asSudo: { @@ -2252,7 +2266,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs' | 'RemoveKey'; } - /** @name PalletAssetsCall (175) */ + /** @name PalletAssetsCall (176) */ interface PalletAssetsCall extends Enum { readonly isCreate: boolean; readonly asCreate: { @@ -2434,7 +2448,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Create' | 'ForceCreate' | 'StartDestroy' | 'DestroyAccounts' | 'DestroyApprovals' | 'FinishDestroy' | 'Mint' | 'Burn' | 'Transfer' | 'TransferKeepAlive' | 'ForceTransfer' | 'Freeze' | 'Thaw' | 'FreezeAsset' | 'ThawAsset' | 'TransferOwnership' | 'SetTeam' | 'SetMetadata' | 'ClearMetadata' | 'ForceSetMetadata' | 'ForceClearMetadata' | 'ForceAssetStatus' | 'ApproveTransfer' | 'CancelApproval' | 'ForceCancelApproval' | 'TransferApproved' | 'Touch' | 'Refund' | 'SetMinBalance' | 'TouchOther' | 'RefundOther' | 'Block'; } - /** @name PalletBalancesCall (177) */ + /** @name PalletBalancesCall (178) */ interface PalletBalancesCall extends Enum { readonly isTransferAllowDeath: boolean; readonly asTransferAllowDeath: { @@ -2484,14 +2498,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'TransferAllowDeath' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve' | 'UpgradeAccounts' | 'ForceSetBalance' | 'ForceAdjustTotalIssuance' | 'Burn'; } - /** @name PalletBalancesAdjustmentDirection (178) */ + /** @name PalletBalancesAdjustmentDirection (179) */ interface PalletBalancesAdjustmentDirection extends Enum { readonly isIncrease: boolean; readonly isDecrease: boolean; readonly type: 'Increase' | 'Decrease'; } - /** @name PalletBabeCall (179) */ + /** @name PalletBabeCall (180) */ interface PalletBabeCall extends Enum { readonly isReportEquivocation: boolean; readonly asReportEquivocation: { @@ -2510,7 +2524,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ReportEquivocation' | 'ReportEquivocationUnsigned' | 'PlanConfigChange'; } - /** @name SpConsensusSlotsEquivocationProof (180) */ + /** @name SpConsensusSlotsEquivocationProof (181) */ interface SpConsensusSlotsEquivocationProof extends Struct { readonly offender: SpConsensusBabeAppPublic; readonly slot: u64; @@ -2518,7 +2532,7 @@ declare module '@polkadot/types/lookup' { readonly secondHeader: SpRuntimeHeader; } - /** @name SpRuntimeHeader (181) */ + /** @name SpRuntimeHeader (182) */ interface SpRuntimeHeader extends Struct { readonly parentHash: H256; readonly number: Compact; @@ -2527,17 +2541,17 @@ declare module '@polkadot/types/lookup' { readonly digest: SpRuntimeDigest; } - /** @name SpConsensusBabeAppPublic (182) */ + /** @name SpConsensusBabeAppPublic (183) */ interface SpConsensusBabeAppPublic extends U8aFixed {} - /** @name SpSessionMembershipProof (184) */ + /** @name SpSessionMembershipProof (185) */ interface SpSessionMembershipProof extends Struct { readonly session: u32; readonly trieNodes: Vec; readonly validatorCount: u32; } - /** @name SpConsensusBabeDigestsNextConfigDescriptor (185) */ + /** @name SpConsensusBabeDigestsNextConfigDescriptor (186) */ interface SpConsensusBabeDigestsNextConfigDescriptor extends Enum { readonly isV1: boolean; readonly asV1: { @@ -2547,7 +2561,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'V1'; } - /** @name SpConsensusBabeAllowedSlots (187) */ + /** @name SpConsensusBabeAllowedSlots (188) */ interface SpConsensusBabeAllowedSlots extends Enum { readonly isPrimarySlots: boolean; readonly isPrimaryAndSecondaryPlainSlots: boolean; @@ -2555,7 +2569,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PrimarySlots' | 'PrimaryAndSecondaryPlainSlots' | 'PrimaryAndSecondaryVRFSlots'; } - /** @name PalletGrandpaCall (188) */ + /** @name PalletGrandpaCall (189) */ interface PalletGrandpaCall extends Enum { readonly isReportEquivocation: boolean; readonly asReportEquivocation: { @@ -2575,13 +2589,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'ReportEquivocation' | 'ReportEquivocationUnsigned' | 'NoteStalled'; } - /** @name SpConsensusGrandpaEquivocationProof (189) */ + /** @name SpConsensusGrandpaEquivocationProof (190) */ interface SpConsensusGrandpaEquivocationProof extends Struct { readonly setId: u64; readonly equivocation: SpConsensusGrandpaEquivocation; } - /** @name SpConsensusGrandpaEquivocation (190) */ + /** @name SpConsensusGrandpaEquivocation (191) */ interface SpConsensusGrandpaEquivocation extends Enum { readonly isPrevote: boolean; readonly asPrevote: FinalityGrandpaEquivocationPrevote; @@ -2590,7 +2604,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Prevote' | 'Precommit'; } - /** @name FinalityGrandpaEquivocationPrevote (191) */ + /** @name FinalityGrandpaEquivocationPrevote (192) */ interface FinalityGrandpaEquivocationPrevote extends Struct { readonly roundNumber: u64; readonly identity: SpConsensusGrandpaAppPublic; @@ -2598,16 +2612,16 @@ declare module '@polkadot/types/lookup' { readonly second: ITuple<[FinalityGrandpaPrevote, SpConsensusGrandpaAppSignature]>; } - /** @name FinalityGrandpaPrevote (192) */ + /** @name FinalityGrandpaPrevote (193) */ interface FinalityGrandpaPrevote extends Struct { readonly targetHash: H256; readonly targetNumber: u64; } - /** @name SpConsensusGrandpaAppSignature (193) */ + /** @name SpConsensusGrandpaAppSignature (194) */ interface SpConsensusGrandpaAppSignature extends U8aFixed {} - /** @name FinalityGrandpaEquivocationPrecommit (196) */ + /** @name FinalityGrandpaEquivocationPrecommit (197) */ interface FinalityGrandpaEquivocationPrecommit extends Struct { readonly roundNumber: u64; readonly identity: SpConsensusGrandpaAppPublic; @@ -2615,16 +2629,16 @@ declare module '@polkadot/types/lookup' { readonly second: ITuple<[FinalityGrandpaPrecommit, SpConsensusGrandpaAppSignature]>; } - /** @name FinalityGrandpaPrecommit (197) */ + /** @name FinalityGrandpaPrecommit (198) */ interface FinalityGrandpaPrecommit extends Struct { readonly targetHash: H256; readonly targetNumber: u64; } - /** @name SpCoreVoid (199) */ + /** @name SpCoreVoid (200) */ type SpCoreVoid = Null; - /** @name PalletIndicesCall (200) */ + /** @name PalletIndicesCall (201) */ interface PalletIndicesCall extends Enum { readonly isClaim: boolean; readonly asClaim: { @@ -2652,7 +2666,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Claim' | 'Transfer' | 'Free' | 'ForceTransfer' | 'Freeze'; } - /** @name PalletDemocracyCall (201) */ + /** @name PalletDemocracyCall (202) */ interface PalletDemocracyCall extends Enum { readonly isPropose: boolean; readonly asPropose: { @@ -2736,7 +2750,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Propose' | 'Second' | 'Vote' | 'EmergencyCancel' | 'ExternalPropose' | 'ExternalProposeMajority' | 'ExternalProposeDefault' | 'FastTrack' | 'VetoExternal' | 'CancelReferendum' | 'Delegate' | 'Undelegate' | 'ClearPublicProposals' | 'Unlock' | 'RemoveVote' | 'RemoveOtherVote' | 'Blacklist' | 'CancelProposal' | 'SetMetadata'; } - /** @name FrameSupportPreimagesBounded (202) */ + /** @name FrameSupportPreimagesBounded (203) */ interface FrameSupportPreimagesBounded extends Enum { readonly isLegacy: boolean; readonly asLegacy: { @@ -2752,10 +2766,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Inline' | 'Lookup'; } - /** @name SpRuntimeBlakeTwo256 (203) */ + /** @name SpRuntimeBlakeTwo256 (204) */ type SpRuntimeBlakeTwo256 = Null; - /** @name PalletDemocracyConviction (205) */ + /** @name PalletDemocracyConviction (206) */ interface PalletDemocracyConviction extends Enum { readonly isNone: boolean; readonly isLocked1x: boolean; @@ -2767,7 +2781,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'None' | 'Locked1x' | 'Locked2x' | 'Locked3x' | 'Locked4x' | 'Locked5x' | 'Locked6x'; } - /** @name PalletCollectiveCall (208) */ + /** @name PalletCollectiveCall (209) */ interface PalletCollectiveCall extends Enum { readonly isSetMembers: boolean; readonly asSetMembers: { @@ -2806,7 +2820,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetMembers' | 'Execute' | 'Propose' | 'Vote' | 'DisapproveProposal' | 'Close'; } - /** @name PalletVestingCall (209) */ + /** @name PalletVestingCall (210) */ interface PalletVestingCall extends Enum { readonly isVest: boolean; readonly isVestOther: boolean; @@ -2837,14 +2851,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Vest' | 'VestOther' | 'VestedTransfer' | 'ForceVestedTransfer' | 'MergeSchedules' | 'ForceRemoveVestingSchedule'; } - /** @name PalletVestingVestingInfo (210) */ + /** @name PalletVestingVestingInfo (211) */ interface PalletVestingVestingInfo extends Struct { readonly locked: u128; readonly perBlock: u128; readonly startingBlock: u64; } - /** @name PalletElectionsPhragmenCall (211) */ + /** @name PalletElectionsPhragmenCall (212) */ interface PalletElectionsPhragmenCall extends Enum { readonly isVote: boolean; readonly asVote: { @@ -2874,7 +2888,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Vote' | 'RemoveVoter' | 'SubmitCandidacy' | 'RenounceCandidacy' | 'RemoveMember' | 'CleanDefunctVoters'; } - /** @name PalletElectionsPhragmenRenouncing (212) */ + /** @name PalletElectionsPhragmenRenouncing (213) */ interface PalletElectionsPhragmenRenouncing extends Enum { readonly isMember: boolean; readonly isRunnerUp: boolean; @@ -2883,7 +2897,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Member' | 'RunnerUp' | 'Candidate'; } - /** @name PalletElectionProviderMultiPhaseCall (213) */ + /** @name PalletElectionProviderMultiPhaseCall (214) */ interface PalletElectionProviderMultiPhaseCall extends Enum { readonly isSubmitUnsigned: boolean; readonly asSubmitUnsigned: { @@ -2910,14 +2924,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'SubmitUnsigned' | 'SetMinimumUntrustedScore' | 'SetEmergencyElectionResult' | 'Submit' | 'GovernanceFallback'; } - /** @name PalletElectionProviderMultiPhaseRawSolution (214) */ + /** @name PalletElectionProviderMultiPhaseRawSolution (215) */ interface PalletElectionProviderMultiPhaseRawSolution extends Struct { readonly solution: TangleTestnetRuntimeNposSolution16; readonly score: SpNposElectionsElectionScore; readonly round: u32; } - /** @name TangleTestnetRuntimeNposSolution16 (215) */ + /** @name TangleTestnetRuntimeNposSolution16 (216) */ interface TangleTestnetRuntimeNposSolution16 extends Struct { readonly votes1: Vec, Compact]>>; readonly votes2: Vec, ITuple<[Compact, Compact]>, Compact]>>; @@ -2937,19 +2951,19 @@ declare module '@polkadot/types/lookup' { readonly votes16: Vec, Vec, Compact]>>, Compact]>>; } - /** @name PalletElectionProviderMultiPhaseSolutionOrSnapshotSize (266) */ + /** @name PalletElectionProviderMultiPhaseSolutionOrSnapshotSize (267) */ interface PalletElectionProviderMultiPhaseSolutionOrSnapshotSize extends Struct { readonly voters: Compact; readonly targets: Compact; } - /** @name SpNposElectionsSupport (270) */ + /** @name SpNposElectionsSupport (271) */ interface SpNposElectionsSupport extends Struct { readonly total: u128; readonly voters: Vec>; } - /** @name PalletStakingPalletCall (271) */ + /** @name PalletStakingPalletCall (272) */ interface PalletStakingPalletCall extends Enum { readonly isBond: boolean; readonly asBond: { @@ -3075,7 +3089,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Bond' | 'BondExtra' | 'Unbond' | 'WithdrawUnbonded' | 'Validate' | 'Nominate' | 'Chill' | 'SetPayee' | 'SetController' | 'SetValidatorCount' | 'IncreaseValidatorCount' | 'ScaleValidatorCount' | 'ForceNoEras' | 'ForceNewEra' | 'SetInvulnerables' | 'ForceUnstake' | 'ForceNewEraAlways' | 'CancelDeferredSlash' | 'PayoutStakers' | 'Rebond' | 'ReapStash' | 'Kick' | 'SetStakingConfigs' | 'ChillOther' | 'ForceApplyMinCommission' | 'SetMinCommission' | 'PayoutStakersByPage' | 'UpdatePayee' | 'DeprecateControllerBatch' | 'RestoreLedger'; } - /** @name PalletStakingPalletConfigOpU128 (274) */ + /** @name PalletStakingPalletConfigOpU128 (275) */ interface PalletStakingPalletConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3084,7 +3098,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpU32 (275) */ + /** @name PalletStakingPalletConfigOpU32 (276) */ interface PalletStakingPalletConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3093,7 +3107,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpPercent (276) */ + /** @name PalletStakingPalletConfigOpPercent (277) */ interface PalletStakingPalletConfigOpPercent extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3102,7 +3116,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingPalletConfigOpPerbill (277) */ + /** @name PalletStakingPalletConfigOpPerbill (278) */ interface PalletStakingPalletConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3111,13 +3125,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletStakingUnlockChunk (282) */ + /** @name PalletStakingUnlockChunk (283) */ interface PalletStakingUnlockChunk extends Struct { readonly value: Compact; readonly era: Compact; } - /** @name PalletSessionCall (284) */ + /** @name PalletSessionCall (285) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -3128,14 +3142,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetKeys' | 'PurgeKeys'; } - /** @name TangleTestnetRuntimeOpaqueSessionKeys (285) */ + /** @name TangleTestnetRuntimeOpaqueSessionKeys (286) */ interface TangleTestnetRuntimeOpaqueSessionKeys extends Struct { readonly babe: SpConsensusBabeAppPublic; readonly grandpa: SpConsensusGrandpaAppPublic; readonly imOnline: PalletImOnlineSr25519AppSr25519Public; } - /** @name PalletTreasuryCall (286) */ + /** @name PalletTreasuryCall (287) */ interface PalletTreasuryCall extends Enum { readonly isSpendLocal: boolean; readonly asSpendLocal: { @@ -3168,7 +3182,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SpendLocal' | 'RemoveApproval' | 'Spend' | 'Payout' | 'CheckStatus' | 'VoidSpend'; } - /** @name PalletBountiesCall (288) */ + /** @name PalletBountiesCall (289) */ interface PalletBountiesCall extends Enum { readonly isProposeBounty: boolean; readonly asProposeBounty: { @@ -3214,7 +3228,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ProposeBounty' | 'ApproveBounty' | 'ProposeCurator' | 'UnassignCurator' | 'AcceptCurator' | 'AwardBounty' | 'ClaimBounty' | 'CloseBounty' | 'ExtendBountyExpiry'; } - /** @name PalletChildBountiesCall (289) */ + /** @name PalletChildBountiesCall (290) */ interface PalletChildBountiesCall extends Enum { readonly isAddChildBounty: boolean; readonly asAddChildBounty: { @@ -3258,7 +3272,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AddChildBounty' | 'ProposeCurator' | 'AcceptCurator' | 'UnassignCurator' | 'AwardChildBounty' | 'ClaimChildBounty' | 'CloseChildBounty'; } - /** @name PalletBagsListCall (290) */ + /** @name PalletBagsListCall (291) */ interface PalletBagsListCall extends Enum { readonly isRebag: boolean; readonly asRebag: { @@ -3276,7 +3290,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Rebag' | 'PutInFrontOf' | 'PutInFrontOfOther'; } - /** @name PalletNominationPoolsCall (291) */ + /** @name PalletNominationPoolsCall (292) */ interface PalletNominationPoolsCall extends Enum { readonly isJoin: boolean; readonly asJoin: { @@ -3409,7 +3423,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Join' | 'BondExtra' | 'ClaimPayout' | 'Unbond' | 'PoolWithdrawUnbonded' | 'WithdrawUnbonded' | 'Create' | 'CreateWithPoolId' | 'Nominate' | 'SetState' | 'SetMetadata' | 'SetConfigs' | 'UpdateRoles' | 'Chill' | 'BondExtraOther' | 'SetClaimPermission' | 'ClaimPayoutOther' | 'SetCommission' | 'SetCommissionMax' | 'SetCommissionChangeRate' | 'ClaimCommission' | 'AdjustPoolDeposit' | 'SetCommissionClaimPermission' | 'ApplySlash' | 'MigrateDelegation' | 'MigratePoolToDelegateStake'; } - /** @name PalletNominationPoolsBondExtra (292) */ + /** @name PalletNominationPoolsBondExtra (293) */ interface PalletNominationPoolsBondExtra extends Enum { readonly isFreeBalance: boolean; readonly asFreeBalance: u128; @@ -3417,7 +3431,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'FreeBalance' | 'Rewards'; } - /** @name PalletNominationPoolsConfigOpU128 (293) */ + /** @name PalletNominationPoolsConfigOpU128 (294) */ interface PalletNominationPoolsConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3426,7 +3440,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpU32 (294) */ + /** @name PalletNominationPoolsConfigOpU32 (295) */ interface PalletNominationPoolsConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3435,7 +3449,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpPerbill (295) */ + /** @name PalletNominationPoolsConfigOpPerbill (296) */ interface PalletNominationPoolsConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3444,7 +3458,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsConfigOpAccountId32 (296) */ + /** @name PalletNominationPoolsConfigOpAccountId32 (297) */ interface PalletNominationPoolsConfigOpAccountId32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -3453,7 +3467,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletNominationPoolsClaimPermission (297) */ + /** @name PalletNominationPoolsClaimPermission (298) */ interface PalletNominationPoolsClaimPermission extends Enum { readonly isPermissioned: boolean; readonly isPermissionlessCompound: boolean; @@ -3462,7 +3476,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissioned' | 'PermissionlessCompound' | 'PermissionlessWithdraw' | 'PermissionlessAll'; } - /** @name PalletSchedulerCall (298) */ + /** @name PalletSchedulerCall (299) */ interface PalletSchedulerCall extends Enum { readonly isSchedule: boolean; readonly asSchedule: { @@ -3526,7 +3540,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Schedule' | 'Cancel' | 'ScheduleNamed' | 'CancelNamed' | 'ScheduleAfter' | 'ScheduleNamedAfter' | 'SetRetry' | 'SetRetryNamed' | 'CancelRetry' | 'CancelRetryNamed'; } - /** @name PalletPreimageCall (300) */ + /** @name PalletPreimageCall (301) */ interface PalletPreimageCall extends Enum { readonly isNotePreimage: boolean; readonly asNotePreimage: { @@ -3551,7 +3565,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotePreimage' | 'UnnotePreimage' | 'RequestPreimage' | 'UnrequestPreimage' | 'EnsureUpdated'; } - /** @name PalletTxPauseCall (301) */ + /** @name PalletTxPauseCall (302) */ interface PalletTxPauseCall extends Enum { readonly isPause: boolean; readonly asPause: { @@ -3564,7 +3578,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pause' | 'Unpause'; } - /** @name PalletImOnlineCall (302) */ + /** @name PalletImOnlineCall (303) */ interface PalletImOnlineCall extends Enum { readonly isHeartbeat: boolean; readonly asHeartbeat: { @@ -3574,7 +3588,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Heartbeat'; } - /** @name PalletImOnlineHeartbeat (303) */ + /** @name PalletImOnlineHeartbeat (304) */ interface PalletImOnlineHeartbeat extends Struct { readonly blockNumber: u64; readonly sessionIndex: u32; @@ -3582,10 +3596,10 @@ declare module '@polkadot/types/lookup' { readonly validatorsLen: u32; } - /** @name PalletImOnlineSr25519AppSr25519Signature (304) */ + /** @name PalletImOnlineSr25519AppSr25519Signature (305) */ interface PalletImOnlineSr25519AppSr25519Signature extends U8aFixed {} - /** @name PalletIdentityCall (305) */ + /** @name PalletIdentityCall (306) */ interface PalletIdentityCall extends Enum { readonly isAddRegistrar: boolean; readonly asAddRegistrar: { @@ -3685,7 +3699,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AddRegistrar' | 'SetIdentity' | 'SetSubs' | 'ClearIdentity' | 'RequestJudgement' | 'CancelRequest' | 'SetFee' | 'SetAccountId' | 'SetFields' | 'ProvideJudgement' | 'KillIdentity' | 'AddSub' | 'RenameSub' | 'RemoveSub' | 'QuitSub' | 'AddUsernameAuthority' | 'RemoveUsernameAuthority' | 'SetUsernameFor' | 'AcceptUsername' | 'RemoveExpiredApproval' | 'SetPrimaryUsername' | 'RemoveDanglingUsername'; } - /** @name PalletIdentityLegacyIdentityInfo (306) */ + /** @name PalletIdentityLegacyIdentityInfo (307) */ interface PalletIdentityLegacyIdentityInfo extends Struct { readonly additional: Vec>; readonly display: Data; @@ -3698,7 +3712,7 @@ declare module '@polkadot/types/lookup' { readonly twitter: Data; } - /** @name PalletIdentityJudgement (342) */ + /** @name PalletIdentityJudgement (343) */ interface PalletIdentityJudgement extends Enum { readonly isUnknown: boolean; readonly isFeePaid: boolean; @@ -3711,7 +3725,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unknown' | 'FeePaid' | 'Reasonable' | 'KnownGood' | 'OutOfDate' | 'LowQuality' | 'Erroneous'; } - /** @name SpRuntimeMultiSignature (344) */ + /** @name SpRuntimeMultiSignature (345) */ interface SpRuntimeMultiSignature extends Enum { readonly isEd25519: boolean; readonly asEd25519: U8aFixed; @@ -3722,7 +3736,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa'; } - /** @name PalletUtilityCall (345) */ + /** @name PalletUtilityCall (346) */ interface PalletUtilityCall extends Enum { readonly isBatch: boolean; readonly asBatch: { @@ -3754,7 +3768,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Batch' | 'AsDerivative' | 'BatchAll' | 'DispatchAs' | 'ForceBatch' | 'WithWeight'; } - /** @name TangleTestnetRuntimeOriginCaller (347) */ + /** @name TangleTestnetRuntimeOriginCaller (348) */ interface TangleTestnetRuntimeOriginCaller extends Enum { readonly isSystem: boolean; readonly asSystem: FrameSupportDispatchRawOrigin; @@ -3766,7 +3780,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'System' | 'Void' | 'Council' | 'Ethereum'; } - /** @name FrameSupportDispatchRawOrigin (348) */ + /** @name FrameSupportDispatchRawOrigin (349) */ interface FrameSupportDispatchRawOrigin extends Enum { readonly isRoot: boolean; readonly isSigned: boolean; @@ -3775,7 +3789,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Root' | 'Signed' | 'None'; } - /** @name PalletCollectiveRawOrigin (349) */ + /** @name PalletCollectiveRawOrigin (350) */ interface PalletCollectiveRawOrigin extends Enum { readonly isMembers: boolean; readonly asMembers: ITuple<[u32, u32]>; @@ -3785,14 +3799,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Members' | 'Member' | 'Phantom'; } - /** @name PalletEthereumRawOrigin (350) */ + /** @name PalletEthereumRawOrigin (351) */ interface PalletEthereumRawOrigin extends Enum { readonly isEthereumTransaction: boolean; readonly asEthereumTransaction: H160; readonly type: 'EthereumTransaction'; } - /** @name PalletMultisigCall (351) */ + /** @name PalletMultisigCall (352) */ interface PalletMultisigCall extends Enum { readonly isAsMultiThreshold1: boolean; readonly asAsMultiThreshold1: { @@ -3825,7 +3839,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'AsMultiThreshold1' | 'AsMulti' | 'ApproveAsMulti' | 'CancelAsMulti'; } - /** @name PalletEthereumCall (353) */ + /** @name PalletEthereumCall (354) */ interface PalletEthereumCall extends Enum { readonly isTransact: boolean; readonly asTransact: { @@ -3834,7 +3848,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Transact'; } - /** @name EthereumTransactionTransactionV2 (354) */ + /** @name EthereumTransactionTransactionV2 (355) */ interface EthereumTransactionTransactionV2 extends Enum { readonly isLegacy: boolean; readonly asLegacy: EthereumTransactionLegacyTransaction; @@ -3845,7 +3859,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Eip2930' | 'Eip1559'; } - /** @name EthereumTransactionLegacyTransaction (355) */ + /** @name EthereumTransactionLegacyTransaction (356) */ interface EthereumTransactionLegacyTransaction extends Struct { readonly nonce: U256; readonly gasPrice: U256; @@ -3856,7 +3870,7 @@ declare module '@polkadot/types/lookup' { readonly signature: EthereumTransactionTransactionSignature; } - /** @name EthereumTransactionTransactionAction (356) */ + /** @name EthereumTransactionTransactionAction (357) */ interface EthereumTransactionTransactionAction extends Enum { readonly isCall: boolean; readonly asCall: H160; @@ -3864,14 +3878,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Call' | 'Create'; } - /** @name EthereumTransactionTransactionSignature (357) */ + /** @name EthereumTransactionTransactionSignature (358) */ interface EthereumTransactionTransactionSignature extends Struct { readonly v: u64; readonly r: H256; readonly s: H256; } - /** @name EthereumTransactionEip2930Transaction (359) */ + /** @name EthereumTransactionEip2930Transaction (360) */ interface EthereumTransactionEip2930Transaction extends Struct { readonly chainId: u64; readonly nonce: U256; @@ -3886,13 +3900,13 @@ declare module '@polkadot/types/lookup' { readonly s: H256; } - /** @name EthereumTransactionAccessListItem (361) */ + /** @name EthereumTransactionAccessListItem (362) */ interface EthereumTransactionAccessListItem extends Struct { readonly address: H160; readonly storageKeys: Vec; } - /** @name EthereumTransactionEip1559Transaction (362) */ + /** @name EthereumTransactionEip1559Transaction (363) */ interface EthereumTransactionEip1559Transaction extends Struct { readonly chainId: u64; readonly nonce: U256; @@ -3908,7 +3922,7 @@ declare module '@polkadot/types/lookup' { readonly s: H256; } - /** @name PalletEvmCall (363) */ + /** @name PalletEvmCall (364) */ interface PalletEvmCall extends Enum { readonly isWithdraw: boolean; readonly asWithdraw: { @@ -3953,7 +3967,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2'; } - /** @name PalletDynamicFeeCall (367) */ + /** @name PalletDynamicFeeCall (368) */ interface PalletDynamicFeeCall extends Enum { readonly isNoteMinGasPriceTarget: boolean; readonly asNoteMinGasPriceTarget: { @@ -3962,7 +3976,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NoteMinGasPriceTarget'; } - /** @name PalletBaseFeeCall (368) */ + /** @name PalletBaseFeeCall (369) */ interface PalletBaseFeeCall extends Enum { readonly isSetBaseFeePerGas: boolean; readonly asSetBaseFeePerGas: { @@ -3975,7 +3989,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'SetBaseFeePerGas' | 'SetElasticity'; } - /** @name PalletHotfixSufficientsCall (369) */ + /** @name PalletHotfixSufficientsCall (370) */ interface PalletHotfixSufficientsCall extends Enum { readonly isHotfixIncAccountSufficients: boolean; readonly asHotfixIncAccountSufficients: { @@ -3984,7 +3998,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'HotfixIncAccountSufficients'; } - /** @name PalletAirdropClaimsCall (371) */ + /** @name PalletAirdropClaimsCall (372) */ interface PalletAirdropClaimsCall extends Enum { readonly isClaim: boolean; readonly asClaim: { @@ -4023,7 +4037,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Claim' | 'MintClaim' | 'ClaimAttest' | 'MoveClaim' | 'ForceSetExpiryConfig' | 'ClaimSigned'; } - /** @name PalletAirdropClaimsUtilsMultiAddressSignature (373) */ + /** @name PalletAirdropClaimsUtilsMultiAddressSignature (374) */ interface PalletAirdropClaimsUtilsMultiAddressSignature extends Enum { readonly isEvm: boolean; readonly asEvm: PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature; @@ -4032,20 +4046,20 @@ declare module '@polkadot/types/lookup' { readonly type: 'Evm' | 'Native'; } - /** @name PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature (374) */ + /** @name PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature (375) */ interface PalletAirdropClaimsUtilsEthereumAddressEcdsaSignature extends U8aFixed {} - /** @name PalletAirdropClaimsUtilsSr25519Signature (375) */ + /** @name PalletAirdropClaimsUtilsSr25519Signature (376) */ interface PalletAirdropClaimsUtilsSr25519Signature extends U8aFixed {} - /** @name PalletAirdropClaimsStatementKind (381) */ + /** @name PalletAirdropClaimsStatementKind (382) */ interface PalletAirdropClaimsStatementKind extends Enum { readonly isRegular: boolean; readonly isSafe: boolean; readonly type: 'Regular' | 'Safe'; } - /** @name PalletProxyCall (382) */ + /** @name PalletProxyCall (383) */ interface PalletProxyCall extends Enum { readonly isProxy: boolean; readonly asProxy: { @@ -4105,7 +4119,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Proxy' | 'AddProxy' | 'RemoveProxy' | 'RemoveProxies' | 'CreatePure' | 'KillPure' | 'Announce' | 'RemoveAnnouncement' | 'RejectAnnouncement' | 'ProxyAnnounced'; } - /** @name PalletMultiAssetDelegationCall (384) */ + /** @name PalletMultiAssetDelegationCall (385) */ interface PalletMultiAssetDelegationCall extends Enum { readonly isJoinOperators: boolean; readonly asJoinOperators: { @@ -4131,6 +4145,7 @@ declare module '@polkadot/types/lookup' { readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; readonly evmAddress: Option; + readonly lockMultiplier: Option; } & Struct; readonly isScheduleWithdraw: boolean; readonly asScheduleWithdraw: { @@ -4166,22 +4181,6 @@ declare module '@polkadot/types/lookup' { readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; } & Struct; - readonly isSetIncentiveApyAndCap: boolean; - readonly asSetIncentiveApyAndCap: { - readonly vaultId: u128; - readonly apy: Percent; - readonly cap: u128; - } & Struct; - readonly isWhitelistBlueprintForRewards: boolean; - readonly asWhitelistBlueprintForRewards: { - readonly blueprintId: u64; - } & Struct; - readonly isManageAssetInVault: boolean; - readonly asManageAssetInVault: { - readonly vaultId: u128; - readonly assetId: TanglePrimitivesServicesAsset; - readonly action: PalletMultiAssetDelegationRewardsAssetAction; - } & Struct; readonly isAddBlueprintId: boolean; readonly asAddBlueprintId: { readonly blueprintId: u64; @@ -4190,10 +4189,19 @@ declare module '@polkadot/types/lookup' { readonly asRemoveBlueprintId: { readonly blueprintId: u64; } & Struct; - readonly type: 'JoinOperators' | 'ScheduleLeaveOperators' | 'CancelLeaveOperators' | 'ExecuteLeaveOperators' | 'OperatorBondMore' | 'ScheduleOperatorUnstake' | 'ExecuteOperatorUnstake' | 'CancelOperatorUnstake' | 'GoOffline' | 'GoOnline' | 'Deposit' | 'ScheduleWithdraw' | 'ExecuteWithdraw' | 'CancelWithdraw' | 'Delegate' | 'ScheduleDelegatorUnstake' | 'ExecuteDelegatorUnstake' | 'CancelDelegatorUnstake' | 'SetIncentiveApyAndCap' | 'WhitelistBlueprintForRewards' | 'ManageAssetInVault' | 'AddBlueprintId' | 'RemoveBlueprintId'; + readonly type: 'JoinOperators' | 'ScheduleLeaveOperators' | 'CancelLeaveOperators' | 'ExecuteLeaveOperators' | 'OperatorBondMore' | 'ScheduleOperatorUnstake' | 'ExecuteOperatorUnstake' | 'CancelOperatorUnstake' | 'GoOffline' | 'GoOnline' | 'Deposit' | 'ScheduleWithdraw' | 'ExecuteWithdraw' | 'CancelWithdraw' | 'Delegate' | 'ScheduleDelegatorUnstake' | 'ExecuteDelegatorUnstake' | 'CancelDelegatorUnstake' | 'AddBlueprintId' | 'RemoveBlueprintId'; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection (386) */ + /** @name TanglePrimitivesRewardsLockMultiplier (388) */ + interface TanglePrimitivesRewardsLockMultiplier extends Enum { + readonly isOneMonth: boolean; + readonly isTwoMonths: boolean; + readonly isThreeMonths: boolean; + readonly isSixMonths: boolean; + readonly type: 'OneMonth' | 'TwoMonths' | 'ThreeMonths' | 'SixMonths'; + } + + /** @name PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection (389) */ interface PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection extends Enum { readonly isFixed: boolean; readonly asFixed: Vec; @@ -4201,10 +4209,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Fixed' | 'All'; } - /** @name TangleTestnetRuntimeMaxDelegatorBlueprints (387) */ + /** @name TangleTestnetRuntimeMaxDelegatorBlueprints (390) */ type TangleTestnetRuntimeMaxDelegatorBlueprints = Null; - /** @name PalletServicesModuleCall (390) */ + /** @name PalletServicesModuleCall (393) */ interface PalletServicesModuleCall extends Enum { readonly isCreateBlueprint: boolean; readonly asCreateBlueprint: { @@ -4285,7 +4293,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'CreateBlueprint' | 'PreRegister' | 'Register' | 'Unregister' | 'UpdatePriceTargets' | 'Request' | 'Approve' | 'Reject' | 'Terminate' | 'Call' | 'SubmitResult' | 'Slash' | 'Dispute' | 'UpdateMasterBlueprintServiceManager'; } - /** @name TanglePrimitivesServicesServiceBlueprint (391) */ + /** @name TanglePrimitivesServicesServiceBlueprint (394) */ interface TanglePrimitivesServicesServiceBlueprint extends Struct { readonly metadata: TanglePrimitivesServicesServiceMetadata; readonly jobs: Vec; @@ -4296,7 +4304,7 @@ declare module '@polkadot/types/lookup' { readonly gadget: TanglePrimitivesServicesGadget; } - /** @name TanglePrimitivesServicesServiceMetadata (392) */ + /** @name TanglePrimitivesServicesServiceMetadata (395) */ interface TanglePrimitivesServicesServiceMetadata extends Struct { readonly name: Bytes; readonly description: Option; @@ -4308,20 +4316,20 @@ declare module '@polkadot/types/lookup' { readonly license: Option; } - /** @name TanglePrimitivesServicesJobDefinition (397) */ + /** @name TanglePrimitivesServicesJobDefinition (400) */ interface TanglePrimitivesServicesJobDefinition extends Struct { readonly metadata: TanglePrimitivesServicesJobMetadata; readonly params: Vec; readonly result: Vec; } - /** @name TanglePrimitivesServicesJobMetadata (398) */ + /** @name TanglePrimitivesServicesJobMetadata (401) */ interface TanglePrimitivesServicesJobMetadata extends Struct { readonly name: Bytes; readonly description: Option; } - /** @name TanglePrimitivesServicesFieldFieldType (400) */ + /** @name TanglePrimitivesServicesFieldFieldType (403) */ interface TanglePrimitivesServicesFieldFieldType extends Enum { readonly isVoid: boolean; readonly isBool: boolean; @@ -4347,14 +4355,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Void' | 'Bool' | 'Uint8' | 'Int8' | 'Uint16' | 'Int16' | 'Uint32' | 'Int32' | 'Uint64' | 'Int64' | 'String' | 'Bytes' | 'Optional' | 'Array' | 'List' | 'Struct' | 'AccountId'; } - /** @name TanglePrimitivesServicesBlueprintServiceManager (406) */ + /** @name TanglePrimitivesServicesBlueprintServiceManager (409) */ interface TanglePrimitivesServicesBlueprintServiceManager extends Enum { readonly isEvm: boolean; readonly asEvm: H160; readonly type: 'Evm'; } - /** @name TanglePrimitivesServicesMasterBlueprintServiceManagerRevision (407) */ + /** @name TanglePrimitivesServicesMasterBlueprintServiceManagerRevision (410) */ interface TanglePrimitivesServicesMasterBlueprintServiceManagerRevision extends Enum { readonly isLatest: boolean; readonly isSpecific: boolean; @@ -4362,7 +4370,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Latest' | 'Specific'; } - /** @name TanglePrimitivesServicesGadget (408) */ + /** @name TanglePrimitivesServicesGadget (411) */ interface TanglePrimitivesServicesGadget extends Enum { readonly isWasm: boolean; readonly asWasm: TanglePrimitivesServicesWasmGadget; @@ -4373,25 +4381,25 @@ declare module '@polkadot/types/lookup' { readonly type: 'Wasm' | 'Native' | 'Container'; } - /** @name TanglePrimitivesServicesWasmGadget (409) */ + /** @name TanglePrimitivesServicesWasmGadget (412) */ interface TanglePrimitivesServicesWasmGadget extends Struct { readonly runtime: TanglePrimitivesServicesWasmRuntime; readonly sources: Vec; } - /** @name TanglePrimitivesServicesWasmRuntime (410) */ + /** @name TanglePrimitivesServicesWasmRuntime (413) */ interface TanglePrimitivesServicesWasmRuntime extends Enum { readonly isWasmtime: boolean; readonly isWasmer: boolean; readonly type: 'Wasmtime' | 'Wasmer'; } - /** @name TanglePrimitivesServicesGadgetSource (412) */ + /** @name TanglePrimitivesServicesGadgetSource (415) */ interface TanglePrimitivesServicesGadgetSource extends Struct { readonly fetcher: TanglePrimitivesServicesGadgetSourceFetcher; } - /** @name TanglePrimitivesServicesGadgetSourceFetcher (413) */ + /** @name TanglePrimitivesServicesGadgetSourceFetcher (416) */ interface TanglePrimitivesServicesGadgetSourceFetcher extends Enum { readonly isIpfs: boolean; readonly asIpfs: Bytes; @@ -4404,7 +4412,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ipfs' | 'Github' | 'ContainerImage' | 'Testing'; } - /** @name TanglePrimitivesServicesGithubFetcher (415) */ + /** @name TanglePrimitivesServicesGithubFetcher (418) */ interface TanglePrimitivesServicesGithubFetcher extends Struct { readonly owner: Bytes; readonly repo: Bytes; @@ -4412,7 +4420,7 @@ declare module '@polkadot/types/lookup' { readonly binaries: Vec; } - /** @name TanglePrimitivesServicesGadgetBinary (423) */ + /** @name TanglePrimitivesServicesGadgetBinary (426) */ interface TanglePrimitivesServicesGadgetBinary extends Struct { readonly arch: TanglePrimitivesServicesArchitecture; readonly os: TanglePrimitivesServicesOperatingSystem; @@ -4420,7 +4428,7 @@ declare module '@polkadot/types/lookup' { readonly sha256: U8aFixed; } - /** @name TanglePrimitivesServicesArchitecture (424) */ + /** @name TanglePrimitivesServicesArchitecture (427) */ interface TanglePrimitivesServicesArchitecture extends Enum { readonly isWasm: boolean; readonly isWasm64: boolean; @@ -4435,7 +4443,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Wasm' | 'Wasm64' | 'Wasi' | 'Wasi64' | 'Amd' | 'Amd64' | 'Arm' | 'Arm64' | 'RiscV' | 'RiscV64'; } - /** @name TanglePrimitivesServicesOperatingSystem (425) */ + /** @name TanglePrimitivesServicesOperatingSystem (428) */ interface TanglePrimitivesServicesOperatingSystem extends Enum { readonly isUnknown: boolean; readonly isLinux: boolean; @@ -4445,31 +4453,31 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unknown' | 'Linux' | 'Windows' | 'MacOS' | 'Bsd'; } - /** @name TanglePrimitivesServicesImageRegistryFetcher (429) */ + /** @name TanglePrimitivesServicesImageRegistryFetcher (432) */ interface TanglePrimitivesServicesImageRegistryFetcher extends Struct { readonly registry_: Bytes; readonly image: Bytes; readonly tag: Bytes; } - /** @name TanglePrimitivesServicesTestFetcher (436) */ + /** @name TanglePrimitivesServicesTestFetcher (439) */ interface TanglePrimitivesServicesTestFetcher extends Struct { readonly cargoPackage: Bytes; readonly cargoBin: Bytes; readonly basePath: Bytes; } - /** @name TanglePrimitivesServicesNativeGadget (438) */ + /** @name TanglePrimitivesServicesNativeGadget (441) */ interface TanglePrimitivesServicesNativeGadget extends Struct { readonly sources: Vec; } - /** @name TanglePrimitivesServicesContainerGadget (439) */ + /** @name TanglePrimitivesServicesContainerGadget (442) */ interface TanglePrimitivesServicesContainerGadget extends Struct { readonly sources: Vec; } - /** @name PalletTangleLstCall (442) */ + /** @name PalletTangleLstCall (445) */ interface PalletTangleLstCall extends Enum { readonly isJoin: boolean; readonly asJoin: { @@ -4587,14 +4595,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'Join' | 'BondExtra' | 'Unbond' | 'PoolWithdrawUnbonded' | 'WithdrawUnbonded' | 'Create' | 'CreateWithPoolId' | 'Nominate' | 'SetState' | 'SetMetadata' | 'SetConfigs' | 'UpdateRoles' | 'Chill' | 'BondExtraOther' | 'SetCommission' | 'SetCommissionMax' | 'SetCommissionChangeRate' | 'ClaimCommission' | 'AdjustPoolDeposit' | 'SetCommissionClaimPermission'; } - /** @name PalletTangleLstBondExtra (443) */ + /** @name PalletTangleLstBondExtra (446) */ interface PalletTangleLstBondExtra extends Enum { readonly isFreeBalance: boolean; readonly asFreeBalance: u128; readonly type: 'FreeBalance'; } - /** @name PalletTangleLstConfigOpU128 (448) */ + /** @name PalletTangleLstConfigOpU128 (451) */ interface PalletTangleLstConfigOpU128 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4603,7 +4611,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpU32 (449) */ + /** @name PalletTangleLstConfigOpU32 (452) */ interface PalletTangleLstConfigOpU32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4612,7 +4620,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpPerbill (450) */ + /** @name PalletTangleLstConfigOpPerbill (453) */ interface PalletTangleLstConfigOpPerbill extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4621,7 +4629,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletTangleLstConfigOpAccountId32 (451) */ + /** @name PalletTangleLstConfigOpAccountId32 (454) */ interface PalletTangleLstConfigOpAccountId32 extends Enum { readonly isNoop: boolean; readonly isSet: boolean; @@ -4630,13 +4638,41 @@ declare module '@polkadot/types/lookup' { readonly type: 'Noop' | 'Set' | 'Remove'; } - /** @name PalletSudoError (452) */ + /** @name PalletRewardsCall (455) */ + interface PalletRewardsCall extends Enum { + readonly isClaimRewards: boolean; + readonly asClaimRewards: { + readonly asset: TanglePrimitivesServicesAsset; + } & Struct; + readonly isManageAssetRewardVault: boolean; + readonly asManageAssetRewardVault: { + readonly vaultId: u32; + readonly assetId: TanglePrimitivesServicesAsset; + readonly action: PalletRewardsAssetAction; + } & Struct; + readonly isUpdateVaultRewardConfig: boolean; + readonly asUpdateVaultRewardConfig: { + readonly vaultId: u32; + readonly newConfig: PalletRewardsRewardConfigForAssetVault; + } & Struct; + readonly type: 'ClaimRewards' | 'ManageAssetRewardVault' | 'UpdateVaultRewardConfig'; + } + + /** @name PalletRewardsRewardConfigForAssetVault (456) */ + interface PalletRewardsRewardConfigForAssetVault extends Struct { + readonly apy: Percent; + readonly incentiveCap: u128; + readonly depositCap: u128; + readonly boostMultiplier: Option; + } + + /** @name PalletSudoError (457) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: 'RequireSudo'; } - /** @name PalletAssetsAssetDetails (454) */ + /** @name PalletAssetsAssetDetails (459) */ interface PalletAssetsAssetDetails extends Struct { readonly owner: AccountId32; readonly issuer: AccountId32; @@ -4652,7 +4688,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletAssetsAssetStatus; } - /** @name PalletAssetsAssetStatus (455) */ + /** @name PalletAssetsAssetStatus (460) */ interface PalletAssetsAssetStatus extends Enum { readonly isLive: boolean; readonly isFrozen: boolean; @@ -4660,7 +4696,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Live' | 'Frozen' | 'Destroying'; } - /** @name PalletAssetsAssetAccount (457) */ + /** @name PalletAssetsAssetAccount (462) */ interface PalletAssetsAssetAccount extends Struct { readonly balance: u128; readonly status: PalletAssetsAccountStatus; @@ -4668,7 +4704,7 @@ declare module '@polkadot/types/lookup' { readonly extra: Null; } - /** @name PalletAssetsAccountStatus (458) */ + /** @name PalletAssetsAccountStatus (463) */ interface PalletAssetsAccountStatus extends Enum { readonly isLiquid: boolean; readonly isFrozen: boolean; @@ -4676,7 +4712,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Liquid' | 'Frozen' | 'Blocked'; } - /** @name PalletAssetsExistenceReason (459) */ + /** @name PalletAssetsExistenceReason (464) */ interface PalletAssetsExistenceReason extends Enum { readonly isConsumer: boolean; readonly isSufficient: boolean; @@ -4688,13 +4724,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'Consumer' | 'Sufficient' | 'DepositHeld' | 'DepositRefunded' | 'DepositFrom'; } - /** @name PalletAssetsApproval (461) */ + /** @name PalletAssetsApproval (466) */ interface PalletAssetsApproval extends Struct { readonly amount: u128; readonly deposit: u128; } - /** @name PalletAssetsAssetMetadata (462) */ + /** @name PalletAssetsAssetMetadata (467) */ interface PalletAssetsAssetMetadata extends Struct { readonly deposit: u128; readonly name: Bytes; @@ -4703,7 +4739,7 @@ declare module '@polkadot/types/lookup' { readonly isFrozen: bool; } - /** @name PalletAssetsError (464) */ + /** @name PalletAssetsError (469) */ interface PalletAssetsError extends Enum { readonly isBalanceLow: boolean; readonly isNoAccount: boolean; @@ -4729,14 +4765,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'BalanceLow' | 'NoAccount' | 'NoPermission' | 'Unknown' | 'Frozen' | 'InUse' | 'BadWitness' | 'MinBalanceZero' | 'UnavailableConsumer' | 'BadMetadata' | 'Unapproved' | 'WouldDie' | 'AlreadyExists' | 'NoDeposit' | 'WouldBurn' | 'LiveAsset' | 'AssetNotLive' | 'IncorrectStatus' | 'NotFrozen' | 'CallbackFailed' | 'BadAssetId'; } - /** @name PalletBalancesBalanceLock (466) */ + /** @name PalletBalancesBalanceLock (471) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (467) */ + /** @name PalletBalancesReasons (472) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -4744,38 +4780,38 @@ declare module '@polkadot/types/lookup' { readonly type: 'Fee' | 'Misc' | 'All'; } - /** @name PalletBalancesReserveData (470) */ + /** @name PalletBalancesReserveData (475) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name FrameSupportTokensMiscIdAmountRuntimeHoldReason (473) */ + /** @name FrameSupportTokensMiscIdAmountRuntimeHoldReason (478) */ interface FrameSupportTokensMiscIdAmountRuntimeHoldReason extends Struct { readonly id: TangleTestnetRuntimeRuntimeHoldReason; readonly amount: u128; } - /** @name TangleTestnetRuntimeRuntimeHoldReason (474) */ + /** @name TangleTestnetRuntimeRuntimeHoldReason (479) */ interface TangleTestnetRuntimeRuntimeHoldReason extends Enum { readonly isPreimage: boolean; readonly asPreimage: PalletPreimageHoldReason; readonly type: 'Preimage'; } - /** @name PalletPreimageHoldReason (475) */ + /** @name PalletPreimageHoldReason (480) */ interface PalletPreimageHoldReason extends Enum { readonly isPreimage: boolean; readonly type: 'Preimage'; } - /** @name FrameSupportTokensMiscIdAmountRuntimeFreezeReason (478) */ + /** @name FrameSupportTokensMiscIdAmountRuntimeFreezeReason (483) */ interface FrameSupportTokensMiscIdAmountRuntimeFreezeReason extends Struct { readonly id: TangleTestnetRuntimeRuntimeFreezeReason; readonly amount: u128; } - /** @name TangleTestnetRuntimeRuntimeFreezeReason (479) */ + /** @name TangleTestnetRuntimeRuntimeFreezeReason (484) */ interface TangleTestnetRuntimeRuntimeFreezeReason extends Enum { readonly isNominationPools: boolean; readonly asNominationPools: PalletNominationPoolsFreezeReason; @@ -4784,19 +4820,19 @@ declare module '@polkadot/types/lookup' { readonly type: 'NominationPools' | 'Lst'; } - /** @name PalletNominationPoolsFreezeReason (480) */ + /** @name PalletNominationPoolsFreezeReason (485) */ interface PalletNominationPoolsFreezeReason extends Enum { readonly isPoolMinBalance: boolean; readonly type: 'PoolMinBalance'; } - /** @name PalletTangleLstFreezeReason (481) */ + /** @name PalletTangleLstFreezeReason (486) */ interface PalletTangleLstFreezeReason extends Enum { readonly isPoolMinBalance: boolean; readonly type: 'PoolMinBalance'; } - /** @name PalletBalancesError (483) */ + /** @name PalletBalancesError (488) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -4813,14 +4849,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'Expendability' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves' | 'TooManyHolds' | 'TooManyFreezes' | 'IssuanceDeactivated' | 'DeltaZero'; } - /** @name PalletTransactionPaymentReleases (485) */ + /** @name PalletTransactionPaymentReleases (490) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: 'V1Ancient' | 'V2'; } - /** @name SpConsensusBabeDigestsPreDigest (492) */ + /** @name SpConsensusBabeDigestsPreDigest (497) */ interface SpConsensusBabeDigestsPreDigest extends Enum { readonly isPrimary: boolean; readonly asPrimary: SpConsensusBabeDigestsPrimaryPreDigest; @@ -4831,39 +4867,39 @@ declare module '@polkadot/types/lookup' { readonly type: 'Primary' | 'SecondaryPlain' | 'SecondaryVRF'; } - /** @name SpConsensusBabeDigestsPrimaryPreDigest (493) */ + /** @name SpConsensusBabeDigestsPrimaryPreDigest (498) */ interface SpConsensusBabeDigestsPrimaryPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; readonly vrfSignature: SpCoreSr25519VrfVrfSignature; } - /** @name SpCoreSr25519VrfVrfSignature (494) */ + /** @name SpCoreSr25519VrfVrfSignature (499) */ interface SpCoreSr25519VrfVrfSignature extends Struct { readonly preOutput: U8aFixed; readonly proof: U8aFixed; } - /** @name SpConsensusBabeDigestsSecondaryPlainPreDigest (495) */ + /** @name SpConsensusBabeDigestsSecondaryPlainPreDigest (500) */ interface SpConsensusBabeDigestsSecondaryPlainPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; } - /** @name SpConsensusBabeDigestsSecondaryVRFPreDigest (496) */ + /** @name SpConsensusBabeDigestsSecondaryVRFPreDigest (501) */ interface SpConsensusBabeDigestsSecondaryVRFPreDigest extends Struct { readonly authorityIndex: u32; readonly slot: u64; readonly vrfSignature: SpCoreSr25519VrfVrfSignature; } - /** @name SpConsensusBabeBabeEpochConfiguration (497) */ + /** @name SpConsensusBabeBabeEpochConfiguration (502) */ interface SpConsensusBabeBabeEpochConfiguration extends Struct { readonly c: ITuple<[u64, u64]>; readonly allowedSlots: SpConsensusBabeAllowedSlots; } - /** @name PalletBabeError (499) */ + /** @name PalletBabeError (504) */ interface PalletBabeError extends Enum { readonly isInvalidEquivocationProof: boolean; readonly isInvalidKeyOwnershipProof: boolean; @@ -4872,7 +4908,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidEquivocationProof' | 'InvalidKeyOwnershipProof' | 'DuplicateOffenceReport' | 'InvalidConfiguration'; } - /** @name PalletGrandpaStoredState (500) */ + /** @name PalletGrandpaStoredState (505) */ interface PalletGrandpaStoredState extends Enum { readonly isLive: boolean; readonly isPendingPause: boolean; @@ -4889,7 +4925,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Live' | 'PendingPause' | 'Paused' | 'PendingResume'; } - /** @name PalletGrandpaStoredPendingChange (501) */ + /** @name PalletGrandpaStoredPendingChange (506) */ interface PalletGrandpaStoredPendingChange extends Struct { readonly scheduledAt: u64; readonly delay: u64; @@ -4897,7 +4933,7 @@ declare module '@polkadot/types/lookup' { readonly forced: Option; } - /** @name PalletGrandpaError (503) */ + /** @name PalletGrandpaError (508) */ interface PalletGrandpaError extends Enum { readonly isPauseFailed: boolean; readonly isResumeFailed: boolean; @@ -4909,7 +4945,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PauseFailed' | 'ResumeFailed' | 'ChangePending' | 'TooSoon' | 'InvalidKeyOwnershipProof' | 'InvalidEquivocationProof' | 'DuplicateOffenceReport'; } - /** @name PalletIndicesError (505) */ + /** @name PalletIndicesError (510) */ interface PalletIndicesError extends Enum { readonly isNotAssigned: boolean; readonly isNotOwner: boolean; @@ -4919,7 +4955,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotAssigned' | 'NotOwner' | 'InUse' | 'NotTransfer' | 'Permanent'; } - /** @name PalletDemocracyReferendumInfo (510) */ + /** @name PalletDemocracyReferendumInfo (515) */ interface PalletDemocracyReferendumInfo extends Enum { readonly isOngoing: boolean; readonly asOngoing: PalletDemocracyReferendumStatus; @@ -4931,7 +4967,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Ongoing' | 'Finished'; } - /** @name PalletDemocracyReferendumStatus (511) */ + /** @name PalletDemocracyReferendumStatus (516) */ interface PalletDemocracyReferendumStatus extends Struct { readonly end: u64; readonly proposal: FrameSupportPreimagesBounded; @@ -4940,14 +4976,14 @@ declare module '@polkadot/types/lookup' { readonly tally: PalletDemocracyTally; } - /** @name PalletDemocracyTally (512) */ + /** @name PalletDemocracyTally (517) */ interface PalletDemocracyTally extends Struct { readonly ayes: u128; readonly nays: u128; readonly turnout: u128; } - /** @name PalletDemocracyVoteVoting (513) */ + /** @name PalletDemocracyVoteVoting (518) */ interface PalletDemocracyVoteVoting extends Enum { readonly isDirect: boolean; readonly asDirect: { @@ -4966,16 +5002,16 @@ declare module '@polkadot/types/lookup' { readonly type: 'Direct' | 'Delegating'; } - /** @name PalletDemocracyDelegations (517) */ + /** @name PalletDemocracyDelegations (522) */ interface PalletDemocracyDelegations extends Struct { readonly votes: u128; readonly capital: u128; } - /** @name PalletDemocracyVotePriorLock (518) */ + /** @name PalletDemocracyVotePriorLock (523) */ interface PalletDemocracyVotePriorLock extends ITuple<[u64, u128]> {} - /** @name PalletDemocracyError (521) */ + /** @name PalletDemocracyError (526) */ interface PalletDemocracyError extends Enum { readonly isValueLow: boolean; readonly isProposalMissing: boolean; @@ -5004,7 +5040,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ValueLow' | 'ProposalMissing' | 'AlreadyCanceled' | 'DuplicateProposal' | 'ProposalBlacklisted' | 'NotSimpleMajority' | 'InvalidHash' | 'NoProposal' | 'AlreadyVetoed' | 'ReferendumInvalid' | 'NoneWaiting' | 'NotVoter' | 'NoPermission' | 'AlreadyDelegating' | 'InsufficientFunds' | 'NotDelegating' | 'VotesExist' | 'InstantNotAllowed' | 'Nonsense' | 'WrongUpperBound' | 'MaxVotesReached' | 'TooMany' | 'VotingPeriodLow' | 'PreimageNotExist'; } - /** @name PalletCollectiveVotes (523) */ + /** @name PalletCollectiveVotes (528) */ interface PalletCollectiveVotes extends Struct { readonly index: u32; readonly threshold: u32; @@ -5013,7 +5049,7 @@ declare module '@polkadot/types/lookup' { readonly end: u64; } - /** @name PalletCollectiveError (524) */ + /** @name PalletCollectiveError (529) */ interface PalletCollectiveError extends Enum { readonly isNotMember: boolean; readonly isDuplicateProposal: boolean; @@ -5029,14 +5065,14 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotMember' | 'DuplicateProposal' | 'ProposalMissing' | 'WrongIndex' | 'DuplicateVote' | 'AlreadyInitialized' | 'TooEarly' | 'TooManyProposals' | 'WrongProposalWeight' | 'WrongProposalLength' | 'PrimeAccountNotMember'; } - /** @name PalletVestingReleases (527) */ + /** @name PalletVestingReleases (532) */ interface PalletVestingReleases extends Enum { readonly isV0: boolean; readonly isV1: boolean; readonly type: 'V0' | 'V1'; } - /** @name PalletVestingError (528) */ + /** @name PalletVestingError (533) */ interface PalletVestingError extends Enum { readonly isNotVesting: boolean; readonly isAtMaxVestingSchedules: boolean; @@ -5046,21 +5082,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotVesting' | 'AtMaxVestingSchedules' | 'AmountLow' | 'ScheduleIndexOutOfBounds' | 'InvalidScheduleParams'; } - /** @name PalletElectionsPhragmenSeatHolder (530) */ + /** @name PalletElectionsPhragmenSeatHolder (535) */ interface PalletElectionsPhragmenSeatHolder extends Struct { readonly who: AccountId32; readonly stake: u128; readonly deposit: u128; } - /** @name PalletElectionsPhragmenVoter (531) */ + /** @name PalletElectionsPhragmenVoter (536) */ interface PalletElectionsPhragmenVoter extends Struct { readonly votes: Vec; readonly stake: u128; readonly deposit: u128; } - /** @name PalletElectionsPhragmenError (532) */ + /** @name PalletElectionsPhragmenError (537) */ interface PalletElectionsPhragmenError extends Enum { readonly isUnableToVote: boolean; readonly isNoVotes: boolean; @@ -5082,20 +5118,20 @@ declare module '@polkadot/types/lookup' { readonly type: 'UnableToVote' | 'NoVotes' | 'TooManyVotes' | 'MaximumVotesExceeded' | 'LowBalance' | 'UnableToPayBond' | 'MustBeVoter' | 'DuplicatedCandidate' | 'TooManyCandidates' | 'MemberSubmit' | 'RunnerUpSubmit' | 'InsufficientCandidateFunds' | 'NotMember' | 'InvalidWitnessData' | 'InvalidVoteCount' | 'InvalidRenouncing' | 'InvalidReplacement'; } - /** @name PalletElectionProviderMultiPhaseReadySolution (533) */ + /** @name PalletElectionProviderMultiPhaseReadySolution (538) */ interface PalletElectionProviderMultiPhaseReadySolution extends Struct { readonly supports: Vec>; readonly score: SpNposElectionsElectionScore; readonly compute: PalletElectionProviderMultiPhaseElectionCompute; } - /** @name PalletElectionProviderMultiPhaseRoundSnapshot (535) */ + /** @name PalletElectionProviderMultiPhaseRoundSnapshot (540) */ interface PalletElectionProviderMultiPhaseRoundSnapshot extends Struct { readonly voters: Vec]>>; readonly targets: Vec; } - /** @name PalletElectionProviderMultiPhaseSignedSignedSubmission (542) */ + /** @name PalletElectionProviderMultiPhaseSignedSignedSubmission (547) */ interface PalletElectionProviderMultiPhaseSignedSignedSubmission extends Struct { readonly who: AccountId32; readonly deposit: u128; @@ -5103,7 +5139,7 @@ declare module '@polkadot/types/lookup' { readonly callFee: u128; } - /** @name PalletElectionProviderMultiPhaseError (543) */ + /** @name PalletElectionProviderMultiPhaseError (548) */ interface PalletElectionProviderMultiPhaseError extends Enum { readonly isPreDispatchEarlySubmission: boolean; readonly isPreDispatchWrongWinnerCount: boolean; @@ -5123,7 +5159,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PreDispatchEarlySubmission' | 'PreDispatchWrongWinnerCount' | 'PreDispatchWeakSubmission' | 'SignedQueueFull' | 'SignedCannotPayDeposit' | 'SignedInvalidWitness' | 'SignedTooMuchWeight' | 'OcwCallWrongEra' | 'MissingSnapshotMetadata' | 'InvalidSubmissionIndex' | 'CallNotAllowed' | 'FallbackFailed' | 'BoundNotMet' | 'TooManyWinners' | 'PreDispatchDifferentRound'; } - /** @name PalletStakingStakingLedger (544) */ + /** @name PalletStakingStakingLedger (549) */ interface PalletStakingStakingLedger extends Struct { readonly stash: AccountId32; readonly total: Compact; @@ -5132,20 +5168,20 @@ declare module '@polkadot/types/lookup' { readonly legacyClaimedRewards: Vec; } - /** @name PalletStakingNominations (546) */ + /** @name PalletStakingNominations (551) */ interface PalletStakingNominations extends Struct { readonly targets: Vec; readonly submittedIn: u32; readonly suppressed: bool; } - /** @name PalletStakingActiveEraInfo (547) */ + /** @name PalletStakingActiveEraInfo (552) */ interface PalletStakingActiveEraInfo extends Struct { readonly index: u32; readonly start: Option; } - /** @name SpStakingPagedExposureMetadata (549) */ + /** @name SpStakingPagedExposureMetadata (554) */ interface SpStakingPagedExposureMetadata extends Struct { readonly total: Compact; readonly own: Compact; @@ -5153,19 +5189,19 @@ declare module '@polkadot/types/lookup' { readonly pageCount: u32; } - /** @name SpStakingExposurePage (551) */ + /** @name SpStakingExposurePage (556) */ interface SpStakingExposurePage extends Struct { readonly pageTotal: Compact; readonly others: Vec; } - /** @name PalletStakingEraRewardPoints (552) */ + /** @name PalletStakingEraRewardPoints (557) */ interface PalletStakingEraRewardPoints extends Struct { readonly total: u32; readonly individual: BTreeMap; } - /** @name PalletStakingUnappliedSlash (557) */ + /** @name PalletStakingUnappliedSlash (562) */ interface PalletStakingUnappliedSlash extends Struct { readonly validator: AccountId32; readonly own: u128; @@ -5174,7 +5210,7 @@ declare module '@polkadot/types/lookup' { readonly payout: u128; } - /** @name PalletStakingSlashingSlashingSpans (561) */ + /** @name PalletStakingSlashingSlashingSpans (566) */ interface PalletStakingSlashingSlashingSpans extends Struct { readonly spanIndex: u32; readonly lastStart: u32; @@ -5182,13 +5218,13 @@ declare module '@polkadot/types/lookup' { readonly prior: Vec; } - /** @name PalletStakingSlashingSpanRecord (562) */ + /** @name PalletStakingSlashingSpanRecord (567) */ interface PalletStakingSlashingSpanRecord extends Struct { readonly slashed: u128; readonly paidOut: u128; } - /** @name PalletStakingPalletError (563) */ + /** @name PalletStakingPalletError (568) */ interface PalletStakingPalletError extends Enum { readonly isNotController: boolean; readonly isNotStash: boolean; @@ -5224,10 +5260,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotController' | 'NotStash' | 'AlreadyBonded' | 'AlreadyPaired' | 'EmptyTargets' | 'DuplicateIndex' | 'InvalidSlashIndex' | 'InsufficientBond' | 'NoMoreChunks' | 'NoUnlockChunk' | 'FundedTarget' | 'InvalidEraToReward' | 'InvalidNumberOfNominations' | 'NotSortedAndUnique' | 'AlreadyClaimed' | 'InvalidPage' | 'IncorrectHistoryDepth' | 'IncorrectSlashingSpans' | 'BadState' | 'TooManyTargets' | 'BadTarget' | 'CannotChillOther' | 'TooManyNominators' | 'TooManyValidators' | 'CommissionTooLow' | 'BoundNotMet' | 'ControllerDeprecated' | 'CannotRestoreLedger' | 'RewardDestinationRestricted' | 'NotEnoughFunds' | 'VirtualStakerNotAllowed'; } - /** @name SpCoreCryptoKeyTypeId (567) */ + /** @name SpCoreCryptoKeyTypeId (572) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (568) */ + /** @name PalletSessionError (573) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -5237,7 +5273,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidProof' | 'NoAssociatedValidatorId' | 'DuplicatedKey' | 'NoKeys' | 'NoAccount'; } - /** @name PalletTreasuryProposal (570) */ + /** @name PalletTreasuryProposal (575) */ interface PalletTreasuryProposal extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -5245,7 +5281,7 @@ declare module '@polkadot/types/lookup' { readonly bond: u128; } - /** @name PalletTreasurySpendStatus (572) */ + /** @name PalletTreasurySpendStatus (577) */ interface PalletTreasurySpendStatus extends Struct { readonly assetKind: Null; readonly amount: u128; @@ -5255,7 +5291,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletTreasuryPaymentState; } - /** @name PalletTreasuryPaymentState (573) */ + /** @name PalletTreasuryPaymentState (578) */ interface PalletTreasuryPaymentState extends Enum { readonly isPending: boolean; readonly isAttempted: boolean; @@ -5266,10 +5302,10 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pending' | 'Attempted' | 'Failed'; } - /** @name FrameSupportPalletId (574) */ + /** @name FrameSupportPalletId (579) */ interface FrameSupportPalletId extends U8aFixed {} - /** @name PalletTreasuryError (575) */ + /** @name PalletTreasuryError (580) */ interface PalletTreasuryError extends Enum { readonly isInvalidIndex: boolean; readonly isTooManyApprovals: boolean; @@ -5285,7 +5321,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidIndex' | 'TooManyApprovals' | 'InsufficientPermission' | 'ProposalNotApproved' | 'FailedToConvertBalance' | 'SpendExpired' | 'EarlyPayout' | 'AlreadyAttempted' | 'PayoutError' | 'NotAttempted' | 'Inconclusive'; } - /** @name PalletBountiesBounty (576) */ + /** @name PalletBountiesBounty (581) */ interface PalletBountiesBounty extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -5295,7 +5331,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletBountiesBountyStatus; } - /** @name PalletBountiesBountyStatus (577) */ + /** @name PalletBountiesBountyStatus (582) */ interface PalletBountiesBountyStatus extends Enum { readonly isProposed: boolean; readonly isApproved: boolean; @@ -5318,7 +5354,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Proposed' | 'Approved' | 'Funded' | 'CuratorProposed' | 'Active' | 'PendingPayout'; } - /** @name PalletBountiesError (579) */ + /** @name PalletBountiesError (584) */ interface PalletBountiesError extends Enum { readonly isInsufficientProposersBalance: boolean; readonly isInvalidIndex: boolean; @@ -5334,7 +5370,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'ReasonTooBig' | 'UnexpectedStatus' | 'RequireCurator' | 'InvalidValue' | 'InvalidFee' | 'PendingPayout' | 'Premature' | 'HasActiveChildBounty' | 'TooManyQueued'; } - /** @name PalletChildBountiesChildBounty (580) */ + /** @name PalletChildBountiesChildBounty (585) */ interface PalletChildBountiesChildBounty extends Struct { readonly parentBounty: u32; readonly value: u128; @@ -5343,7 +5379,7 @@ declare module '@polkadot/types/lookup' { readonly status: PalletChildBountiesChildBountyStatus; } - /** @name PalletChildBountiesChildBountyStatus (581) */ + /** @name PalletChildBountiesChildBountyStatus (586) */ interface PalletChildBountiesChildBountyStatus extends Enum { readonly isAdded: boolean; readonly isCuratorProposed: boolean; @@ -5363,7 +5399,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Added' | 'CuratorProposed' | 'Active' | 'PendingPayout'; } - /** @name PalletChildBountiesError (582) */ + /** @name PalletChildBountiesError (587) */ interface PalletChildBountiesError extends Enum { readonly isParentBountyNotActive: boolean; readonly isInsufficientBountyBalance: boolean; @@ -5371,7 +5407,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ParentBountyNotActive' | 'InsufficientBountyBalance' | 'TooManyChildBounties'; } - /** @name PalletBagsListListNode (583) */ + /** @name PalletBagsListListNode (588) */ interface PalletBagsListListNode extends Struct { readonly id: AccountId32; readonly prev: Option; @@ -5380,20 +5416,20 @@ declare module '@polkadot/types/lookup' { readonly score: u64; } - /** @name PalletBagsListListBag (584) */ + /** @name PalletBagsListListBag (589) */ interface PalletBagsListListBag extends Struct { readonly head: Option; readonly tail: Option; } - /** @name PalletBagsListError (585) */ + /** @name PalletBagsListError (590) */ interface PalletBagsListError extends Enum { readonly isList: boolean; readonly asList: PalletBagsListListListError; readonly type: 'List'; } - /** @name PalletBagsListListListError (586) */ + /** @name PalletBagsListListListError (591) */ interface PalletBagsListListListError extends Enum { readonly isDuplicate: boolean; readonly isNotHeavier: boolean; @@ -5402,7 +5438,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Duplicate' | 'NotHeavier' | 'NotInSameBag' | 'NodeNotFound'; } - /** @name PalletNominationPoolsPoolMember (587) */ + /** @name PalletNominationPoolsPoolMember (592) */ interface PalletNominationPoolsPoolMember extends Struct { readonly poolId: u32; readonly points: u128; @@ -5410,7 +5446,7 @@ declare module '@polkadot/types/lookup' { readonly unbondingEras: BTreeMap; } - /** @name PalletNominationPoolsBondedPoolInner (592) */ + /** @name PalletNominationPoolsBondedPoolInner (597) */ interface PalletNominationPoolsBondedPoolInner extends Struct { readonly commission: PalletNominationPoolsCommission; readonly memberCounter: u32; @@ -5419,7 +5455,7 @@ declare module '@polkadot/types/lookup' { readonly state: PalletNominationPoolsPoolState; } - /** @name PalletNominationPoolsCommission (593) */ + /** @name PalletNominationPoolsCommission (598) */ interface PalletNominationPoolsCommission extends Struct { readonly current: Option>; readonly max: Option; @@ -5428,7 +5464,7 @@ declare module '@polkadot/types/lookup' { readonly claimPermission: Option; } - /** @name PalletNominationPoolsPoolRoles (596) */ + /** @name PalletNominationPoolsPoolRoles (601) */ interface PalletNominationPoolsPoolRoles extends Struct { readonly depositor: AccountId32; readonly root: Option; @@ -5436,7 +5472,7 @@ declare module '@polkadot/types/lookup' { readonly bouncer: Option; } - /** @name PalletNominationPoolsRewardPool (597) */ + /** @name PalletNominationPoolsRewardPool (602) */ interface PalletNominationPoolsRewardPool extends Struct { readonly lastRecordedRewardCounter: u128; readonly lastRecordedTotalPayouts: u128; @@ -5445,19 +5481,19 @@ declare module '@polkadot/types/lookup' { readonly totalCommissionClaimed: u128; } - /** @name PalletNominationPoolsSubPools (598) */ + /** @name PalletNominationPoolsSubPools (603) */ interface PalletNominationPoolsSubPools extends Struct { readonly noEra: PalletNominationPoolsUnbondPool; readonly withEra: BTreeMap; } - /** @name PalletNominationPoolsUnbondPool (599) */ + /** @name PalletNominationPoolsUnbondPool (604) */ interface PalletNominationPoolsUnbondPool extends Struct { readonly points: u128; readonly balance: u128; } - /** @name PalletNominationPoolsError (604) */ + /** @name PalletNominationPoolsError (609) */ interface PalletNominationPoolsError extends Enum { readonly isPoolNotFound: boolean; readonly isPoolMemberNotFound: boolean; @@ -5500,7 +5536,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PoolNotFound' | 'PoolMemberNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'AccountBelongsToOtherPool' | 'FullyUnbonding' | 'MaxUnbondingLimit' | 'CannotWithdrawAny' | 'MinimumBondNotMet' | 'OverflowRisk' | 'NotDestroying' | 'NotNominator' | 'NotKickerOrDestroying' | 'NotOpen' | 'MaxPools' | 'MaxPoolMembers' | 'CanNotChangeState' | 'DoesNotHavePermission' | 'MetadataExceedsMaxLen' | 'Defensive' | 'PartialUnbondNotAllowedPermissionlessly' | 'MaxCommissionRestricted' | 'CommissionExceedsMaximum' | 'CommissionExceedsGlobalMaximum' | 'CommissionChangeThrottled' | 'CommissionChangeRateNotAllowed' | 'NoPendingCommission' | 'NoCommissionCurrentSet' | 'PoolIdInUse' | 'InvalidPoolId' | 'BondExtraRestricted' | 'NothingToAdjust' | 'NothingToSlash' | 'SlashTooLow' | 'AlreadyMigrated' | 'NotMigrated' | 'NotSupported'; } - /** @name PalletNominationPoolsDefensiveError (605) */ + /** @name PalletNominationPoolsDefensiveError (610) */ interface PalletNominationPoolsDefensiveError extends Enum { readonly isNotEnoughSpaceInUnbondPool: boolean; readonly isPoolNotFound: boolean; @@ -5512,7 +5548,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotEnoughSpaceInUnbondPool' | 'PoolNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'BondedStashKilledPrematurely' | 'DelegationUnsupported' | 'SlashNotApplied'; } - /** @name PalletSchedulerScheduled (608) */ + /** @name PalletSchedulerScheduled (613) */ interface PalletSchedulerScheduled extends Struct { readonly maybeId: Option; readonly priority: u8; @@ -5521,14 +5557,14 @@ declare module '@polkadot/types/lookup' { readonly origin: TangleTestnetRuntimeOriginCaller; } - /** @name PalletSchedulerRetryConfig (610) */ + /** @name PalletSchedulerRetryConfig (615) */ interface PalletSchedulerRetryConfig extends Struct { readonly totalRetries: u8; readonly remaining: u8; readonly period: u64; } - /** @name PalletSchedulerError (611) */ + /** @name PalletSchedulerError (616) */ interface PalletSchedulerError extends Enum { readonly isFailedToSchedule: boolean; readonly isNotFound: boolean; @@ -5538,7 +5574,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'FailedToSchedule' | 'NotFound' | 'TargetBlockNumberInPast' | 'RescheduleNoChange' | 'Named'; } - /** @name PalletPreimageOldRequestStatus (612) */ + /** @name PalletPreimageOldRequestStatus (617) */ interface PalletPreimageOldRequestStatus extends Enum { readonly isUnrequested: boolean; readonly asUnrequested: { @@ -5554,7 +5590,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unrequested' | 'Requested'; } - /** @name PalletPreimageRequestStatus (614) */ + /** @name PalletPreimageRequestStatus (619) */ interface PalletPreimageRequestStatus extends Enum { readonly isUnrequested: boolean; readonly asUnrequested: { @@ -5570,7 +5606,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Unrequested' | 'Requested'; } - /** @name PalletPreimageError (618) */ + /** @name PalletPreimageError (623) */ interface PalletPreimageError extends Enum { readonly isTooBig: boolean; readonly isAlreadyNoted: boolean; @@ -5584,13 +5620,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooBig' | 'AlreadyNoted' | 'NotAuthorized' | 'NotNoted' | 'Requested' | 'NotRequested' | 'TooMany' | 'TooFew' | 'NoCost'; } - /** @name SpStakingOffenceOffenceDetails (619) */ + /** @name SpStakingOffenceOffenceDetails (624) */ interface SpStakingOffenceOffenceDetails extends Struct { readonly offender: ITuple<[AccountId32, SpStakingExposure]>; readonly reporters: Vec; } - /** @name PalletTxPauseError (621) */ + /** @name PalletTxPauseError (626) */ interface PalletTxPauseError extends Enum { readonly isIsPaused: boolean; readonly isIsUnpaused: boolean; @@ -5599,34 +5635,34 @@ declare module '@polkadot/types/lookup' { readonly type: 'IsPaused' | 'IsUnpaused' | 'Unpausable' | 'NotFound'; } - /** @name PalletImOnlineError (624) */ + /** @name PalletImOnlineError (629) */ interface PalletImOnlineError extends Enum { readonly isInvalidKey: boolean; readonly isDuplicatedHeartbeat: boolean; readonly type: 'InvalidKey' | 'DuplicatedHeartbeat'; } - /** @name PalletIdentityRegistration (626) */ + /** @name PalletIdentityRegistration (631) */ interface PalletIdentityRegistration extends Struct { readonly judgements: Vec>; readonly deposit: u128; readonly info: PalletIdentityLegacyIdentityInfo; } - /** @name PalletIdentityRegistrarInfo (635) */ + /** @name PalletIdentityRegistrarInfo (640) */ interface PalletIdentityRegistrarInfo extends Struct { readonly account: AccountId32; readonly fee: u128; readonly fields: u64; } - /** @name PalletIdentityAuthorityProperties (637) */ + /** @name PalletIdentityAuthorityProperties (642) */ interface PalletIdentityAuthorityProperties extends Struct { readonly suffix: Bytes; readonly allocation: u32; } - /** @name PalletIdentityError (640) */ + /** @name PalletIdentityError (645) */ interface PalletIdentityError extends Enum { readonly isTooManySubAccounts: boolean; readonly isNotFound: boolean; @@ -5657,13 +5693,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooManySubAccounts' | 'NotFound' | 'NotNamed' | 'EmptyIndex' | 'FeeChanged' | 'NoIdentity' | 'StickyJudgement' | 'JudgementGiven' | 'InvalidJudgement' | 'InvalidIndex' | 'InvalidTarget' | 'TooManyRegistrars' | 'AlreadyClaimed' | 'NotSub' | 'NotOwned' | 'JudgementForDifferentIdentity' | 'JudgementPaymentFailed' | 'InvalidSuffix' | 'NotUsernameAuthority' | 'NoAllocation' | 'InvalidSignature' | 'RequiresSignature' | 'InvalidUsername' | 'UsernameTaken' | 'NoUsername' | 'NotExpired'; } - /** @name PalletUtilityError (641) */ + /** @name PalletUtilityError (646) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: 'TooManyCalls'; } - /** @name PalletMultisigMultisig (643) */ + /** @name PalletMultisigMultisig (648) */ interface PalletMultisigMultisig extends Struct { readonly when: PalletMultisigTimepoint; readonly deposit: u128; @@ -5671,7 +5707,7 @@ declare module '@polkadot/types/lookup' { readonly approvals: Vec; } - /** @name PalletMultisigError (644) */ + /** @name PalletMultisigError (649) */ interface PalletMultisigError extends Enum { readonly isMinimumThreshold: boolean; readonly isAlreadyApproved: boolean; @@ -5690,7 +5726,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'MinimumThreshold' | 'AlreadyApproved' | 'NoApprovalsNeeded' | 'TooFewSignatories' | 'TooManySignatories' | 'SignatoriesOutOfOrder' | 'SenderInSignatories' | 'NotFound' | 'NotOwner' | 'NoTimepoint' | 'WrongTimepoint' | 'UnexpectedTimepoint' | 'MaxWeightTooLow' | 'AlreadyStored'; } - /** @name FpRpcTransactionStatus (647) */ + /** @name FpRpcTransactionStatus (652) */ interface FpRpcTransactionStatus extends Struct { readonly transactionHash: H256; readonly transactionIndex: u32; @@ -5701,10 +5737,10 @@ declare module '@polkadot/types/lookup' { readonly logsBloom: EthbloomBloom; } - /** @name EthbloomBloom (649) */ + /** @name EthbloomBloom (654) */ interface EthbloomBloom extends U8aFixed {} - /** @name EthereumReceiptReceiptV3 (651) */ + /** @name EthereumReceiptReceiptV3 (656) */ interface EthereumReceiptReceiptV3 extends Enum { readonly isLegacy: boolean; readonly asLegacy: EthereumReceiptEip658ReceiptData; @@ -5715,7 +5751,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Legacy' | 'Eip2930' | 'Eip1559'; } - /** @name EthereumReceiptEip658ReceiptData (652) */ + /** @name EthereumReceiptEip658ReceiptData (657) */ interface EthereumReceiptEip658ReceiptData extends Struct { readonly statusCode: u8; readonly usedGas: U256; @@ -5723,14 +5759,14 @@ declare module '@polkadot/types/lookup' { readonly logs: Vec; } - /** @name EthereumBlock (653) */ + /** @name EthereumBlock (658) */ interface EthereumBlock extends Struct { readonly header: EthereumHeader; readonly transactions: Vec; readonly ommers: Vec; } - /** @name EthereumHeader (654) */ + /** @name EthereumHeader (659) */ interface EthereumHeader extends Struct { readonly parentHash: H256; readonly ommersHash: H256; @@ -5749,23 +5785,23 @@ declare module '@polkadot/types/lookup' { readonly nonce: EthereumTypesHashH64; } - /** @name EthereumTypesHashH64 (655) */ + /** @name EthereumTypesHashH64 (660) */ interface EthereumTypesHashH64 extends U8aFixed {} - /** @name PalletEthereumError (660) */ + /** @name PalletEthereumError (665) */ interface PalletEthereumError extends Enum { readonly isInvalidSignature: boolean; readonly isPreLogExists: boolean; readonly type: 'InvalidSignature' | 'PreLogExists'; } - /** @name PalletEvmCodeMetadata (661) */ + /** @name PalletEvmCodeMetadata (666) */ interface PalletEvmCodeMetadata extends Struct { readonly size_: u64; readonly hash_: H256; } - /** @name PalletEvmError (663) */ + /** @name PalletEvmError (668) */ interface PalletEvmError extends Enum { readonly isBalanceLow: boolean; readonly isFeeOverflow: boolean; @@ -5783,13 +5819,13 @@ declare module '@polkadot/types/lookup' { readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'InvalidChainId' | 'InvalidSignature' | 'Reentrancy' | 'TransactionMustComeFromEOA' | 'Undefined'; } - /** @name PalletHotfixSufficientsError (664) */ + /** @name PalletHotfixSufficientsError (669) */ interface PalletHotfixSufficientsError extends Enum { readonly isMaxAddressCountExceeded: boolean; readonly type: 'MaxAddressCountExceeded'; } - /** @name PalletAirdropClaimsError (666) */ + /** @name PalletAirdropClaimsError (671) */ interface PalletAirdropClaimsError extends Enum { readonly isInvalidEthereumSignature: boolean; readonly isInvalidNativeSignature: boolean; @@ -5802,21 +5838,21 @@ declare module '@polkadot/types/lookup' { readonly type: 'InvalidEthereumSignature' | 'InvalidNativeSignature' | 'InvalidNativeAccount' | 'SignerHasNoClaim' | 'SenderHasNoClaim' | 'PotUnderflow' | 'InvalidStatement' | 'VestedBalanceExists'; } - /** @name PalletProxyProxyDefinition (669) */ + /** @name PalletProxyProxyDefinition (674) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: TangleTestnetRuntimeProxyType; readonly delay: u64; } - /** @name PalletProxyAnnouncement (673) */ + /** @name PalletProxyAnnouncement (678) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u64; } - /** @name PalletProxyError (675) */ + /** @name PalletProxyError (680) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -5829,7 +5865,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'TooMany' | 'NotFound' | 'NotProxy' | 'Unproxyable' | 'Duplicate' | 'NoPermission' | 'Unannounced' | 'NoSelfProxy'; } - /** @name PalletMultiAssetDelegationOperatorOperatorMetadata (676) */ + /** @name PalletMultiAssetDelegationOperatorOperatorMetadata (681) */ interface PalletMultiAssetDelegationOperatorOperatorMetadata extends Struct { readonly stake: u128; readonly delegationCount: u32; @@ -5839,26 +5875,26 @@ declare module '@polkadot/types/lookup' { readonly blueprintIds: Vec; } - /** @name TangleTestnetRuntimeMaxDelegations (677) */ + /** @name TangleTestnetRuntimeMaxDelegations (682) */ type TangleTestnetRuntimeMaxDelegations = Null; - /** @name TangleTestnetRuntimeMaxOperatorBlueprints (678) */ + /** @name TangleTestnetRuntimeMaxOperatorBlueprints (683) */ type TangleTestnetRuntimeMaxOperatorBlueprints = Null; - /** @name PalletMultiAssetDelegationOperatorOperatorBondLessRequest (680) */ + /** @name PalletMultiAssetDelegationOperatorOperatorBondLessRequest (685) */ interface PalletMultiAssetDelegationOperatorOperatorBondLessRequest extends Struct { readonly amount: u128; readonly requestTime: u32; } - /** @name PalletMultiAssetDelegationOperatorDelegatorBond (682) */ + /** @name PalletMultiAssetDelegationOperatorDelegatorBond (687) */ interface PalletMultiAssetDelegationOperatorDelegatorBond extends Struct { readonly delegator: AccountId32; readonly amount: u128; readonly assetId: TanglePrimitivesServicesAsset; } - /** @name PalletMultiAssetDelegationOperatorOperatorStatus (684) */ + /** @name PalletMultiAssetDelegationOperatorOperatorStatus (689) */ interface PalletMultiAssetDelegationOperatorOperatorStatus extends Enum { readonly isActive: boolean; readonly isInactive: boolean; @@ -5867,35 +5903,49 @@ declare module '@polkadot/types/lookup' { readonly type: 'Active' | 'Inactive' | 'Leaving'; } - /** @name PalletMultiAssetDelegationOperatorOperatorSnapshot (686) */ + /** @name PalletMultiAssetDelegationOperatorOperatorSnapshot (691) */ interface PalletMultiAssetDelegationOperatorOperatorSnapshot extends Struct { readonly stake: u128; readonly delegations: Vec; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorMetadata (687) */ + /** @name PalletMultiAssetDelegationDelegatorDelegatorMetadata (692) */ interface PalletMultiAssetDelegationDelegatorDelegatorMetadata extends Struct { - readonly deposits: BTreeMap; + readonly deposits: BTreeMap; readonly withdrawRequests: Vec; readonly delegations: Vec; readonly delegatorUnstakeRequests: Vec; readonly status: PalletMultiAssetDelegationDelegatorDelegatorStatus; } - /** @name TangleTestnetRuntimeMaxWithdrawRequests (688) */ + /** @name TangleTestnetRuntimeMaxWithdrawRequests (693) */ type TangleTestnetRuntimeMaxWithdrawRequests = Null; - /** @name TangleTestnetRuntimeMaxUnstakeRequests (689) */ + /** @name TangleTestnetRuntimeMaxUnstakeRequests (694) */ type TangleTestnetRuntimeMaxUnstakeRequests = Null; - /** @name PalletMultiAssetDelegationDelegatorWithdrawRequest (694) */ + /** @name PalletMultiAssetDelegationDelegatorDeposit (696) */ + interface PalletMultiAssetDelegationDelegatorDeposit extends Struct { + readonly amount: u128; + readonly delegatedAmount: u128; + readonly locks: Option>; + } + + /** @name TanglePrimitivesRewardsLockInfo (699) */ + interface TanglePrimitivesRewardsLockInfo extends Struct { + readonly amount: u128; + readonly lockMultiplier: TanglePrimitivesRewardsLockMultiplier; + readonly expiryBlock: u64; + } + + /** @name PalletMultiAssetDelegationDelegatorWithdrawRequest (704) */ interface PalletMultiAssetDelegationDelegatorWithdrawRequest extends Struct { readonly assetId: TanglePrimitivesServicesAsset; readonly amount: u128; readonly requestedRound: u32; } - /** @name PalletMultiAssetDelegationDelegatorBondInfoDelegator (697) */ + /** @name PalletMultiAssetDelegationDelegatorBondInfoDelegator (707) */ interface PalletMultiAssetDelegationDelegatorBondInfoDelegator extends Struct { readonly operator: AccountId32; readonly amount: u128; @@ -5903,7 +5953,7 @@ declare module '@polkadot/types/lookup' { readonly blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; } - /** @name PalletMultiAssetDelegationDelegatorBondLessRequest (700) */ + /** @name PalletMultiAssetDelegationDelegatorBondLessRequest (710) */ interface PalletMultiAssetDelegationDelegatorBondLessRequest extends Struct { readonly operator: AccountId32; readonly assetId: TanglePrimitivesServicesAsset; @@ -5912,7 +5962,7 @@ declare module '@polkadot/types/lookup' { readonly blueprintSelection: PalletMultiAssetDelegationDelegatorDelegatorBlueprintSelection; } - /** @name PalletMultiAssetDelegationDelegatorDelegatorStatus (702) */ + /** @name PalletMultiAssetDelegationDelegatorDelegatorStatus (712) */ interface PalletMultiAssetDelegationDelegatorDelegatorStatus extends Enum { readonly isActive: boolean; readonly isLeavingScheduled: boolean; @@ -5920,19 +5970,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Active' | 'LeavingScheduled'; } - /** @name PalletMultiAssetDelegationRewardsRewardConfig (704) */ - interface PalletMultiAssetDelegationRewardsRewardConfig extends Struct { - readonly configs: BTreeMap; - readonly whitelistedBlueprintIds: Vec; - } - - /** @name PalletMultiAssetDelegationRewardsRewardConfigForAssetVault (706) */ - interface PalletMultiAssetDelegationRewardsRewardConfigForAssetVault extends Struct { - readonly apy: Percent; - readonly cap: u128; - } - - /** @name PalletMultiAssetDelegationError (709) */ + /** @name PalletMultiAssetDelegationError (713) */ interface PalletMultiAssetDelegationError extends Enum { readonly isAlreadyOperator: boolean; readonly isBondTooLow: boolean; @@ -5984,10 +6022,12 @@ declare module '@polkadot/types/lookup' { readonly isErc20TransferFailed: boolean; readonly isEvmAbiEncode: boolean; readonly isEvmAbiDecode: boolean; - readonly type: 'AlreadyOperator' | 'BondTooLow' | 'NotAnOperator' | 'CannotExit' | 'AlreadyLeaving' | 'NotLeavingOperator' | 'NotLeavingRound' | 'LeavingRoundNotReached' | 'NoScheduledBondLess' | 'BondLessRequestNotSatisfied' | 'NotActiveOperator' | 'NotOfflineOperator' | 'AlreadyDelegator' | 'NotDelegator' | 'WithdrawRequestAlreadyExists' | 'InsufficientBalance' | 'NoWithdrawRequest' | 'NoBondLessRequest' | 'BondLessNotReady' | 'BondLessRequestAlreadyExists' | 'ActiveServicesUsingAsset' | 'NoActiveDelegation' | 'AssetNotWhitelisted' | 'NotAuthorized' | 'MaxBlueprintsExceeded' | 'AssetNotFound' | 'BlueprintAlreadyWhitelisted' | 'NowithdrawRequests' | 'NoMatchingwithdrawRequest' | 'AssetAlreadyInVault' | 'AssetNotInVault' | 'VaultNotFound' | 'DuplicateBlueprintId' | 'BlueprintIdNotFound' | 'NotInFixedMode' | 'MaxDelegationsExceeded' | 'MaxUnstakeRequestsExceeded' | 'MaxWithdrawRequestsExceeded' | 'DepositOverflow' | 'UnstakeAmountTooLarge' | 'StakeOverflow' | 'InsufficientStakeRemaining' | 'ApyExceedsMaximum' | 'CapCannotBeZero' | 'CapExceedsTotalSupply' | 'PendingUnstakeRequestExists' | 'BlueprintNotSelected' | 'Erc20TransferFailed' | 'EvmAbiEncode' | 'EvmAbiDecode'; + readonly isLockViolation: boolean; + readonly isDepositExceedsCapForAsset: boolean; + readonly type: 'AlreadyOperator' | 'BondTooLow' | 'NotAnOperator' | 'CannotExit' | 'AlreadyLeaving' | 'NotLeavingOperator' | 'NotLeavingRound' | 'LeavingRoundNotReached' | 'NoScheduledBondLess' | 'BondLessRequestNotSatisfied' | 'NotActiveOperator' | 'NotOfflineOperator' | 'AlreadyDelegator' | 'NotDelegator' | 'WithdrawRequestAlreadyExists' | 'InsufficientBalance' | 'NoWithdrawRequest' | 'NoBondLessRequest' | 'BondLessNotReady' | 'BondLessRequestAlreadyExists' | 'ActiveServicesUsingAsset' | 'NoActiveDelegation' | 'AssetNotWhitelisted' | 'NotAuthorized' | 'MaxBlueprintsExceeded' | 'AssetNotFound' | 'BlueprintAlreadyWhitelisted' | 'NowithdrawRequests' | 'NoMatchingwithdrawRequest' | 'AssetAlreadyInVault' | 'AssetNotInVault' | 'VaultNotFound' | 'DuplicateBlueprintId' | 'BlueprintIdNotFound' | 'NotInFixedMode' | 'MaxDelegationsExceeded' | 'MaxUnstakeRequestsExceeded' | 'MaxWithdrawRequestsExceeded' | 'DepositOverflow' | 'UnstakeAmountTooLarge' | 'StakeOverflow' | 'InsufficientStakeRemaining' | 'ApyExceedsMaximum' | 'CapCannotBeZero' | 'CapExceedsTotalSupply' | 'PendingUnstakeRequestExists' | 'BlueprintNotSelected' | 'Erc20TransferFailed' | 'EvmAbiEncode' | 'EvmAbiDecode' | 'LockViolation' | 'DepositExceedsCapForAsset'; } - /** @name TanglePrimitivesServicesServiceRequest (712) */ + /** @name TanglePrimitivesServicesServiceRequest (716) */ interface TanglePrimitivesServicesServiceRequest extends Struct { readonly blueprint: u64; readonly owner: AccountId32; @@ -5998,7 +6038,7 @@ declare module '@polkadot/types/lookup' { readonly operatorsWithApprovalState: Vec>; } - /** @name TanglePrimitivesServicesApprovalState (718) */ + /** @name TanglePrimitivesServicesApprovalState (722) */ interface TanglePrimitivesServicesApprovalState extends Enum { readonly isPending: boolean; readonly isApproved: boolean; @@ -6009,7 +6049,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Pending' | 'Approved' | 'Rejected'; } - /** @name TanglePrimitivesServicesService (720) */ + /** @name TanglePrimitivesServicesService (724) */ interface TanglePrimitivesServicesService extends Struct { readonly id: u64; readonly blueprint: u64; @@ -6020,21 +6060,21 @@ declare module '@polkadot/types/lookup' { readonly ttl: u64; } - /** @name TanglePrimitivesServicesJobCall (726) */ + /** @name TanglePrimitivesServicesJobCall (730) */ interface TanglePrimitivesServicesJobCall extends Struct { readonly serviceId: u64; readonly job: u8; readonly args: Vec; } - /** @name TanglePrimitivesServicesJobCallResult (727) */ + /** @name TanglePrimitivesServicesJobCallResult (731) */ interface TanglePrimitivesServicesJobCallResult extends Struct { readonly serviceId: u64; readonly callId: u64; readonly result: Vec; } - /** @name PalletServicesUnappliedSlash (728) */ + /** @name PalletServicesUnappliedSlash (732) */ interface PalletServicesUnappliedSlash extends Struct { readonly serviceId: u64; readonly operator: AccountId32; @@ -6044,13 +6084,13 @@ declare module '@polkadot/types/lookup' { readonly payout: u128; } - /** @name TanglePrimitivesServicesOperatorProfile (730) */ + /** @name TanglePrimitivesServicesOperatorProfile (734) */ interface TanglePrimitivesServicesOperatorProfile extends Struct { readonly services: BTreeSet; readonly blueprints: BTreeSet; } - /** @name TanglePrimitivesServicesStagingServicePayment (733) */ + /** @name TanglePrimitivesServicesStagingServicePayment (737) */ interface TanglePrimitivesServicesStagingServicePayment extends Struct { readonly requestId: u64; readonly refundTo: TanglePrimitivesAccount; @@ -6058,7 +6098,7 @@ declare module '@polkadot/types/lookup' { readonly amount: u128; } - /** @name TanglePrimitivesAccount (734) */ + /** @name TanglePrimitivesAccount (738) */ interface TanglePrimitivesAccount extends Enum { readonly isId: boolean; readonly asId: AccountId32; @@ -6067,7 +6107,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Id' | 'Address'; } - /** @name PalletServicesModuleError (735) */ + /** @name PalletServicesModuleError (739) */ interface PalletServicesModuleError extends Enum { readonly isBlueprintNotFound: boolean; readonly isBlueprintCreationInterrupted: boolean; @@ -6116,7 +6156,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'BlueprintNotFound' | 'BlueprintCreationInterrupted' | 'AlreadyRegistered' | 'InvalidRegistrationInput' | 'NotAllowedToUnregister' | 'NotAllowedToUpdatePriceTargets' | 'InvalidRequestInput' | 'InvalidJobCallInput' | 'InvalidJobResult' | 'NotRegistered' | 'ApprovalInterrupted' | 'RejectionInterrupted' | 'ServiceRequestNotFound' | 'ServiceInitializationInterrupted' | 'ServiceNotFound' | 'TerminationInterrupted' | 'TypeCheck' | 'MaxPermittedCallersExceeded' | 'MaxServiceProvidersExceeded' | 'MaxServicesPerUserExceeded' | 'MaxFieldsExceeded' | 'ApprovalNotRequested' | 'JobDefinitionNotFound' | 'ServiceOrJobCallNotFound' | 'JobCallResultNotFound' | 'EvmAbiEncode' | 'EvmAbiDecode' | 'OperatorProfileNotFound' | 'MaxServicesPerProviderExceeded' | 'OperatorNotActive' | 'NoAssetsProvided' | 'MaxAssetsPerServiceExceeded' | 'OffenderNotOperator' | 'OffenderNotActiveOperator' | 'NoSlashingOrigin' | 'NoDisputeOrigin' | 'UnappliedSlashNotFound' | 'MasterBlueprintServiceManagerRevisionNotFound' | 'MaxMasterBlueprintServiceManagerVersionsExceeded' | 'Erc20TransferFailed' | 'MissingEVMOrigin' | 'ExpectedEVMAddress' | 'ExpectedAccountId'; } - /** @name TanglePrimitivesServicesTypeCheckError (736) */ + /** @name TanglePrimitivesServicesTypeCheckError (740) */ interface TanglePrimitivesServicesTypeCheckError extends Enum { readonly isArgumentTypeMismatch: boolean; readonly asArgumentTypeMismatch: { @@ -6138,7 +6178,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'ArgumentTypeMismatch' | 'NotEnoughArguments' | 'ResultTypeMismatch'; } - /** @name PalletTangleLstBondedPoolBondedPoolInner (737) */ + /** @name PalletTangleLstBondedPoolBondedPoolInner (741) */ interface PalletTangleLstBondedPoolBondedPoolInner extends Struct { readonly commission: PalletTangleLstCommission; readonly roles: PalletTangleLstPoolsPoolRoles; @@ -6146,7 +6186,7 @@ declare module '@polkadot/types/lookup' { readonly metadata: PalletTangleLstBondedPoolPoolMetadata; } - /** @name PalletTangleLstCommission (738) */ + /** @name PalletTangleLstCommission (742) */ interface PalletTangleLstCommission extends Struct { readonly current: Option>; readonly max: Option; @@ -6155,7 +6195,7 @@ declare module '@polkadot/types/lookup' { readonly claimPermission: Option; } - /** @name PalletTangleLstPoolsPoolRoles (740) */ + /** @name PalletTangleLstPoolsPoolRoles (744) */ interface PalletTangleLstPoolsPoolRoles extends Struct { readonly depositor: AccountId32; readonly root: Option; @@ -6163,13 +6203,13 @@ declare module '@polkadot/types/lookup' { readonly bouncer: Option; } - /** @name PalletTangleLstBondedPoolPoolMetadata (741) */ + /** @name PalletTangleLstBondedPoolPoolMetadata (745) */ interface PalletTangleLstBondedPoolPoolMetadata extends Struct { readonly name: Option; readonly icon: Option; } - /** @name PalletTangleLstSubPoolsRewardPool (742) */ + /** @name PalletTangleLstSubPoolsRewardPool (746) */ interface PalletTangleLstSubPoolsRewardPool extends Struct { readonly lastRecordedRewardCounter: u128; readonly lastRecordedTotalPayouts: u128; @@ -6178,24 +6218,24 @@ declare module '@polkadot/types/lookup' { readonly totalCommissionClaimed: u128; } - /** @name PalletTangleLstSubPools (743) */ + /** @name PalletTangleLstSubPools (747) */ interface PalletTangleLstSubPools extends Struct { readonly noEra: PalletTangleLstSubPoolsUnbondPool; readonly withEra: BTreeMap; } - /** @name PalletTangleLstSubPoolsUnbondPool (744) */ + /** @name PalletTangleLstSubPoolsUnbondPool (748) */ interface PalletTangleLstSubPoolsUnbondPool extends Struct { readonly points: u128; readonly balance: u128; } - /** @name PalletTangleLstPoolsPoolMember (750) */ + /** @name PalletTangleLstPoolsPoolMember (754) */ interface PalletTangleLstPoolsPoolMember extends Struct { readonly unbondingEras: BTreeMap>; } - /** @name PalletTangleLstClaimPermission (755) */ + /** @name PalletTangleLstClaimPermission (759) */ interface PalletTangleLstClaimPermission extends Enum { readonly isPermissioned: boolean; readonly isPermissionlessCompound: boolean; @@ -6204,7 +6244,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'Permissioned' | 'PermissionlessCompound' | 'PermissionlessWithdraw' | 'PermissionlessAll'; } - /** @name PalletTangleLstError (756) */ + /** @name PalletTangleLstError (760) */ interface PalletTangleLstError extends Enum { readonly isPoolNotFound: boolean; readonly isPoolMemberNotFound: boolean; @@ -6243,7 +6283,7 @@ declare module '@polkadot/types/lookup' { readonly type: 'PoolNotFound' | 'PoolMemberNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'FullyUnbonding' | 'MaxUnbondingLimit' | 'CannotWithdrawAny' | 'MinimumBondNotMet' | 'OverflowRisk' | 'NotDestroying' | 'NotNominator' | 'NotKickerOrDestroying' | 'NotOpen' | 'MaxPools' | 'MaxPoolMembers' | 'CanNotChangeState' | 'DoesNotHavePermission' | 'MetadataExceedsMaxLen' | 'Defensive' | 'PartialUnbondNotAllowedPermissionlessly' | 'MaxCommissionRestricted' | 'CommissionExceedsMaximum' | 'CommissionExceedsGlobalMaximum' | 'CommissionChangeThrottled' | 'CommissionChangeRateNotAllowed' | 'NoPendingCommission' | 'NoCommissionCurrentSet' | 'PoolIdInUse' | 'InvalidPoolId' | 'BondExtraRestricted' | 'NothingToAdjust' | 'PoolTokenCreationFailed' | 'NoBalanceToUnbond'; } - /** @name PalletTangleLstDefensiveError (757) */ + /** @name PalletTangleLstDefensiveError (761) */ interface PalletTangleLstDefensiveError extends Enum { readonly isNotEnoughSpaceInUnbondPool: boolean; readonly isPoolNotFound: boolean; @@ -6253,40 +6293,57 @@ declare module '@polkadot/types/lookup' { readonly type: 'NotEnoughSpaceInUnbondPool' | 'PoolNotFound' | 'RewardPoolNotFound' | 'SubPoolsNotFound' | 'BondedStashKilledPrematurely'; } - /** @name FrameSystemExtensionsCheckNonZeroSender (760) */ + /** @name PalletRewardsError (765) */ + interface PalletRewardsError extends Enum { + readonly isNoRewardsAvailable: boolean; + readonly isInsufficientRewardsBalance: boolean; + readonly isAssetNotWhitelisted: boolean; + readonly isAssetAlreadyWhitelisted: boolean; + readonly isInvalidAPY: boolean; + readonly isAssetAlreadyInVault: boolean; + readonly isAssetNotInVault: boolean; + readonly isVaultNotFound: boolean; + readonly isDuplicateBlueprintId: boolean; + readonly isBlueprintIdNotFound: boolean; + readonly isRewardConfigNotFound: boolean; + readonly isArithmeticError: boolean; + readonly type: 'NoRewardsAvailable' | 'InsufficientRewardsBalance' | 'AssetNotWhitelisted' | 'AssetAlreadyWhitelisted' | 'InvalidAPY' | 'AssetAlreadyInVault' | 'AssetNotInVault' | 'VaultNotFound' | 'DuplicateBlueprintId' | 'BlueprintIdNotFound' | 'RewardConfigNotFound' | 'ArithmeticError'; + } + + /** @name FrameSystemExtensionsCheckNonZeroSender (768) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (761) */ + /** @name FrameSystemExtensionsCheckSpecVersion (769) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (762) */ + /** @name FrameSystemExtensionsCheckTxVersion (770) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (763) */ + /** @name FrameSystemExtensionsCheckGenesis (771) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (766) */ + /** @name FrameSystemExtensionsCheckNonce (774) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (767) */ + /** @name FrameSystemExtensionsCheckWeight (775) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (768) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (776) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name FrameMetadataHashExtensionCheckMetadataHash (769) */ + /** @name FrameMetadataHashExtensionCheckMetadataHash (777) */ interface FrameMetadataHashExtensionCheckMetadataHash extends Struct { readonly mode: FrameMetadataHashExtensionMode; } - /** @name FrameMetadataHashExtensionMode (770) */ + /** @name FrameMetadataHashExtensionMode (778) */ interface FrameMetadataHashExtensionMode extends Enum { readonly isDisabled: boolean; readonly isEnabled: boolean; readonly type: 'Disabled' | 'Enabled'; } - /** @name TangleTestnetRuntimeRuntime (772) */ + /** @name TangleTestnetRuntimeRuntime (780) */ type TangleTestnetRuntimeRuntime = Null; } // declare module diff --git a/types/src/metadata.json b/types/src/metadata.json index 802c6f66..23386031 100644 --- a/types/src/metadata.json +++ b/types/src/metadata.json @@ -1 +1 @@ -{"jsonrpc":"2.0","result":"0x6d6574610e150c000c1c73705f636f72651863727970746f2c4163636f756e7449643332000004000401205b75383b2033325d0000040000032000000008000800000503000c08306672616d655f73797374656d2c4163636f756e74496e666f08144e6f6e636501102c4163636f756e74446174610114001401146e6f6e63651001144e6f6e6365000124636f6e73756d657273100120526566436f756e7400012470726f766964657273100120526566436f756e7400012c73756666696369656e7473100120526566436f756e740001106461746114012c4163636f756e74446174610000100000050500140c3c70616c6c65745f62616c616e6365731474797065732c4163636f756e7444617461041c42616c616e63650118001001106672656518011c42616c616e6365000120726573657276656418011c42616c616e636500011866726f7a656e18011c42616c616e6365000114666c6167731c01284578747261466c61677300001800000507001c0c3c70616c6c65745f62616c616e636573147479706573284578747261466c61677300000400180110753132380000200000050000240c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540128000c01186e6f726d616c2801045400012c6f7065726174696f6e616c280104540001246d616e6461746f7279280104540000280c2873705f77656967687473247765696768745f76321857656967687400000801207265665f74696d652c010c75363400012870726f6f665f73697a652c010c75363400002c000006300030000005060034083c7072696d69746976655f74797065731048323536000004000401205b75383b2033325d00003800000208003c102873705f72756e74696d651c67656e65726963186469676573741844696765737400000401106c6f677340013c5665633c4469676573744974656d3e000040000002440044102873705f72756e74696d651c67656e6572696318646967657374284469676573744974656d0001142850726552756e74696d650800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e00060024436f6e73656e7375730800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000400105365616c0800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000500144f74686572040038011c5665633c75383e0000006452756e74696d65456e7669726f6e6d656e745570646174656400080000480000030400000008004c00000250005008306672616d655f73797374656d2c4576656e745265636f7264080445015404540134000c011470686173655902011450686173650001146576656e7454010445000118746f70696373c10101185665633c543e000054085874616e676c655f746573746e65745f72756e74696d653052756e74696d654576656e7400018c1853797374656d04005801706672616d655f73797374656d3a3a4576656e743c52756e74696d653e000100105375646f04007c016c70616c6c65745f7375646f3a3a4576656e743c52756e74696d653e0003001841737365747304008c017470616c6c65745f6173736574733a3a4576656e743c52756e74696d653e0005002042616c616e636573040090017c70616c6c65745f62616c616e6365733a3a4576656e743c52756e74696d653e000600485472616e73616374696f6e5061796d656e7404009801a870616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4576656e743c52756e74696d653e0007001c4772616e64706104009c015470616c6c65745f6772616e6470613a3a4576656e74000a001c496e64696365730400ac017870616c6c65745f696e64696365733a3a4576656e743c52756e74696d653e000b002444656d6f63726163790400b0018070616c6c65745f64656d6f63726163793a3a4576656e743c52756e74696d653e000c001c436f756e63696c0400c401fc70616c6c65745f636f6c6c6563746976653a3a4576656e743c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d001c56657374696e670400c8017870616c6c65745f76657374696e673a3a4576656e743c52756e74696d653e000e0024456c656374696f6e730400cc01a470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4576656e743c52756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400d801d070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a4576656e743c52756e74696d653e0010001c5374616b696e670400ec017870616c6c65745f7374616b696e673a3a4576656e743c52756e74696d653e0011001c53657373696f6e04000501015470616c6c65745f73657373696f6e3a3a4576656e7400120020547265617375727904000901017c70616c6c65745f74726561737572793a3a4576656e743c52756e74696d653e00140020426f756e7469657304000d01017c70616c6c65745f626f756e746965733a3a4576656e743c52756e74696d653e001500344368696c64426f756e7469657304001101019470616c6c65745f6368696c645f626f756e746965733a3a4576656e743c52756e74696d653e00160020426167734c69737404001501018070616c6c65745f626167735f6c6973743a3a4576656e743c52756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304001901019c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a4576656e743c52756e74696d653e001800245363686564756c657204003501018070616c6c65745f7363686564756c65723a3a4576656e743c52756e74696d653e00190020507265696d61676504004101017c70616c6c65745f707265696d6167653a3a4576656e743c52756e74696d653e001a00204f6666656e63657304004501015870616c6c65745f6f6666656e6365733a3a4576656e74001b001c5478506175736504004d01017c70616c6c65745f74785f70617573653a3a4576656e743c52756e74696d653e001c0020496d4f6e6c696e6504005901018070616c6c65745f696d5f6f6e6c696e653a3a4576656e743c52756e74696d653e001d00204964656e7469747904007901017c70616c6c65745f6964656e746974793a3a4576656e743c52756e74696d653e001e001c5574696c69747904008101015470616c6c65745f7574696c6974793a3a4576656e74001f00204d756c746973696704008501017c70616c6c65745f6d756c74697369673a3a4576656e743c52756e74696d653e00200020457468657265756d04008d01015870616c6c65745f657468657265756d3a3a4576656e740021000c45564d0400b901016870616c6c65745f65766d3a3a4576656e743c52756e74696d653e0022001c426173654665650400c501015870616c6c65745f626173655f6665653a3a4576656e7400250018436c61696d730400d501019470616c6c65745f61697264726f705f636c61696d733a3a4576656e743c52756e74696d653e0027001450726f78790400e101017070616c6c65745f70726f78793a3a4576656e743c52756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400ed0101b470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e3a3a4576656e743c52756e74696d653e002d002053657276696365730400fd01017c70616c6c65745f73657276696365733a3a4576656e743c52756e74696d653e0033000c4c737404004502018470616c6c65745f74616e676c655f6c73743a3a4576656e743c52756e74696d653e00340000580c306672616d655f73797374656d1870616c6c6574144576656e7404045400011c4045787472696e7369635375636365737304013464697370617463685f696e666f5c01304469737061746368496e666f00000490416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e3c45787472696e7369634661696c656408013864697370617463685f6572726f7268013444697370617463684572726f7200013464697370617463685f696e666f5c01304469737061746368496e666f00010450416e2065787472696e736963206661696c65642e2c436f64655570646174656400020450603a636f6465602077617320757064617465642e284e65774163636f756e7404011c6163636f756e74000130543a3a4163636f756e7449640003046841206e6577206163636f756e742077617320637265617465642e344b696c6c65644163636f756e7404011c6163636f756e74000130543a3a4163636f756e74496400040458416e206163636f756e7420776173207265617065642e2052656d61726b656408011873656e646572000130543a3a4163636f756e7449640001106861736834011c543a3a48617368000504704f6e206f6e2d636861696e2072656d61726b2068617070656e65642e4455706772616465417574686f72697a6564080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00060468416e20757067726164652077617320617574686f72697a65642e04704576656e7420666f72207468652053797374656d2070616c6c65742e5c0c346672616d655f737570706f7274206469737061746368304469737061746368496e666f00000c0118776569676874280118576569676874000114636c6173736001344469737061746368436c617373000120706179735f666565640110506179730000600c346672616d655f737570706f7274206469737061746368344469737061746368436c61737300010c184e6f726d616c0000002c4f7065726174696f6e616c000100244d616e6461746f727900020000640c346672616d655f737570706f727420646973706174636810506179730001080c596573000000084e6f0001000068082873705f72756e74696d653444697370617463684572726f72000138144f746865720000003043616e6e6f744c6f6f6b7570000100244261644f726967696e000200184d6f64756c6504006c012c4d6f64756c654572726f7200030044436f6e73756d657252656d61696e696e670004002c4e6f50726f76696465727300050040546f6f4d616e79436f6e73756d65727300060014546f6b656e0400700128546f6b656e4572726f720007002841726974686d65746963040074013c41726974686d657469634572726f72000800345472616e73616374696f6e616c04007801485472616e73616374696f6e616c4572726f7200090024457868617573746564000a0028436f7272757074696f6e000b002c556e617661696c61626c65000c0038526f6f744e6f74416c6c6f776564000d00006c082873705f72756e74696d652c4d6f64756c654572726f720000080114696e64657808010875380001146572726f7248018c5b75383b204d41585f4d4f44554c455f4552524f525f454e434f4445445f53495a455d000070082873705f72756e74696d6528546f6b656e4572726f720001284046756e6473556e617661696c61626c65000000304f6e6c7950726f76696465720001003042656c6f774d696e696d756d0002003043616e6e6f7443726561746500030030556e6b6e6f776e41737365740004001846726f7a656e0005002c556e737570706f727465640006004043616e6e6f74437265617465486f6c64000700344e6f74457870656e6461626c650008001c426c6f636b65640009000074083473705f61726974686d657469633c41726974686d657469634572726f7200010c24556e646572666c6f77000000204f766572666c6f77000100384469766973696f6e42795a65726f0002000078082873705f72756e74696d65485472616e73616374696f6e616c4572726f72000108304c696d6974526561636865640000001c4e6f4c61796572000100007c0c2c70616c6c65745f7375646f1870616c6c6574144576656e7404045400011014537564696404012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e00047041207375646f2063616c6c206a75737420746f6f6b20706c6163652e284b65794368616e67656408010c6f6c648801504f7074696f6e3c543a3a4163636f756e7449643e04b4546865206f6c64207375646f206b657920286966206f6e65207761732070726576696f75736c7920736574292e010c6e6577000130543a3a4163636f756e7449640488546865206e6577207375646f206b657920286966206f6e652077617320736574292e010478546865207375646f206b657920686173206265656e20757064617465642e284b657952656d6f76656400020480546865206b657920776173207065726d616e656e746c792072656d6f7665642e285375646f4173446f6e6504012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e0304c841205b7375646f5f61735d2850616c6c65743a3a7375646f5f6173292063616c6c206a75737420746f6f6b20706c6163652e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574800418526573756c740804540184044501680108084f6b040084000000000c45727204006800000100008400000400008804184f7074696f6e04045401000108104e6f6e6500000010536f6d6504000000000100008c0c3470616c6c65745f6173736574731870616c6c6574144576656e740804540004490001681c437265617465640c012061737365745f6964180128543a3a4173736574496400011c63726561746f72000130543a3a4163636f756e7449640001146f776e6572000130543a3a4163636f756e74496400000474536f6d6520617373657420636c6173732077617320637265617465642e184973737565640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500010460536f6d65206173736574732077657265206973737565642e2c5472616e7366657272656410012061737365745f6964180128543a3a4173736574496400011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500020474536f6d65206173736574732077657265207472616e736665727265642e184275726e65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400011c62616c616e6365180128543a3a42616c616e63650003046c536f6d652061737365747320776572652064657374726f7965642e2c5465616d4368616e67656410012061737365745f6964180128543a3a41737365744964000118697373756572000130543a3a4163636f756e74496400011461646d696e000130543a3a4163636f756e74496400011c667265657a6572000130543a3a4163636f756e74496400040470546865206d616e6167656d656e74207465616d206368616e6765642e304f776e65724368616e67656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400050448546865206f776e6572206368616e6765642e1846726f7a656e08012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400060478536f6d65206163636f756e74206077686f60207761732066726f7a656e2e1854686177656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400070478536f6d65206163636f756e74206077686f6020776173207468617765642e2c417373657446726f7a656e04012061737365745f6964180128543a3a4173736574496400080484536f6d65206173736574206061737365745f696460207761732066726f7a656e2e2c417373657454686177656404012061737365745f6964180128543a3a4173736574496400090484536f6d65206173736574206061737365745f69646020776173207468617765642e444163636f756e747344657374726f7965640c012061737365745f6964180128543a3a417373657449640001486163636f756e74735f64657374726f79656410010c7533320001486163636f756e74735f72656d61696e696e6710010c753332000a04a04163636f756e747320776572652064657374726f79656420666f7220676976656e2061737365742e48417070726f76616c7344657374726f7965640c012061737365745f6964180128543a3a4173736574496400014c617070726f76616c735f64657374726f79656410010c75333200014c617070726f76616c735f72656d61696e696e6710010c753332000b04a4417070726f76616c7320776572652064657374726f79656420666f7220676976656e2061737365742e484465737472756374696f6e5374617274656404012061737365745f6964180128543a3a41737365744964000c04d0416e20617373657420636c61737320697320696e207468652070726f63657373206f66206265696e672064657374726f7965642e2444657374726f79656404012061737365745f6964180128543a3a41737365744964000d0474416e20617373657420636c617373207761732064657374726f7965642e30466f7263654372656174656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000e048c536f6d6520617373657420636c6173732077617320666f7263652d637265617465642e2c4d6574616461746153657414012061737365745f6964180128543a3a417373657449640001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000f049c4e6577206d6574616461746120686173206265656e2073657420666f7220616e2061737365742e3c4d65746164617461436c656172656404012061737365745f6964180128543a3a417373657449640010049c4d6574616461746120686173206265656e20636c656172656420666f7220616e2061737365742e40417070726f7665645472616e7366657210012061737365745f6964180128543a3a41737365744964000118736f75726365000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650011043101284164646974696f6e616c292066756e64732068617665206265656e20617070726f76656420666f72207472616e7366657220746f20612064657374696e6174696f6e206163636f756e742e44417070726f76616c43616e63656c6c65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964001204f0416e20617070726f76616c20666f72206163636f756e74206064656c656761746560207761732063616e63656c6c656420627920606f776e6572602e4c5472616e73666572726564417070726f76656414012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e74496400012c64657374696e6174696f6e000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650013083101416e2060616d6f756e746020776173207472616e7366657272656420696e2069747320656e7469726574792066726f6d20606f776e65726020746f206064657374696e6174696f6e602062796074686520617070726f766564206064656c6567617465602e4841737365745374617475734368616e67656404012061737365745f6964180128543a3a41737365744964001404f8416e2061737365742068617320686164206974732061747472696275746573206368616e676564206279207468652060466f72636560206f726967696e2e5841737365744d696e42616c616e63654368616e67656408012061737365745f6964180128543a3a4173736574496400013c6e65775f6d696e5f62616c616e6365180128543a3a42616c616e63650015040101546865206d696e5f62616c616e6365206f6620616e20617373657420686173206265656e207570646174656420627920746865206173736574206f776e65722e1c546f75636865640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640001246465706f7369746f72000130543a3a4163636f756e744964001604fc536f6d65206163636f756e74206077686f6020776173206372656174656420776974682061206465706f7369742066726f6d20606465706f7369746f72602e1c426c6f636b656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640017047c536f6d65206163636f756e74206077686f602077617320626c6f636b65642e244465706f73697465640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365001804dc536f6d65206173736574732077657265206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e2457697468647261776e0c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650019042101536f6d652061737365747320776572652077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574900c3c70616c6c65745f62616c616e6365731870616c6c6574144576656e740804540004490001581c456e646f77656408011c6163636f756e74000130543a3a4163636f756e744964000130667265655f62616c616e6365180128543a3a42616c616e6365000004b8416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e20447573744c6f737408011c6163636f756e74000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650001083d01416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c78726573756c74696e6720696e20616e206f75747269676874206c6f73732e205472616e736665720c011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650002044c5472616e73666572207375636365656465642e2842616c616e636553657408010c77686f000130543a3a4163636f756e74496400011066726565180128543a3a42616c616e636500030468412062616c616e6365207761732073657420627920726f6f742e20526573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000404e0536f6d652062616c616e63652077617320726573657276656420286d6f7665642066726f6d206672656520746f207265736572766564292e28556e726573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000504e8536f6d652062616c616e63652077617320756e726573657276656420286d6f7665642066726f6d20726573657276656420746f2066726565292e4852657365727665526570617472696174656410011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500014864657374696e6174696f6e5f7374617475739401185374617475730006084d01536f6d652062616c616e636520776173206d6f7665642066726f6d207468652072657365727665206f6620746865206669727374206163636f756e7420746f20746865207365636f6e64206163636f756e742ed846696e616c20617267756d656e7420696e64696361746573207468652064657374696e6174696f6e2062616c616e636520747970652e1c4465706f73697408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000704d8536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20576974686472617708010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650008041d01536f6d6520616d6f756e74207761732077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e1c536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650009040101536f6d6520616d6f756e74207761732072656d6f7665642066726f6d20746865206163636f756e742028652e672e20666f72206d69736265686176696f72292e184d696e74656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000a049c536f6d6520616d6f756e7420776173206d696e74656420696e746f20616e206163636f756e742e184275726e656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000b049c536f6d6520616d6f756e7420776173206275726e65642066726f6d20616e206163636f756e742e2453757370656e64656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000c041501536f6d6520616d6f756e74207761732073757370656e6465642066726f6d20616e206163636f756e74202869742063616e20626520726573746f726564206c61746572292e20526573746f72656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000d04a4536f6d6520616d6f756e742077617320726573746f72656420696e746f20616e206163636f756e742e20557067726164656404010c77686f000130543a3a4163636f756e744964000e0460416e206163636f756e74207761732075706772616465642e18497373756564040118616d6f756e74180128543a3a42616c616e6365000f042d01546f74616c2069737375616e63652077617320696e637265617365642062792060616d6f756e74602c206372656174696e6720612063726564697420746f2062652062616c616e6365642e2452657363696e646564040118616d6f756e74180128543a3a42616c616e63650010042501546f74616c2069737375616e636520776173206465637265617365642062792060616d6f756e74602c206372656174696e672061206465627420746f2062652062616c616e6365642e184c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500110460536f6d652062616c616e636520776173206c6f636b65642e20556e6c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500120468536f6d652062616c616e63652077617320756e6c6f636b65642e1846726f7a656e08010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500130460536f6d652062616c616e6365207761732066726f7a656e2e1854686177656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500140460536f6d652062616c616e636520776173207468617765642e4c546f74616c49737375616e6365466f7263656408010c6f6c64180128543a3a42616c616e636500010c6e6577180128543a3a42616c616e6365001504ac5468652060546f74616c49737375616e6365602077617320666f72636566756c6c79206368616e6765642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749414346672616d655f737570706f72741874726169747318746f6b656e73106d6973633442616c616e6365537461747573000108104672656500000020526573657276656400010000980c6870616c6c65745f7472616e73616374696f6e5f7061796d656e741870616c6c6574144576656e74040454000104485472616e73616374696f6e466565506169640c010c77686f000130543a3a4163636f756e74496400012861637475616c5f66656518013042616c616e63654f663c543e00010c74697018013042616c616e63654f663c543e000008590141207472616e73616374696f6e20666565206061637475616c5f666565602c206f662077686963682060746970602077617320616464656420746f20746865206d696e696d756d20696e636c7573696f6e206665652c5c686173206265656e2070616964206279206077686f602e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749c0c3870616c6c65745f6772616e6470611870616c6c6574144576656e7400010c384e6577417574686f726974696573040134617574686f726974795f736574a00134417574686f726974794c6973740000048c4e657720617574686f726974792073657420686173206265656e206170706c6965642e185061757365640001049843757272656e7420617574686f726974792073657420686173206265656e207061757365642e1c526573756d65640002049c43757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574a0000002a400a400000408a83000a80c5073705f636f6e73656e7375735f6772616e6470610c617070185075626c69630000040004013c656432353531393a3a5075626c69630000ac0c3870616c6c65745f696e64696365731870616c6c6574144576656e7404045400010c34496e64657841737369676e656408010c77686f000130543a3a4163636f756e744964000114696e64657810013c543a3a4163636f756e74496e6465780000047441206163636f756e7420696e646578207761732061737369676e65642e28496e6465784672656564040114696e64657810013c543a3a4163636f756e74496e646578000104bc41206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e2c496e64657846726f7a656e080114696e64657810013c543a3a4163636f756e74496e64657800010c77686f000130543a3a4163636f756e744964000204e841206163636f756e7420696e64657820686173206265656e2066726f7a656e20746f206974732063757272656e74206163636f756e742049442e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b00c4070616c6c65745f64656d6f63726163791870616c6c6574144576656e740404540001442050726f706f73656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000004bc41206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e185461626c656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000104d841207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e3845787465726e616c5461626c656400020494416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e1c537461727465640801247265665f696e64657810013c5265666572656e64756d496e6465780001247468726573686f6c64b40134566f74655468726573686f6c640003045c41207265666572656e64756d2068617320626567756e2e185061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000404ac412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e244e6f745061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000504ac412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e2443616e63656c6c65640401247265665f696e64657810013c5265666572656e64756d496e6465780006048041207265666572656e64756d20686173206265656e2063616e63656c6c65642e2444656c65676174656408010c77686f000130543a3a4163636f756e744964000118746172676574000130543a3a4163636f756e744964000704dc416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e2c556e64656c65676174656404011c6163636f756e74000130543a3a4163636f756e744964000804e4416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e185665746f65640c010c77686f000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114756e74696c300144426c6f636b4e756d626572466f723c543e00090494416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e2c426c61636b6c697374656404013470726f706f73616c5f6861736834011c543a3a48617368000a04c4412070726f706f73616c5f6861736820686173206265656e20626c61636b6c6973746564207065726d616e656e746c792e14566f7465640c0114766f746572000130543a3a4163636f756e7449640001247265665f696e64657810013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e000b0490416e206163636f756e742068617320766f74656420696e2061207265666572656e64756d205365636f6e6465640801207365636f6e646572000130543a3a4163636f756e74496400012870726f705f696e64657810012450726f70496e646578000c0488416e206163636f756e7420686173207365636f6e64656420612070726f706f73616c4050726f706f73616c43616e63656c656404012870726f705f696e64657810012450726f70496e646578000d0460412070726f706f73616c20676f742063616e63656c65642e2c4d657461646174615365740801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0e04d44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e207365742e3c4d65746164617461436c65617265640801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0f04e44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e20636c65617265642e4c4d657461646174615472616e736665727265640c0128707265765f6f776e6572c001344d657461646174614f776e6572046050726576696f7573206d65746164617461206f776e65722e01146f776e6572c001344d657461646174614f776e6572044c4e6577206d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e1004ac4d6574616461746120686173206265656e207472616e7366657272656420746f206e6577206f776e65722e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b40c4070616c6c65745f64656d6f637261637938766f74655f7468726573686f6c6434566f74655468726573686f6c6400010c5053757065724d616a6f72697479417070726f76650000005053757065724d616a6f72697479416761696e73740001003853696d706c654d616a6f7269747900020000b80c4070616c6c65745f64656d6f637261637910766f74652c4163636f756e74566f7465041c42616c616e636501180108205374616e64617264080110766f7465bc0110566f746500011c62616c616e636518011c42616c616e63650000001453706c697408010c61796518011c42616c616e636500010c6e617918011c42616c616e636500010000bc0c4070616c6c65745f64656d6f637261637910766f746510566f74650000040008000000c00c4070616c6c65745f64656d6f6372616379147479706573344d657461646174614f776e657200010c2045787465726e616c0000002050726f706f73616c040010012450726f70496e646578000100285265666572656e64756d040010013c5265666572656e64756d496e64657800020000c40c4470616c6c65745f636f6c6c6563746976651870616c6c6574144576656e7408045400044900011c2050726f706f73656410011c6163636f756e74000130543a3a4163636f756e74496400013870726f706f73616c5f696e64657810013450726f706f73616c496e64657800013470726f706f73616c5f6861736834011c543a3a486173680001247468726573686f6c6410012c4d656d626572436f756e74000008490141206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e3c604d656d626572436f756e7460292e14566f74656414011c6163636f756e74000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114766f746564200110626f6f6c00010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e74000108050141206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e671501612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e20417070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000204c041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2c446973617070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000304d041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e20457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c74000404210141206d6f74696f6e207761732065786563757465643b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e384d656d626572457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c740005044901412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e18436c6f7365640c013470726f706f73616c5f6861736834011c543a3a4861736800010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e740006045501412070726f706f73616c2077617320636c6f736564206265636175736520697473207468726573686f6c64207761732072656163686564206f7220616674657220697473206475726174696f6e207761732075702e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c80c3870616c6c65745f76657374696e671870616c6c6574144576656e740404540001083856657374696e675570646174656408011c6163636f756e74000130543a3a4163636f756e744964000120756e76657374656418013042616c616e63654f663c543e000008510154686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e6469636174652061206368616e676520696e2066756e647320617661696c61626c652e25015468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e4056657374696e67436f6d706c6574656404011c6163636f756e74000130543a3a4163636f756e7449640001049c416e205c5b6163636f756e745c5d20686173206265636f6d652066756c6c79207665737465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574cc0c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144576656e7404045400011c1c4e65775465726d04012c6e65775f6d656d62657273d001ec5665633c283c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e7449642c2042616c616e63654f663c543e293e000014450141206e6577207465726d2077697468206e65775f6d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e550174686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e65644501666f72207468697320707572706f73652e204120604e65775465726d285c5b5c5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e645501736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f2c626567696e20776974682e24456d7074795465726d00010831014e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6dc8604e65775465726d285c5b5c5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e34456c656374696f6e4572726f72000204e4496e7465726e616c206572726f722068617070656e6564207768696c6520747279696e6720746f20706572666f726d20656c656374696f6e2e304d656d6265724b69636b65640401186d656d6265720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000308410141206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f723060456d7074795465726d602e2452656e6f756e63656404012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400040498536f6d656f6e65206861732072656e6f756e6365642074686569722063616e6469646163792e4043616e646964617465536c617368656408012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0005103901412063616e6469646174652077617320736c617368656420627920616d6f756e742064756520746f206661696c696e6720746f206f627461696e20612073656174206173206d656d626572206f722872756e6e65722d75702e00e44e6f74652074686174206f6c64206d656d6265727320616e642072756e6e6572732d75702061726520616c736f2063616e646964617465732e4453656174486f6c646572536c617368656408012c736561745f686f6c6465720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000604350141207365617420686f6c6465722077617320736c617368656420627920616d6f756e74206279206265696e6720666f72636566756c6c792072656d6f7665642066726f6d20746865207365742e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d0000002d400d400000408001800d80c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144576656e7404045400011838536f6c7574696f6e53746f7265640c011c636f6d70757465dc013c456c656374696f6e436f6d707574650001186f726967696e8801504f7074696f6e3c543a3a4163636f756e7449643e000130707265765f656a6563746564200110626f6f6c00001cb44120736f6c7574696f6e207761732073746f72656420776974682074686520676976656e20636f6d707574652e00510154686520606f726967696e6020696e6469636174657320746865206f726967696e206f662074686520736f6c7574696f6e2e20496620606f726967696e602069732060536f6d65284163636f756e74496429602c59017468652073746f72656420736f6c7574696f6e20776173207375626d697474656420696e20746865207369676e65642070686173652062792061206d696e657220776974682074686520604163636f756e744964602e25014f74686572776973652c2074686520736f6c7574696f6e207761732073746f7265642065697468657220647572696e672074686520756e7369676e6564207068617365206f722062794d0160543a3a466f7263654f726967696e602e205468652060626f6f6c6020697320607472756560207768656e20612070726576696f757320736f6c7574696f6e2077617320656a656374656420746f206d616b6548726f6f6d20666f722074686973206f6e652e44456c656374696f6e46696e616c697a656408011c636f6d70757465dc013c456c656374696f6e436f6d7075746500011473636f7265e00134456c656374696f6e53636f7265000104190154686520656c656374696f6e20686173206265656e2066696e616c697a65642c20776974682074686520676976656e20636f6d7075746174696f6e20616e642073636f72652e38456c656374696f6e4661696c656400020c4c416e20656c656374696f6e206661696c65642e0001014e6f74206d7563682063616e20626520736169642061626f757420776869636820636f6d7075746573206661696c656420696e207468652070726f636573732e20526577617264656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0003042501416e206163636f756e7420686173206265656e20726577617264656420666f72207468656972207369676e6564207375626d697373696f6e206265696e672066696e616c697a65642e1c536c617368656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0004042101416e206163636f756e7420686173206265656e20736c617368656420666f72207375626d697474696e6720616e20696e76616c6964207369676e6564207375626d697373696f6e2e4450686173655472616e736974696f6e65640c011066726f6de4016050686173653c426c6f636b4e756d626572466f723c543e3e000108746fe4016050686173653c426c6f636b4e756d626572466f723c543e3e000114726f756e6410010c753332000504b85468657265207761732061207068617365207472616e736974696f6e20696e206120676976656e20726f756e642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574dc089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653c456c656374696f6e436f6d707574650001141c4f6e436861696e000000185369676e656400010020556e7369676e65640002002046616c6c6261636b00030024456d657267656e637900040000e0084473705f6e706f735f656c656374696f6e7334456c656374696f6e53636f726500000c01346d696e696d616c5f7374616b6518013c457874656e64656442616c616e636500012473756d5f7374616b6518013c457874656e64656442616c616e636500014473756d5f7374616b655f7371756172656418013c457874656e64656442616c616e63650000e4089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651450686173650408426e013001100c4f6666000000185369676e656400010020556e7369676e65640400e8012828626f6f6c2c20426e2900020024456d657267656e637900030000e800000408203000ec103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144576656e740404540001481c457261506169640c01246572615f696e646578100120457261496e64657800014076616c696461746f725f7061796f757418013042616c616e63654f663c543e00012472656d61696e64657218013042616c616e63654f663c543e000008550154686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973c07468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e2052657761726465640c01147374617368000130543a3a4163636f756e74496400011064657374f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000118616d6f756e7418013042616c616e63654f663c543e0001040d01546865206e6f6d696e61746f7220686173206265656e207265776172646564206279207468697320616d6f756e7420746f20746869732064657374696e6174696f6e2e1c536c61736865640801187374616b6572000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0002041d0141207374616b6572202876616c696461746f72206f72206e6f6d696e61746f722920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e34536c6173685265706f727465640c012476616c696461746f72000130543a3a4163636f756e7449640001206672616374696f6ef4011c50657262696c6c000124736c6173685f657261100120457261496e64657800030859014120736c61736820666f722074686520676976656e2076616c696461746f722c20666f722074686520676976656e2070657263656e74616765206f66207468656972207374616b652c2061742074686520676976656e54657261206173206265656e207265706f727465642e684f6c64536c617368696e675265706f727444697363617264656404013473657373696f6e5f696e64657810013053657373696f6e496e6465780004081901416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64446e6f742062652070726f6365737365642e385374616b657273456c65637465640005048441206e657720736574206f66207374616b6572732077617320656c65637465642e18426f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000610d0416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d004d014e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c210169742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e20556e626f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00070490416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e2457697468647261776e0801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0008085901416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365606466726f6d2074686520756e6c6f636b696e672071756575652e184b69636b65640801246e6f6d696e61746f72000130543a3a4163636f756e7449640001147374617368000130543a3a4163636f756e744964000904b441206e6f6d696e61746f7220686173206265656e206b69636b65642066726f6d20612076616c696461746f722e545374616b696e67456c656374696f6e4661696c6564000a04ac54686520656c656374696f6e206661696c65642e204e6f206e65772065726120697320706c616e6e65642e1c4368696c6c65640401147374617368000130543a3a4163636f756e744964000b042101416e206163636f756e74206861732073746f707065642070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e345061796f7574537461727465640801246572615f696e646578100120457261496e64657800013c76616c696461746f725f7374617368000130543a3a4163636f756e744964000c0498546865207374616b657273272072657761726473206172652067657474696e6720706169642e4456616c696461746f7250726566735365740801147374617368000130543a3a4163636f756e7449640001147072656673f8013856616c696461746f725072656673000d0498412076616c696461746f72206861732073657420746865697220707265666572656e6365732e68536e617073686f74566f7465727353697a65457863656564656404011073697a6510010c753332000e0468566f746572732073697a65206c696d697420726561636865642e6c536e617073686f745461726765747353697a65457863656564656404011073697a6510010c753332000f046c546172676574732073697a65206c696d697420726561636865642e20466f7263654572610401106d6f64650101011c466f7263696e670010047441206e657720666f72636520657261206d6f646520776173207365742e64436f6e74726f6c6c65724261746368446570726563617465640401206661696c7572657310010c753332001104a45265706f7274206f66206120636f6e74726f6c6c6572206261746368206465707265636174696f6e2e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574f0083870616c6c65745f7374616b696e674452657761726444657374696e6174696f6e04244163636f756e74496401000114185374616b656400000014537461736800010028436f6e74726f6c6c65720002001c4163636f756e7404000001244163636f756e744964000300104e6f6e6500040000f40c3473705f61726974686d65746963287065725f7468696e67731c50657262696c6c0000040010010c7533320000f8083870616c6c65745f7374616b696e673856616c696461746f7250726566730000080128636f6d6d697373696f6efc011c50657262696c6c00011c626c6f636b6564200110626f6f6c0000fc000006f4000101083870616c6c65745f7374616b696e671c466f7263696e67000110284e6f74466f7263696e6700000020466f7263654e657700010024466f7263654e6f6e650002002c466f726365416c776179730003000005010c3870616c6c65745f73657373696f6e1870616c6c6574144576656e74000104284e657753657373696f6e04013473657373696f6e5f696e64657810013053657373696f6e496e64657800000839014e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f74207468659c626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657409010c3c70616c6c65745f74726561737572791870616c6c6574144576656e74080454000449000130205370656e64696e670401406275646765745f72656d61696e696e6718013c42616c616e63654f663c542c20493e000004e45765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e1c417761726465640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000114617761726418013c42616c616e63654f663c542c20493e00011c6163636f756e74000130543a3a4163636f756e7449640001047c536f6d652066756e64732068617665206265656e20616c6c6f63617465642e144275726e7404012c6275726e745f66756e647318013c42616c616e63654f663c542c20493e00020488536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20526f6c6c6f766572040140726f6c6c6f7665725f62616c616e636518013c42616c616e63654f663c542c20493e0003042d015370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e1c4465706f73697404011476616c756518013c42616c616e63654f663c542c20493e0004047c536f6d652066756e64732068617665206265656e206465706f73697465642e345370656e64417070726f7665640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000118616d6f756e7418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640005049c41206e6577207370656e642070726f706f73616c20686173206265656e20617070726f7665642e3c55706461746564496e61637469766508012c726561637469766174656418013c42616c616e63654f663c542c20493e00012c646561637469766174656418013c42616c616e63654f663c542c20493e000604cc54686520696e6163746976652066756e6473206f66207468652070616c6c65742068617665206265656e20757064617465642e4841737365745370656e64417070726f766564180114696e6465781001285370656e64496e64657800012861737365745f6b696e64840130543a3a41737365744b696e64000118616d6f756e74180150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000138543a3a42656e656669636961727900012876616c69645f66726f6d300144426c6f636b4e756d626572466f723c543e0001246578706972655f6174300144426c6f636b4e756d626572466f723c543e000704b441206e6577206173736574207370656e642070726f706f73616c20686173206265656e20617070726f7665642e4041737365745370656e64566f69646564040114696e6465781001285370656e64496e64657800080474416e20617070726f766564207370656e642077617320766f696465642e1050616964080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a49640009044c41207061796d656e742068617070656e65642e345061796d656e744661696c6564080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a4964000a049041207061796d656e74206661696c656420616e642063616e20626520726574726965642e385370656e6450726f636573736564040114696e6465781001285370656e64496e646578000b084d0141207370656e64207761732070726f63657373656420616e642072656d6f7665642066726f6d207468652073746f726167652e204974206d696768742068617665206265656e207375636365737366756c6c797070616964206f72206974206d6179206861766520657870697265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65740d010c3c70616c6c65745f626f756e746965731870616c6c6574144576656e7408045400044900012c38426f756e747950726f706f736564040114696e64657810012c426f756e7479496e646578000004504e657720626f756e74792070726f706f73616c2e38426f756e747952656a6563746564080114696e64657810012c426f756e7479496e646578000110626f6e6418013c42616c616e63654f663c542c20493e000104cc4120626f756e74792070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e48426f756e7479426563616d65416374697665040114696e64657810012c426f756e7479496e646578000204b84120626f756e74792070726f706f73616c2069732066756e64656420616e6420626563616d65206163746976652e34426f756e747941776172646564080114696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000304944120626f756e7479206973206177617264656420746f20612062656e65666963696172792e34426f756e7479436c61696d65640c0114696e64657810012c426f756e7479496e6465780001187061796f757418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640004048c4120626f756e747920697320636c61696d65642062792062656e65666963696172792e38426f756e747943616e63656c6564040114696e64657810012c426f756e7479496e646578000504584120626f756e74792069732063616e63656c6c65642e38426f756e7479457874656e646564040114696e64657810012c426f756e7479496e646578000604704120626f756e74792065787069727920697320657874656e6465642e38426f756e7479417070726f766564040114696e64657810012c426f756e7479496e646578000704544120626f756e747920697320617070726f7665642e3c43757261746f7250726f706f736564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000804744120626f756e74792063757261746f722069732070726f706f7365642e4443757261746f72556e61737369676e6564040124626f756e74795f696410012c426f756e7479496e6465780009047c4120626f756e74792063757261746f7220697320756e61737369676e65642e3c43757261746f724163636570746564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000a04744120626f756e74792063757261746f722069732061636365707465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657411010c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144576656e74040454000110144164646564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780000046041206368696c642d626f756e74792069732061646465642e1c417761726465640c0114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000104ac41206368696c642d626f756e7479206973206177617264656420746f20612062656e65666963696172792e1c436c61696d6564100114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780001187061796f757418013042616c616e63654f663c543e00012c62656e6566696369617279000130543a3a4163636f756e744964000204a441206368696c642d626f756e747920697320636c61696d65642062792062656e65666963696172792e2043616e63656c6564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780003047041206368696c642d626f756e74792069732063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657415010c4070616c6c65745f626167735f6c6973741870616c6c6574144576656e740804540004490001082052656261676765640c010c77686f000130543a3a4163636f756e74496400011066726f6d300120543a3a53636f7265000108746f300120543a3a53636f7265000004a44d6f76656420616e206163636f756e742066726f6d206f6e652062616720746f20616e6f746865722e3053636f72655570646174656408010c77686f000130543a3a4163636f756e7449640001246e65775f73636f7265300120543a3a53636f7265000104d855706461746564207468652073636f7265206f6620736f6d65206163636f756e7420746f2074686520676976656e20616d6f756e742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657419010c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f73746174651d010124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e1d01085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e6700020000210104184f7074696f6e0404540125010108104e6f6e6500000010536f6d65040025010000010000250100000408f400002901085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7350436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d62657200002d0104184f7074696f6e0404540131010108104e6f6e6500000010536f6d650400310100000100003101085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7364436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e7449640001000035010c4070616c6c65745f7363686564756c65721870616c6c6574144576656e74040454000124245363686564756c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c753332000004505363686564756c656420736f6d65207461736b2e2043616e63656c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001044c43616e63656c656420736f6d65207461736b2e28446973706174636865640c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118726573756c748001384469737061746368526573756c74000204544469737061746368656420736f6d65207461736b2e2052657472795365741001107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118706572696f64300144426c6f636b4e756d626572466f723c543e00011c726574726965730801087538000304a0536574206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e38526574727943616e63656c6c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000404ac43616e63656c206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e3c43616c6c556e617661696c61626c650801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e00050429015468652063616c6c20666f72207468652070726f7669646564206861736820776173206e6f7420666f756e6420736f20746865207461736b20686173206265656e2061626f727465642e38506572696f6469634661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0006043d0154686520676976656e207461736b2077617320756e61626c6520746f2062652072656e657765642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b2e2c52657472794661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0007085d0154686520676976656e207461736b2077617320756e61626c6520746f20626520726574726965642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b206f722074686572659c776173206e6f7420656e6f7567682077656967687420746f2072657363686564756c652069742e545065726d616e656e746c794f7665727765696768740801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000804f054686520676976656e207461736b2063616e206e657665722062652065786563757465642073696e6365206974206973206f7665727765696768742e04304576656e747320747970652e3901000004083010003d0104184f7074696f6e04045401040108104e6f6e6500000010536f6d65040004000001000041010c3c70616c6c65745f707265696d6167651870616c6c6574144576656e7404045400010c144e6f7465640401106861736834011c543a3a48617368000004684120707265696d61676520686173206265656e206e6f7465642e245265717565737465640401106861736834011c543a3a48617368000104784120707265696d61676520686173206265656e207265717565737465642e1c436c65617265640401106861736834011c543a3a486173680002046c4120707265696d616765206861732062656e20636c65617265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657445010c3c70616c6c65745f6f6666656e6365731870616c6c6574144576656e740001041c4f6666656e63650801106b696e64490101104b696e6400012074696d65736c6f743801384f706171756554696d65536c6f7400000c5101546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e643501286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4c5c5b6b696e642c2074696d65736c6f745c5d2e04304576656e747320747970652e49010000031000000008004d010c3c70616c6c65745f74785f70617573651870616c6c6574144576656e740404540001082843616c6c50617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000004b8546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f77207061757365642e3043616c6c556e70617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000104c0546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f7720756e7061757365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574510100000408550155010055010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000059010c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144576656e7404045400010c444865617274626561745265636569766564040130617574686f726974795f69645d010138543a3a417574686f726974794964000004c041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f726974794964602e1c416c6c476f6f64000104d041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2c536f6d654f66666c696e6504011c6f66666c696e656101016c5665633c4964656e74696669636174696f6e5475706c653c543e3e000204290141742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e047c54686520604576656e746020656e756d206f6620746869732070616c6c65745d01104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139185075626c69630000040004013c737232353531393a3a5075626c696300006101000002650100650100000408006901006901082873705f7374616b696e67204578706f7375726508244163636f756e74496401001c42616c616e63650118000c0114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e00006d01000006180071010000027501007501082873705f7374616b696e6748496e646976696475616c4578706f7375726508244163636f756e74496401001c42616c616e636501180008010c77686f0001244163636f756e74496400011476616c75656d01011c42616c616e6365000079010c3c70616c6c65745f6964656e746974791870616c6c6574144576656e740404540001442c4964656e7469747953657404010c77686f000130543a3a4163636f756e744964000004ec41206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e3c4964656e74697479436c656172656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000104cc41206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e384964656e746974794b696c6c656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000204c441206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e484a756467656d656e7452657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780003049c41206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e504a756467656d656e74556e72657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780004048841206a756467656d656e74207265717565737420776173207265747261637465642e384a756467656d656e74476976656e080118746172676574000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780005049441206a756467656d656e742077617320676976656e2062792061207265676973747261722e38526567697374726172416464656404013c7265676973747261725f696e646578100138526567697374726172496e646578000604584120726567697374726172207761732061646465642e405375624964656e7469747941646465640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000704f441207375622d6964656e746974792077617320616464656420746f20616e206964656e7469747920616e6420746865206465706f73697420706169642e485375624964656e7469747952656d6f7665640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000804090141207375622d6964656e74697479207761732072656d6f7665642066726f6d20616e206964656e7469747920616e6420746865206465706f7369742066726565642e485375624964656e746974795265766f6b65640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000908190141207375622d6964656e746974792077617320636c65617265642c20616e642074686520676976656e206465706f7369742072657061747269617465642066726f6d20746865c86d61696e206964656e74697479206163636f756e7420746f20746865207375622d6964656e74697479206163636f756e742e38417574686f726974794164646564040124617574686f72697479000130543a3a4163636f756e744964000a047c4120757365726e616d6520617574686f72697479207761732061646465642e40417574686f7269747952656d6f766564040124617574686f72697479000130543a3a4163636f756e744964000b04844120757365726e616d6520617574686f72697479207761732072656d6f7665642e2c557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000c04744120757365726e616d65207761732073657420666f72206077686f602e38557365726e616d655175657565640c010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e00012865787069726174696f6e300144426c6f636b4e756d626572466f723c543e000d0419014120757365726e616d6520776173207175657565642c20627574206077686f60206d75737420616363657074206974207072696f7220746f206065787069726174696f6e602e48507265617070726f76616c4578706972656404011477686f7365000130543a3a4163636f756e744964000e043901412071756575656420757365726e616d6520706173736564206974732065787069726174696f6e20776974686f7574206265696e6720636c61696d656420616e64207761732072656d6f7665642e485072696d617279557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000f0401014120757365726e616d6520776173207365742061732061207072696d61727920616e642063616e206265206c6f6f6b65642075702066726f6d206077686f602e5c44616e676c696e67557365726e616d6552656d6f76656408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e0010085d01412064616e676c696e6720757365726e616d652028617320696e2c206120757365726e616d6520636f72726573706f6e64696e6720746f20616e206163636f756e742074686174206861732072656d6f766564206974736c6964656e746974792920686173206265656e2072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65747d010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000081010c3870616c6c65745f7574696c6974791870616c6c6574144576656e74000118404261746368496e746572727570746564080114696e64657810010c7533320001146572726f7268013444697370617463684572726f7200000855014261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061734877656c6c20617320746865206572726f722e384261746368436f6d706c65746564000104c84261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e604261746368436f6d706c65746564576974684572726f7273000204b44261746368206f66206469737061746368657320636f6d706c657465642062757420686173206572726f72732e344974656d436f6d706c657465640003041d01412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206e6f206572726f722e284974656d4661696c65640401146572726f7268013444697370617463684572726f720004041101412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206572726f722e30446973706174636865644173040118726573756c748001384469737061746368526573756c7400050458412063616c6c2077617320646973706174636865642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657485010c3c70616c6c65745f6d756c74697369671870616c6c6574144576656e740404540001102c4e65774d756c74697369670c0124617070726f76696e67000130543a3a4163636f756e7449640001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c486173680000048c41206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e404d756c7469736967417070726f76616c100124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000104c841206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e404d756c74697369674578656375746564140124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000118726573756c748001384469737061746368526573756c740002049c41206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e444d756c746973696743616e63656c6c656410012863616e63656c6c696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000304a041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65748901083c70616c6c65745f6d756c74697369672454696d65706f696e74042c426c6f636b4e756d62657201300008011868656967687430012c426c6f636b4e756d626572000114696e64657810010c75333200008d010c3c70616c6c65745f657468657265756d1870616c6c6574144576656e7400010420457865637574656414011066726f6d9101011048313630000108746f91010110483136300001407472616e73616374696f6e5f686173683401104832353600012c657869745f726561736f6e9901012845786974526561736f6e00012865787472615f6461746138011c5665633c75383e000004c8416e20657468657265756d207472616e73616374696f6e20776173207375636365737366756c6c792065786563757465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749101083c7072696d69746976655f7479706573104831363000000400950101205b75383b2032305d0000950100000314000000080099010c2065766d5f636f7265146572726f722845786974526561736f6e0001101c5375636365656404009d01012c4578697453756363656564000000144572726f720400a1010124457869744572726f72000100185265766572740400b10101284578697452657665727400020014466174616c0400b501012445786974466174616c000300009d010c2065766d5f636f7265146572726f722c457869745375636365656400010c1c53746f707065640000002052657475726e656400010020537569636964656400020000a1010c2065766d5f636f7265146572726f7224457869744572726f7200014038537461636b556e646572666c6f7700000034537461636b4f766572666c6f770001002c496e76616c69644a756d7000020030496e76616c696452616e67650003004444657369676e61746564496e76616c69640004002c43616c6c546f6f446565700005003c437265617465436f6c6c6973696f6e0006004c437265617465436f6e74726163744c696d69740007002c496e76616c6964436f64650400a50101184f70636f6465000f002c4f75744f664f6666736574000800204f75744f66476173000900244f75744f6646756e64000a002c5043556e646572666c6f77000b002c437265617465456d707479000c00144f746865720400a9010144436f773c277374617469632c207374723e000d00204d61784e6f6e6365000e0000a5010c2065766d5f636f7265186f70636f6465184f70636f64650000040008010875380000a901040c436f7704045401ad01000400ad01000000ad010000050200b1010c2065766d5f636f7265146572726f72284578697452657665727400010420526576657274656400000000b5010c2065766d5f636f7265146572726f722445786974466174616c000110304e6f74537570706f7274656400000048556e68616e646c6564496e746572727570740001004043616c6c4572726f724173466174616c0400a1010124457869744572726f72000200144f746865720400a9010144436f773c277374617469632c207374723e00030000b9010c2870616c6c65745f65766d1870616c6c6574144576656e740404540001140c4c6f6704010c6c6f67bd01010c4c6f670000047c457468657265756d206576656e74732066726f6d20636f6e7472616374732e1c4372656174656404011c616464726573739101011048313630000104b44120636f6e747261637420686173206265656e206372656174656420617420676976656e20616464726573732e34437265617465644661696c656404011c61646472657373910101104831363000020405014120636f6e74726163742077617320617474656d7074656420746f20626520637265617465642c206275742074686520657865637574696f6e206661696c65642e20457865637574656404011c616464726573739101011048313630000304f84120636f6e747261637420686173206265656e206578656375746564207375636365737366756c6c79207769746820737461746573206170706c6965642e3845786563757465644661696c656404011c61646472657373910101104831363000040465014120636f6e747261637420686173206265656e2065786563757465642077697468206572726f72732e20537461746573206172652072657665727465642077697468206f6e6c79206761732066656573206170706c6965642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574bd010c20657468657265756d0c6c6f670c4c6f6700000c011c616464726573739101011048313630000118746f70696373c10101245665633c483235363e0001106461746138011442797465730000c1010000023400c5010c3c70616c6c65745f626173655f6665651870616c6c6574144576656e7400010c404e65774261736546656550657247617304010c666565c9010110553235360000003c426173654665654f766572666c6f77000100344e6577456c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000200047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c901083c7072696d69746976655f7479706573105532353600000400cd0101205b7536343b20345d0000cd01000003040000003000d1010c3473705f61726974686d65746963287065725f7468696e67731c5065726d696c6c0000040010010c7533320000d5010c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144576656e740404540001041c436c61696d65640c0124726563697069656e74000130543a3a4163636f756e744964000118736f75726365d90101304d756c746941646472657373000118616d6f756e7418013042616c616e63654f663c543e0000048c536f6d656f6e6520636c61696d656420736f6d65206e617469766520746f6b656e732e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d9010c5470616c6c65745f61697264726f705f636c61696d73147574696c73304d756c7469416464726573730001080c45564d0400dd01013c457468657265756d41646472657373000000184e6174697665040000012c4163636f756e744964333200010000dd01105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733c457468657265756d4164647265737300000400950101205b75383b2032305d0000e1010c3070616c6c65745f70726f78791870616c6c6574144576656e740404540001143450726f78794578656375746564040118726573756c748001384469737061746368526573756c74000004bc412070726f78792077617320657865637574656420636f72726563746c792c20776974682074686520676976656e2e2c507572654372656174656410011070757265000130543a3a4163636f756e74496400010c77686f000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f787954797065000150646973616d626967756174696f6e5f696e646578e901010c753136000108dc412070757265206163636f756e7420686173206265656e2063726561746564206279206e65772070726f7879207769746820676976656e90646973616d626967756174696f6e20696e64657820616e642070726f787920747970652e24416e6e6f756e6365640c01107265616c000130543a3a4163636f756e74496400011470726f7879000130543a3a4163636f756e74496400012463616c6c5f6861736834013443616c6c486173684f663c543e000204e0416e20616e6e6f756e63656d656e742077617320706c6163656420746f206d616b6520612063616c6c20696e20746865206675747572652e2850726f7879416464656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00030448412070726f7879207761732061646465642e3050726f787952656d6f76656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00040450412070726f7879207761732072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574e501085874616e676c655f746573746e65745f72756e74696d652450726f7879547970650001100c416e790000002c4e6f6e5472616e7366657200010028476f7665726e616e63650002001c5374616b696e6700030000e9010000050400ed010c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144576656e74040454000160384f70657261746f724a6f696e656404010c77686f000130543a3a4163636f756e7449640000045c416e206f70657261746f7220686173206a6f696e65642e604f70657261746f724c656176696e675363686564756c656404010c77686f000130543a3a4163636f756e7449640001048c416e206f70657261746f7220686173207363686564756c656420746f206c656176652e584f70657261746f724c6561766543616e63656c6c656404010c77686f000130543a3a4163636f756e744964000204b8416e206f70657261746f72206861732063616e63656c6c6564207468656972206c6561766520726571756573742e544f70657261746f724c65617665457865637574656404010c77686f000130543a3a4163636f756e744964000304b4416e206f70657261746f7220686173206578656375746564207468656972206c6561766520726571756573742e404f70657261746f72426f6e644d6f726508010c77686f000130543a3a4163636f756e74496400013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00040498416e206f70657261746f722068617320696e63726561736564207468656972207374616b652e644f70657261746f72426f6e644c6573735363686564756c656408010c77686f000130543a3a4163636f756e744964000138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504c8416e206f70657261746f7220686173207363686564756c656420746f206465637265617365207468656972207374616b652e604f70657261746f72426f6e644c657373457865637574656404010c77686f000130543a3a4163636f756e744964000604b8416e206f70657261746f7220686173206578656375746564207468656972207374616b652064656372656173652e644f70657261746f72426f6e644c65737343616e63656c6c656404010c77686f000130543a3a4163636f756e744964000704dc416e206f70657261746f72206861732063616e63656c6c6564207468656972207374616b6520646563726561736520726571756573742e4c4f70657261746f7257656e744f66666c696e6504010c77686f000130543a3a4163636f756e74496400080474416e206f70657261746f722068617320676f6e65206f66666c696e652e484f70657261746f7257656e744f6e6c696e6504010c77686f000130543a3a4163636f756e74496400090470416e206f70657261746f722068617320676f6e65206f6e6c696e652e244465706f73697465640c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000a046041206465706f73697420686173206265656e206d6164652e445363686564756c656477697468647261770c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000b047c416e20776974686472617720686173206265656e207363686564756c65642e404578656375746564776974686472617704010c77686f000130543a3a4163636f756e744964000c0478416e20776974686472617720686173206265656e2065786563757465642e4443616e63656c6c6564776974686472617704010c77686f000130543a3a4163636f756e744964000d047c416e20776974686472617720686173206265656e2063616e63656c6c65642e2444656c65676174656410010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000e046c412064656c65676174696f6e20686173206265656e206d6164652e685363686564756c656444656c656761746f72426f6e644c65737310010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000f04bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e207363686564756c65642e64457865637574656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001004b8412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2065786563757465642e6843616e63656c6c656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001104bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2063616e63656c6c65642e54496e63656e74697665415059416e644361705365740c01207661756c745f6964180128543a3a5661756c74496400010c617079f501014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e00120419014576656e7420656d6974746564207768656e20616e20696e63656e746976652041505920616e6420636170206172652073657420666f72206120726577617264207661756c7450426c75657072696e7457686974656c6973746564040130626c75657072696e745f696430012c426c75657072696e744964001304e44576656e7420656d6974746564207768656e206120626c75657072696e742069732077686974656c697374656420666f7220726577617264734c417373657455706461746564496e5661756c7410010c77686f000130543a3a4163636f756e7449640001207661756c745f6964180128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6ef901012c4173736574416374696f6e00140498417373657420686173206265656e207570646174656420746f20726577617264207661756c743c4f70657261746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e001504644f70657261746f7220686173206265656e20736c61736865644044656c656761746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0016046844656c656761746f7220686173206265656e20736c61736865642c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e0017049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e04744576656e747320656d6974746564206279207468652070616c6c65742ef1010c4474616e676c655f7072696d697469766573207365727669636573144173736574041c417373657449640118010818437573746f6d040018011c4173736574496400000014457263323004009101013473705f636f72653a3a4831363000010000f5010c3473705f61726974686d65746963287065725f7468696e67731c50657263656e740000040008010875380000f901107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c726577617264732c4173736574416374696f6e0001080c4164640000001852656d6f766500010000fd010c3c70616c6c65745f7365727669636573186d6f64756c65144576656e7404045400014040426c75657072696e74437265617465640801146f776e6572000130543a3a4163636f756e74496404bc546865206163636f756e742074686174206372656174656420746865207365727669636520626c75657072696e742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0004a441206e6577207365727669636520626c75657072696e7420686173206265656e20637265617465642e3c507265526567697374726174696f6e0801206f70657261746f72000130543a3a4163636f756e74496404bc546865206163636f756e742074686174207072652d7265676973746572656420617320616e206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0104dc416e206f70657261746f7220686173207072652d7265676973746572656420666f722061207365727669636520626c75657072696e742e285265676973746572656410012070726f7669646572000130543a3a4163636f756e74496404a8546865206163636f756e74207468617420726567697374657265642061732061206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e012c707265666572656e6365730102014c4f70657261746f72507265666572656e63657304f454686520707265666572656e63657320666f7220746865206f70657261746f7220666f72207468697320737065636966696320626c75657072696e742e0144726567697374726174696f6e5f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e049054686520617267756d656e7473207573656420666f7220726567697374726174696f6e2e020490416e206e6577206f70657261746f7220686173206265656e20726567697374657265642e30556e726567697374657265640801206f70657261746f72000130543a3a4163636f756e74496404b4546865206163636f756e74207468617420756e7265676973746572656420617320616d206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e030488416e206f70657261746f7220686173206265656e20756e726567697374657265642e4c507269636554617267657473557064617465640c01206f70657261746f72000130543a3a4163636f756e74496404c4546865206163636f756e74207468617420757064617465642074686520617070726f76616c20707265666572656e63652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e013470726963655f74617267657473090201305072696365546172676574730458546865206e657720707269636520746172676574732e0404cc546865207072696365207461726765747320666f7220616e206f70657261746f7220686173206265656e20757064617465642e40536572766963655265717565737465641801146f776e6572000130543a3a4163636f756e744964049c546865206163636f756e742074686174207265717565737465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c733d0201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f7665643d0201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e01186173736574734102013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e05048441206e6577207365727669636520686173206265656e207265717565737465642e585365727669636552657175657374417070726f7665641401206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e74207468617420617070726f7665642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c733d0201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f7665643d0201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e060490412073657276696365207265717565737420686173206265656e20617070726f7665642e58536572766963655265717565737452656a65637465640c01206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e7420746861742072656a65637465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e070490412073657276696365207265717565737420686173206265656e2072656a65637465642e4053657276696365496e697469617465641401146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128726571756573745f696430010c75363404c0546865204944206f662074686520736572766963652072657175657374207468617420676f7420617070726f7665642e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e01186173736574734102013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e08047441207365727669636520686173206265656e20696e697469617465642e44536572766963655465726d696e617465640c01146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e09047841207365727669636520686173206265656e207465726d696e617465642e244a6f6243616c6c656414011863616c6c6572000130543a3a4163636f756e7449640480546865206163636f756e7420746861742063616c6c656420746865206a6f622e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0110617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e046454686520617267756d656e7473206f6620746865206a6f622e0a045841206a6f6220686173206265656e2063616c6c65642e484a6f62526573756c745375626d69747465641401206f70657261746f72000130543a3a4163636f756e74496404a8546865206163636f756e742074686174207375626d697474656420746865206a6f6220726573756c742e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0118726573756c740d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e045854686520726573756c74206f6620746865206a6f622e0b048041206a6f6220726573756c7420686173206265656e207375626d69747465642e2c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e000c049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e38556e6170706c696564536c617368180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780d048c416e204f70657261746f722068617320616e20756e6170706c69656420736c6173682e38536c617368446973636172646564180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780e0484416e20556e6170706c69656420536c61736820676f74206469736361726465642e904d6173746572426c75657072696e74536572766963654d616e61676572526576697365640801207265766973696f6e10010c75333204f0546865207265766973696f6e206e756d626572206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e011c61646472657373910101104831363004d05468652061646472657373206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e0f04d8546865204d617374657220426c75657072696e742053657276696365204d616e6167657220686173206265656e20726576697365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657401020c4474616e676c655f7072696d6974697665732073657276696365734c4f70657261746f72507265666572656e636573000008010c6b6579050201205b75383b2036355d00013470726963655f74617267657473090201305072696365546172676574730000050200000341000000080009020c4474616e676c655f7072696d69746976657320736572766963657330507269636554617267657473000014010c63707530010c75363400010c6d656d30010c75363400012c73746f726167655f68646430010c75363400012c73746f726167655f73736430010c75363400013073746f726167655f6e766d6530010c75363400000d020000021102001102104474616e676c655f7072696d697469766573207365727669636573146669656c64144669656c6408044300244163636f756e74496401000140104e6f6e6500000010426f6f6c0400200110626f6f6c0001001455696e74380400080108753800020010496e743804001502010869380003001855696e7431360400e901010c75313600040014496e74313604001902010c6931360005001855696e743332040010010c75333200060014496e74333204001d02010c6933320007001855696e743634040030010c75363400080014496e74363404002102010c69363400090018537472696e6704002502017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e000a00144279746573040029020180426f756e6465645665633c75382c20433a3a4d61784669656c647353697a653e000b0014417272617904002d0201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000c00104c69737404002d0201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000d001853747275637408002502017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e00003102016d01426f756e6465645665633c0a28426f756e646564537472696e673c433a3a4d61784669656c647353697a653e2c20426f783c4669656c643c432c204163636f756e7449643e3e292c20433a3a0a4d61784669656c647353697a653e000e00244163636f756e74496404000001244163636f756e744964006400001502000005090019020000050a001d020000050b0021020000050c002502104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040029020144426f756e6465645665633c75382c20533e000029020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00002d020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540111020453000004000d0201185665633c543e000031020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013502045300000400390201185665633c543e0000350200000408250211020039020000023502003d0200000200004102000002180045020c4470616c6c65745f74616e676c655f6c73741870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d62657220686173206265636f6d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c82020646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00250154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e20666f72206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f737461746549020124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654d02019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104b0436c61696d6564206578636573732066726f7a656e204544206f66207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e4902104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e67000200004d02104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e50436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d6265720000510204184f7074696f6e0404540155020108104e6f6e6500000010536f6d650400550200000100005502104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e64436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e74496400010000590208306672616d655f73797374656d14506861736500010c384170706c7945787472696e736963040010010c7533320000003046696e616c697a6174696f6e00010038496e697469616c697a6174696f6e000200005d02000002390100610208306672616d655f73797374656d584c61737452756e74696d6555706772616465496e666f0000080130737065635f76657273696f6e6502014c636f6465633a3a436f6d706163743c7533323e000124737065635f6e616d65ad01016473705f72756e74696d653a3a52756e74696d65537472696e67000065020000061000690208306672616d655f73797374656d60436f646555706772616465417574686f72697a6174696f6e0404540000080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00006d020c306672616d655f73797374656d1870616c6c65741043616c6c04045400012c1872656d61726b04011872656d61726b38011c5665633c75383e00000c684d616b6520736f6d65206f6e2d636861696e2072656d61726b2e008843616e20626520657865637574656420627920657665727920606f726967696e602e387365745f686561705f7061676573040114706167657330010c753634000104f853657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e207365745f636f6465040110636f646538011c5665633c75383e0002046453657420746865206e65772072756e74696d6520636f64652e5c7365745f636f64655f776974686f75745f636865636b73040110636f646538011c5665633c75383e000310190153657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e0051014e6f746520746861742072756e74696d652075706772616465732077696c6c206e6f742072756e20696620746869732069732063616c6c656420776974682061206e6f742d696e6372656173696e6720737065632076657273696f6e212c7365745f73746f726167650401146974656d73710201345665633c4b657956616c75653e0004046853657420736f6d65206974656d73206f662073746f726167652e306b696c6c5f73746f726167650401106b657973790201205665633c4b65793e000504744b696c6c20736f6d65206974656d732066726f6d2073746f726167652e2c6b696c6c5f70726566697808011870726566697838010c4b657900011c7375626b65797310010c75333200061011014b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e0039012a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465723d0174686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e4472656d61726b5f776974685f6576656e7404011872656d61726b38011c5665633c75383e000704a44d616b6520736f6d65206f6e2d636861696e2072656d61726b20616e6420656d6974206576656e742e44617574686f72697a655f75706772616465040124636f64655f6861736834011c543a3a486173680009106101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e80617574686f72697a655f757067726164655f776974686f75745f636865636b73040124636f64655f6861736834011c543a3a48617368000a206101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e005d015741524e494e473a205468697320617574686f72697a657320616e207570677261646520746861742077696c6c2074616b6520706c61636520776974686f757420616e792073616665747920636865636b732c20666f7259016578616d706c652074686174207468652073706563206e616d652072656d61696e73207468652073616d6520616e642074686174207468652076657273696f6e206e756d62657220696e637265617365732e204e6f74f07265636f6d6d656e64656420666f72206e6f726d616c207573652e205573652060617574686f72697a655f757067726164656020696e73746561642e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e606170706c795f617574686f72697a65645f75706772616465040110636f646538011c5665633c75383e000b24550150726f766964652074686520707265696d616765202872756e74696d652062696e617279292060636f64656020666f7220616e2075706772616465207468617420686173206265656e20617574686f72697a65642e00490149662074686520617574686f72697a6174696f6e20726571756972656420612076657273696f6e20636865636b2c20746869732063616c6c2077696c6c20656e73757265207468652073706563206e616d65e872656d61696e7320756e6368616e67656420616e6420746861742074686520737065632076657273696f6e2068617320696e637265617365642e005901446570656e64696e67206f6e207468652072756e74696d65277320604f6e536574436f64656020636f6e66696775726174696f6e2c20746869732066756e6374696f6e206d6179206469726563746c79206170706c791101746865206e65772060636f64656020696e207468652073616d6520626c6f636b206f7220617474656d707420746f207363686564756c652074686520757067726164652e0060416c6c206f726967696e732061726520616c6c6f7765642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e7102000002750200750200000408383800790200000238007d020c306672616d655f73797374656d186c696d69747330426c6f636b5765696768747300000c0128626173655f626c6f636b2801185765696768740001246d61785f626c6f636b2801185765696768740001247065725f636c617373810201845065724469737061746368436c6173733c57656967687473506572436c6173733e000081020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c617373040454018502000c01186e6f726d616c850201045400012c6f7065726174696f6e616c85020104540001246d616e6461746f72798502010454000085020c306672616d655f73797374656d186c696d6974733c57656967687473506572436c6173730000100138626173655f65787472696e7369632801185765696768740001346d61785f65787472696e736963890201384f7074696f6e3c5765696768743e0001246d61785f746f74616c890201384f7074696f6e3c5765696768743e0001207265736572766564890201384f7074696f6e3c5765696768743e0000890204184f7074696f6e04045401280108104e6f6e6500000010536f6d6504002800000100008d020c306672616d655f73797374656d186c696d6974732c426c6f636b4c656e677468000004010c6d6178910201545065724469737061746368436c6173733c7533323e000091020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540110000c01186e6f726d616c1001045400012c6f7065726174696f6e616c100104540001246d616e6461746f72791001045400009502082873705f776569676874733c52756e74696d65446257656967687400000801107265616430010c753634000114777269746530010c75363400009902082873705f76657273696f6e3852756e74696d6556657273696f6e0000200124737065635f6e616d65ad01013452756e74696d65537472696e67000124696d706c5f6e616d65ad01013452756e74696d65537472696e67000144617574686f72696e675f76657273696f6e10010c753332000130737065635f76657273696f6e10010c753332000130696d706c5f76657273696f6e10010c753332000110617069739d02011c4170697356656300014c7472616e73616374696f6e5f76657273696f6e10010c75333200013473746174655f76657273696f6e080108753800009d02040c436f7704045401a102000400a102000000a102000002a50200a50200000408a9021000a902000003080000000800ad020c306672616d655f73797374656d1870616c6c6574144572726f720404540001243c496e76616c6964537065634e616d650000081101546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e685370656356657273696f6e4e65656473546f496e63726561736500010841015468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e744661696c6564546f4578747261637452756e74696d6556657273696f6e00020cec4661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e0009014569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e4c4e6f6e44656661756c74436f6d706f73697465000304fc537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e3c4e6f6e5a65726f526566436f756e74000404350154686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e3043616c6c46696c7465726564000504d0546865206f726967696e2066696c7465722070726576656e74207468652063616c6c20746f20626520646973706174636865642e6c4d756c7469426c6f636b4d6967726174696f6e734f6e676f696e67000604550141206d756c74692d626c6f636b206d6967726174696f6e206973206f6e676f696e6720616e642070726576656e7473207468652063757272656e7420636f64652066726f6d206265696e67207265706c616365642e444e6f7468696e67417574686f72697a6564000704584e6f207570677261646520617574686f72697a65642e30556e617574686f72697a656400080494546865207375626d697474656420636f6465206973206e6f7420617574686f72697a65642e046c4572726f7220666f72207468652053797374656d2070616c6c6574b1020c4070616c6c65745f74696d657374616d701870616c6c65741043616c6c0404540001040c73657404010c6e6f772c0124543a3a4d6f6d656e7400004c54536574207468652063757272656e742074696d652e005501546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6ed470686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e0041015468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e7420737065636966696564206279685b60436f6e6669673a3a4d696e696d756d506572696f64605d2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0051015468697320646973706174636820636c617373206973205f4d616e6461746f72795f20746f20656e73757265206974206765747320657865637574656420696e2074686520626c6f636b2e204265206177617265510174686174206368616e67696e672074686520636f6d706c6578697479206f6620746869732063616c6c20636f756c6420726573756c742065786861757374696e6720746865207265736f757263657320696e206184626c6f636b20746f206578656375746520616e79206f746865722063616c6c732e0034232320436f6d706c657869747931012d20604f2831296020284e6f7465207468617420696d706c656d656e746174696f6e73206f6620604f6e54696d657374616d7053657460206d75737420616c736f20626520604f283129602955012d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f283129602062656361757365206f6620604469645570646174653a3a74616b656020696e402020606f6e5f66696e616c697a656029d42d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f736574602e204d75737420626520604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb5020c2c70616c6c65745f7375646f1870616c6c65741043616c6c040454000114107375646f04011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000004350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e547375646f5f756e636865636b65645f77656967687408011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000114350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e2d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b05375646f207573657220746f20737065636966792074686520776569676874206f66207468652063616c6c2e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e1c7365745f6b657904010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e0002085d0141757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f106b65792e1c7375646f5f617308010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0003104d0141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d406120676976656e206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2872656d6f76655f6b657900040c845065726d616e656e746c792072656d6f76657320746865207375646f206b65792e006c2a2a546869732063616e6e6f7420626520756e2d646f6e652e2a2a040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb902085874616e676c655f746573746e65745f72756e74696d652c52756e74696d6543616c6c0001941853797374656d04006d0201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53797374656d2c2052756e74696d653e0001002454696d657374616d700400b10201b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54696d657374616d702c2052756e74696d653e000200105375646f0400b50201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5375646f2c2052756e74696d653e000300184173736574730400bd0201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4173736574732c2052756e74696d653e0005002042616c616e6365730400c50201b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c42616c616e6365732c2052756e74696d653e00060010426162650400cd0201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426162652c2052756e74696d653e0009001c4772616e6470610400f10201b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4772616e6470612c2052756e74696d653e000a001c496e64696365730400210301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496e64696365732c2052756e74696d653e000b002444656d6f63726163790400250301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44656d6f63726163792c2052756e74696d653e000c001c436f756e63696c0400410301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436f756e63696c2c2052756e74696d653e000d001c56657374696e670400450301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c56657374696e672c2052756e74696d653e000e0024456c656374696f6e7304004d0301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e732c2052756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400550301fd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e50726f76696465724d756c746950686173652c2052756e74696d653e0010001c5374616b696e6704003d0401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5374616b696e672c2052756e74696d653e0011001c53657373696f6e0400710401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657373696f6e2c2052756e74696d653e0012002054726561737572790400790401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54726561737572792c2052756e74696d653e00140020426f756e746965730400810401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426f756e746965732c2052756e74696d653e001500344368696c64426f756e746965730400850401c90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4368696c64426f756e746965732c2052756e74696d653e00160020426167734c6973740400890401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426167734c6973742c2052756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304008d0401d10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4e6f6d696e6174696f6e506f6f6c732c2052756e74696d653e001800245363686564756c65720400a90401b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5363686564756c65722c2052756e74696d653e00190020507265696d6167650400b10401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c507265696d6167652c2052756e74696d653e001a001c547850617573650400b50401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c547850617573652c2052756e74696d653e001c0020496d4f6e6c696e650400b90401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496d4f6e6c696e652c2052756e74696d653e001d00204964656e746974790400c50401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4964656e746974792c2052756e74696d653e001e001c5574696c6974790400650501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5574696c6974792c2052756e74696d653e001f00204d756c746973696704007d0501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c74697369672c2052756e74696d653e00200020457468657265756d0400850501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c457468657265756d2c2052756e74696d653e0021000c45564d0400ad0501a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c45564d2c2052756e74696d653e0022002844796e616d69634665650400bd0501bd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44796e616d69634665652c2052756e74696d653e0024001c426173654665650400c10501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426173654665652c2052756e74696d653e00250044486f7466697853756666696369656e74730400c50501d90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c486f7466697853756666696369656e74732c2052756e74696d653e00260018436c61696d730400cd0501ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436c61696d732c2052756e74696d653e0027001450726f78790400f90501a90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c50726f78792c2052756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400010601e50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c7469417373657444656c65676174696f6e2c2052756e74696d653e002d002053657276696365730400190601b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657276696365732c2052756e74696d653e0033000c4c73740400e90601a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4c73742c2052756e74696d653e00340000bd020c3470616c6c65745f6173736574731870616c6c65741043616c6c080454000449000180186372656174650c010869646d01014c543a3a41737365744964506172616d6574657200011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e6365180128543a3a42616c616e636500004ce849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d2061207075626c6963206f726967696e2e00250154686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c7920616e6420697473206f776e657220697320746865206f726967696e2e006101546865206f726967696e206d75737420636f6e666f726d20746f2074686520636f6e6669677572656420604372656174654f726967696e6020616e6420686176652073756666696369656e742066756e647320667265652e00bc46756e6473206f662073656e64657220617265207265736572766564206279206041737365744465706f736974602e002c506172616d65746572733a59012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d206061646d696e603a205468652061646d696e206f66207468697320636c617373206f66206173736574732e205468652061646d696e2069732074686520696e697469616c2061646472657373206f6620656163689c6d656d626572206f662074686520617373657420636c61737327732061646d696e207465616d2e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e0098456d69747320604372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296030666f7263655f63726561746510010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00013469735f73756666696369656e74200110626f6f6c00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500014cf849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d20612070726976696c65676564206f726967696e2e00b454686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c792e00a4546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e602e009c556e6c696b652060637265617465602c206e6f2066756e6473206172652072657365727665642e0059012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d20606f776e6572603a20546865206f776e6572206f66207468697320636c617373206f66206173736574732e20546865206f776e6572206861732066756c6c20737570657275736572207065726d697373696f6e7325016f76657220746869732061737365742c20627574206d6179206c61746572206368616e676520616e6420636f6e66696775726520746865207065726d697373696f6e73207573696e6790607472616e736665725f6f776e6572736869706020616e6420607365745f7465616d602e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e00ac456d6974732060466f7263654372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f283129603473746172745f64657374726f7904010869646d01014c543a3a41737365744964506172616d6574657200022cdc5374617274207468652070726f63657373206f662064657374726f79696e6720612066756e6769626c6520617373657420636c6173732e0059016073746172745f64657374726f79602069732074686520666972737420696e206120736572696573206f662065787472696e7369637320746861742073686f756c642062652063616c6c65642c20746f20616c6c6f77786465737472756374696f6e206f6620616e20617373657420636c6173732e005101546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e60206f72206d75737420626520605369676e65646020627920746865206173736574277320606f776e6572602e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00f854686520617373657420636c617373206d7573742062652066726f7a656e206265666f72652063616c6c696e67206073746172745f64657374726f79602e4064657374726f795f6163636f756e747304010869646d01014c543a3a41737365744964506172616d65746572000330cc44657374726f7920616c6c206163636f756e7473206173736f6369617465642077697468206120676976656e2061737365742e005d016064657374726f795f6163636f756e7473602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79310164657374726f7920616c6c206163636f756e74732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d697460206163636f756e747320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d4456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f7965644163636f756e747360206576656e742e4464657374726f795f617070726f76616c7304010869646d01014c543a3a41737365744964506172616d65746572000430610144657374726f7920616c6c20617070726f76616c73206173736f6369617465642077697468206120676976656e20617373657420757020746f20746865206d61782028543a3a52656d6f76654974656d734c696d6974292e0061016064657374726f795f617070726f76616c73602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79390164657374726f7920616c6c20617070726f76616c732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d69746020617070726f76616c7320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d8456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f796564417070726f76616c7360206576656e742e3866696e6973685f64657374726f7904010869646d01014c543a3a41737365744964506172616d65746572000528c4436f6d706c6574652064657374726f79696e6720617373657420616e6420756e726573657276652063757272656e63792e0055016066696e6973685f64657374726f79602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e64207468655901617373657420697320696e2061206044657374726f79696e67602073746174652e20416c6c206163636f756e7473206f7220617070726f76616c732073686f756c642062652064657374726f796564206265666f72651468616e642e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00e045616368207375636365737366756c2063616c6c20656d6974732074686520604576656e743a3a44657374726f79656460206576656e742e106d696e740c010869646d01014c543a3a41737365744964506172616d6574657200012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000630884d696e7420617373657473206f66206120706172746963756c617220636c6173732e003901546865206f726967696e206d757374206265205369676e656420616e64207468652073656e646572206d7573742062652074686520497373756572206f662074686520617373657420606964602e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206d696e7465642e0d012d206062656e6566696369617279603a20546865206163636f756e7420746f206265206372656469746564207769746820746865206d696e746564206173736574732ec42d2060616d6f756e74603a2054686520616d6f756e74206f662074686520617373657420746f206265206d696e7465642e0094456d697473206049737375656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296055014d6f6465733a205072652d6578697374696e672062616c616e6365206f66206062656e6566696369617279603b204163636f756e74207072652d6578697374656e6365206f66206062656e6566696369617279602e106275726e0c010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500073c4501526564756365207468652062616c616e6365206f66206077686f60206279206173206d75636820617320706f737369626c6520757020746f2060616d6f756e746020617373657473206f6620606964602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204d616e61676572206f662074686520617373657420606964602e00d04261696c73207769746820604e6f4163636f756e746020696620746865206077686f6020697320616c726561647920646561642e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206275726e65642ea02d206077686f603a20546865206163636f756e7420746f20626520646562697465642066726f6d2e29012d2060616d6f756e74603a20546865206d6178696d756d20616d6f756e74206279207768696368206077686f6027732062616c616e63652073686f756c6420626520726564756365642e005101456d69747320604275726e6564602077697468207468652061637475616c20616d6f756e74206275726e65642e20496620746869732074616b6573207468652062616c616e636520746f2062656c6f772074686539016d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74206275726e656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296009014d6f6465733a20506f73742d6578697374656e6365206f66206077686f603b20507265202620706f7374205a6f6d6269652d737461747573206f66206077686f602e207472616e736665720c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000848d04d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e4c7472616e736665725f6b6565705f616c6976650c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500094859014d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722c206b656570696e67207468652073656e646572206163636f756e7420616c6976652e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e38666f7263655f7472616e7366657210010869646d01014c543a3a41737365744964506172616d65746572000118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000a4cb44d6f766520736f6d65206173736574732066726f6d206f6e65206163636f756e7420746f20616e6f746865722e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e982d2060736f75726365603a20546865206163636f756e7420746f20626520646562697465642e942d206064657374603a20546865206163636f756e7420746f2062652063726564697465642e59012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652060736f757263656027732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e64590160646573746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e4d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652060736f75726365602062616c616e63652061626f7665207a65726f20627574d462656c6f7720746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f66206064657374603b20506f73742d6578697374656e6365206f662060736f75726365603b204163636f756e74207072652d6578697374656e6365206f661c6064657374602e18667265657a6508010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000b305501446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e20617373657420606964602066726f6d20616e206163636f756e74206077686f602e206077686f604d016d75737420616c726561647920657869737420617320616e20656e74727920696e20604163636f756e746073206f66207468652061737365742e20496620796f752077616e7420746f20667265657a6520616ef46163636f756e74207468617420646f6573206e6f74206861766520616e20656e7472792c207573652060746f7563685f6f74686572602066697273742e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e882d206077686f603a20546865206163636f756e7420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f28312960107468617708010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000c28e8416c6c6f7720756e70726976696c65676564207472616e736665727320746f20616e642066726f6d20616e206163636f756e7420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e902d206077686f603a20546865206163636f756e7420746f20626520756e66726f7a656e2e003c456d6974732060546861776564602e00385765696768743a20604f2831296030667265657a655f617373657404010869646d01014c543a3a41737365744964506172616d65746572000d24f0446973616c6c6f77206675727468657220756e70726976696c65676564207472616e736665727320666f722074686520617373657420636c6173732e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f2831296028746861775f617373657404010869646d01014c543a3a41737365744964506172616d65746572000e24c4416c6c6f7720756e70726976696c65676564207472616e736665727320666f722074686520617373657420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206265207468617765642e003c456d6974732060546861776564602e00385765696768743a20604f28312960487472616e736665725f6f776e65727368697008010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e000f28744368616e676520746865204f776e6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742e0054456d69747320604f776e65724368616e676564602e00385765696768743a20604f28312960207365745f7465616d10010869646d01014c543a3a41737365744964506172616d65746572000118697373756572c10201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c10201504163636f756e7449644c6f6f6b75704f663c543e001030c44368616e676520746865204973737565722c2041646d696e20616e6420467265657a6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e0050456d69747320605465616d4368616e676564602e00385765696768743a20604f28312960307365745f6d6574616461746110010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c7308010875380011407853657420746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00d846756e6473206f662073656e64657220617265207265736572766564206163636f7264696e6720746f2074686520666f726d756c613a5101604d657461646174614465706f73697442617365202b204d657461646174614465706f73697450657242797465202a20286e616d652e6c656e202b2073796d626f6c2e6c656e29602074616b696e6720696e746f8c6163636f756e7420616e7920616c72656164792072657365727665642066756e64732e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e00385765696768743a20604f2831296038636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200122c80436c65617220746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00a4416e79206465706f73697420697320667265656420666f7220746865206173736574206f776e65722e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f7365745f6d6574616461746114010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c001338b8466f72636520746865206d6574616461746120666f7220616e20617373657420746f20736f6d652076616c75652e006c4f726967696e206d75737420626520466f7263654f726967696e2e0068416e79206465706f736974206973206c65667420616c6f6e652e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e0051015765696768743a20604f284e202b20532960207768657265204e20616e6420532061726520746865206c656e677468206f6620746865206e616d6520616e642073796d626f6c20726573706563746976656c792e50666f7263655f636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200142c80436c65617220746865206d6574616461746120666f7220616e2061737365742e006c4f726967696e206d75737420626520466f7263654f726967696e2e0060416e79206465706f7369742069732072657475726e65642e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f61737365745f73746174757320010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e000118697373756572c10201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec10201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500013469735f73756666696369656e74200110626f6f6c00012469735f66726f7a656e200110626f6f6c00155898416c746572207468652061747472696275746573206f66206120676976656e2061737365742e00744f726967696e206d7573742062652060466f7263654f726967696e602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e51012d206069735f73756666696369656e74603a20576865746865722061206e6f6e2d7a65726f2062616c616e6365206f662074686973206173736574206973206465706f736974206f662073756666696369656e744d0176616c756520746f206163636f756e7420666f722074686520737461746520626c6f6174206173736f6369617465642077697468206974732062616c616e63652073746f726167652e2049662073657420746f55016074727565602c207468656e206e6f6e2d7a65726f2062616c616e636573206d61792062652073746f72656420776974686f757420612060636f6e73756d657260207265666572656e63652028616e6420746875734d01616e20454420696e207468652042616c616e6365732070616c6c6574206f7220776861746576657220656c7365206973207573656420746f20636f6e74726f6c20757365722d6163636f756e742073746174652067726f777468292e3d012d206069735f66726f7a656e603a2057686574686572207468697320617373657420636c6173732069732066726f7a656e2065786365707420666f72207065726d697373696f6e65642f61646d696e34696e737472756374696f6e732e00e8456d697473206041737365745374617475734368616e67656460207769746820746865206964656e74697479206f66207468652061737365742e00385765696768743a20604f2831296040617070726f76655f7472616e736665720c010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650016502d01417070726f766520616e20616d6f756e74206f6620617373657420666f72207472616e7366657220627920612064656c6567617465642074686972642d7061727479206163636f756e742e00584f726967696e206d757374206265205369676e65642e004d01456e737572657320746861742060417070726f76616c4465706f7369746020776f727468206f66206043757272656e6379602069732072657365727665642066726f6d207369676e696e67206163636f756e745501666f722074686520707572706f7365206f6620686f6c64696e672074686520617070726f76616c2e20496620736f6d65206e6f6e2d7a65726f20616d6f756e74206f662061737365747320697320616c72656164794901617070726f7665642066726f6d207369676e696e67206163636f756e7420746f206064656c6567617465602c207468656e20697420697320746f70706564207570206f7220756e726573657276656420746f546d656574207468652072696768742076616c75652e0045014e4f54453a20546865207369676e696e67206163636f756e7420646f6573206e6f74206e65656420746f206f776e2060616d6f756e7460206f66206173736574732061742074686520706f696e74206f66446d616b696e6720746869732063616c6c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e0d012d206064656c6567617465603a20546865206163636f756e7420746f2064656c6567617465207065726d697373696f6e20746f207472616e736665722061737365742e49012d2060616d6f756e74603a2054686520616d6f756e74206f662061737365742074686174206d6179206265207472616e73666572726564206279206064656c6567617465602e204966207468657265206973e0616c726561647920616e20617070726f76616c20696e20706c6163652c207468656e207468697320616374732061646469746976656c792e0090456d6974732060417070726f7665645472616e7366657260206f6e20737563636573732e00385765696768743a20604f283129603c63616e63656c5f617070726f76616c08010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e001734490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e003d014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c616365206265747765656e207369676e657220616e642c6064656c6567617465602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f2831296054666f7263655f63616e63656c5f617070726f76616c0c010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e001834490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e0049014f726967696e206d7573742062652065697468657220466f7263654f726967696e206f72205369676e6564206f726967696e207769746820746865207369676e6572206265696e67207468652041646d696e686163636f756e74206f662074686520617373657420606964602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f28312960447472616e736665725f617070726f76656410010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012c64657374696e6174696f6ec10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650019484d015472616e7366657220736f6d652061737365742062616c616e63652066726f6d20612070726576696f75736c792064656c656761746564206163636f756e7420746f20736f6d652074686972642d7061727479206163636f756e742e0049014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c6163652062792074686520606f776e65726020746f207468651c7369676e65722e00590149662074686520656e7469726520616d6f756e7420617070726f76656420666f72207472616e73666572206973207472616e736665727265642c207468656e20616e79206465706f7369742070726576696f75736c79b472657365727665642062792060617070726f76655f7472616e736665726020697320756e72657365727665642e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e61012d20606f776e6572603a20546865206163636f756e742077686963682070726576696f75736c7920617070726f76656420666f722061207472616e73666572206f66206174206c656173742060616d6f756e746020616e64bc66726f6d207768696368207468652061737365742062616c616e63652077696c6c2062652077697468647261776e2e61012d206064657374696e6174696f6e603a20546865206163636f756e7420746f207768696368207468652061737365742062616c616e6365206f662060616d6f756e74602077696c6c206265207472616e736665727265642eb42d2060616d6f756e74603a2054686520616d6f756e74206f662061737365747320746f207472616e736665722e009c456d69747320605472616e73666572726564417070726f76656460206f6e20737563636573732e00385765696768743a20604f2831296014746f75636804010869646d01014c543a3a41737365744964506172616d65746572001a24c043726561746520616e206173736574206163636f756e7420666f72206e6f6e2d70726f7669646572206173736574732e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e005d012d20606f726967696e603a204d757374206265205369676e65643b20746865207369676e6572206163636f756e74206d75737420686176652073756666696369656e742066756e647320666f722061206465706f736974382020746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e18726566756e6408010869646d01014c543a3a41737365744964506172616d65746572000128616c6c6f775f6275726e200110626f6f6c001b28590152657475726e20746865206465706f7369742028696620616e7929206f6620616e206173736574206163636f756e74206f72206120636f6e73756d6572207265666572656e63652028696620616e7929206f6620616e206163636f756e742e0068546865206f726967696e206d757374206265205369676e65642e003d012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f72207768696368207468652063616c6c657220776f756c64206c696b6520746865206465706f7369742c2020726566756e6465642e5d012d2060616c6c6f775f6275726e603a20496620607472756560207468656e20617373657473206d61792062652064657374726f79656420696e206f7264657220746f20636f6d706c6574652074686520726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e3c7365745f6d696e5f62616c616e636508010869646d01014c543a3a41737365744964506172616d6574657200012c6d696e5f62616c616e6365180128543a3a42616c616e6365001c30945365747320746865206d696e696d756d2062616c616e6365206f6620616e2061737365742e0021014f6e6c7920776f726b73206966207468657265206172656e277420616e79206163636f756e747320746861742061726520686f6c64696e6720746865206173736574206f72206966e0746865206e65772076616c7565206f6620606d696e5f62616c616e636560206973206c657373207468616e20746865206f6c64206f6e652e00fc4f726967696e206d757374206265205369676e656420616e64207468652073656e6465722068617320746f20626520746865204f776e6572206f66207468652c617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742ec02d20606d696e5f62616c616e6365603a20546865206e65772076616c7565206f6620606d696e5f62616c616e6365602e00d4456d697473206041737365744d696e42616c616e63654368616e67656460206576656e74207768656e207375636365737366756c2e2c746f7563685f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001d288843726561746520616e206173736574206163636f756e7420666f72206077686f602e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e0061012d20606f726967696e603a204d757374206265205369676e65642062792060467265657a657260206f72206041646d696e60206f662074686520617373657420606964603b20746865207369676e6572206163636f756e74dc20206d75737420686176652073756666696369656e742066756e647320666f722061206465706f73697420746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e8c2d206077686f603a20546865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e30726566756e645f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001e285d0152657475726e20746865206465706f7369742028696620616e7929206f66206120746172676574206173736574206163636f756e742e2055736566756c20696620796f752061726520746865206465706f7369746f722e005d01546865206f726967696e206d757374206265205369676e656420616e642065697468657220746865206163636f756e74206f776e65722c206465706f7369746f722c206f72206173736574206041646d696e602e20496e61016f7264657220746f206275726e2061206e6f6e2d7a65726f2062616c616e6365206f66207468652061737365742c207468652063616c6c6572206d75737420626520746865206163636f756e7420616e642073686f756c64347573652060726566756e64602e0019012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420686f6c64696e672061206465706f7369742e7c2d206077686f603a20546865206163636f756e7420746f20726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e14626c6f636b08010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e001f285901446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e206173736574206069646020746f20616e642066726f6d20616e206163636f756e74206077686f602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00b82d20606964603a20546865206964656e746966696572206f6620746865206163636f756e7427732061737365742e942d206077686f603a20546865206163636f756e7420746f20626520756e626c6f636b65642e0040456d6974732060426c6f636b6564602e00385765696768743a20604f28312960040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec1020c2873705f72756e74696d65306d756c746961646472657373304d756c74694164647265737308244163636f756e7449640100304163636f756e74496e6465780110011408496404000001244163636f756e74496400000014496e6465780400650201304163636f756e74496e6465780001000c526177040038011c5665633c75383e0002002441646472657373333204000401205b75383b2033325d000300244164647265737332300400950101205b75383b2032305d00040000c5020c3c70616c6c65745f62616c616e6365731870616c6c65741043616c6c080454000449000124507472616e736665725f616c6c6f775f646561746808011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e636500001cd45472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e003501607472616e736665725f616c6c6f775f6465617468602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e11014966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74b06f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e38666f7263655f7472616e736665720c0118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000208610145786163746c7920617320607472616e736665725f616c6c6f775f6465617468602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74446d6179206265207370656369666965642e4c7472616e736665725f6b6565705f616c69766508011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000318590153616d6520617320746865205b607472616e736665725f616c6c6f775f6465617468605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74606b696c6c20746865206f726967696e206163636f756e742e00e8393925206f66207468652074696d6520796f752077616e74205b607472616e736665725f616c6c6f775f6465617468605d20696e73746561642e00f05b607472616e736665725f616c6c6f775f6465617468605d3a207374727563742e50616c6c65742e68746d6c236d6574686f642e7472616e73666572307472616e736665725f616c6c08011064657374c10201504163636f756e7449644c6f6f6b75704f663c543e0001286b6565705f616c697665200110626f6f6c00043c05015472616e736665722074686520656e74697265207472616e7366657261626c652062616c616e63652066726f6d207468652063616c6c6572206163636f756e742e0059014e4f54453a20546869732066756e6374696f6e206f6e6c7920617474656d70747320746f207472616e73666572205f7472616e7366657261626c655f2062616c616e6365732e2054686973206d65616e7320746861746101616e79206c6f636b65642c2072657365727665642c206f72206578697374656e7469616c206465706f7369747320287768656e20606b6565705f616c6976656020697320607472756560292c2077696c6c206e6f742062655d017472616e7366657272656420627920746869732066756e6374696f6e2e20546f20656e73757265207468617420746869732066756e6374696f6e20726573756c747320696e2061206b696c6c6564206163636f756e742c4501796f75206d69676874206e65656420746f207072657061726520746865206163636f756e742062792072656d6f76696e6720616e79207265666572656e636520636f756e746572732c2073746f72616765406465706f736974732c206574632e2e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205369676e65642e00a02d206064657374603a2054686520726563697069656e74206f6620746865207472616e736665722e59012d20606b6565705f616c697665603a204120626f6f6c65616e20746f2064657465726d696e652069662074686520607472616e736665725f616c6c60206f7065726174696f6e2073686f756c642073656e6420616c6c4d0120206f66207468652066756e647320746865206163636f756e74206861732c2063617573696e67207468652073656e646572206163636f756e7420746f206265206b696c6c6564202866616c7365292c206f72590120207472616e736665722065766572797468696e6720657863657074206174206c6561737420746865206578697374656e7469616c206465706f7369742c2077686963682077696c6c2067756172616e74656520746f9c20206b656570207468652073656e646572206163636f756e7420616c697665202874727565292e3c666f7263655f756e7265736572766508010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e74180128543a3a42616c616e636500050cb0556e7265736572766520736f6d652062616c616e63652066726f6d2061207573657220627920666f7263652e006c43616e206f6e6c792062652063616c6c656420627920524f4f542e40757067726164655f6163636f756e747304010c77686f3d0201445665633c543a3a4163636f756e7449643e0006207055706772616465206120737065636966696564206163636f756e742e00742d20606f726967696e603a204d75737420626520605369676e6564602e902d206077686f603a20546865206163636f756e7420746f2062652075706772616465642e005501546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966206174206c6561737420616c6c2062757420313025206f6620746865206163636f756e7473206e656564656420746f410162652075706772616465642e20285765206c657420736f6d65206e6f74206861766520746f206265207570677261646564206a75737420696e206f7264657220746f20616c6c6f7720666f722074686558706f73736962696c697479206f6620636875726e292e44666f7263655f7365745f62616c616e636508010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e0001206e65775f667265656d010128543a3a42616c616e636500080cac5365742074686520726567756c61722062616c616e6365206f66206120676976656e206163636f756e742e00b0546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e6c666f7263655f61646a7573745f746f74616c5f69737375616e6365080124646972656374696f6ec902014c41646a7573746d656e74446972656374696f6e00011464656c74616d010128543a3a42616c616e6365000914b841646a7573742074686520746f74616c2069737375616e636520696e20612073617475726174696e67207761792e00fc43616e206f6e6c792062652063616c6c656420627920726f6f7420616e6420616c77617973206e65656473206120706f736974697665206064656c7461602e002423204578616d706c65106275726e08011476616c75656d010128543a3a42616c616e63650001286b6565705f616c697665200110626f6f6c000a1cfc4275726e2074686520737065636966696564206c697175696420667265652062616c616e63652066726f6d20746865206f726967696e206163636f756e742e002501496620746865206f726967696e2773206163636f756e7420656e64732075702062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c7409016f6620746865206275726e20616e6420606b6565705f616c697665602069732066616c73652c20746865206163636f756e742077696c6c206265207265617065642e005101556e6c696b652073656e64696e672066756e647320746f2061205f6275726e5f20616464726573732c207768696368206d6572656c79206d616b6573207468652066756e647320696e61636365737369626c652c21017468697320606275726e60206f7065726174696f6e2077696c6c2072656475636520746f74616c2069737375616e63652062792074686520616d6f756e74205f6275726e65645f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec9020c3c70616c6c65745f62616c616e6365731474797065734c41646a7573746d656e74446972656374696f6e00010820496e63726561736500000020446563726561736500010000cd020c2c70616c6c65745f626162651870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66d1020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e1020140543a3a4b65794f776e657250726f6f6600001009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66d1020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e1020140543a3a4b65794f776e657250726f6f6600012009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e0d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e48706c616e5f636f6e6669675f6368616e6765040118636f6e666967e50201504e657874436f6e66696744657363726970746f720002105d01506c616e20616e2065706f636820636f6e666967206368616e67652e205468652065706f636820636f6e666967206368616e6765206973207265636f7264656420616e642077696c6c20626520656e6163746564206f6e5101746865206e6578742063616c6c20746f2060656e6163745f65706f63685f6368616e6765602e2054686520636f6e6669672077696c6c20626520616374697661746564206f6e652065706f63682061667465722e59014d756c7469706c652063616c6c7320746f2074686973206d6574686f642077696c6c207265706c61636520616e79206578697374696e6720706c616e6e656420636f6e666967206368616e6765207468617420686164546e6f74206265656e20656e6163746564207965742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed102084873705f636f6e73656e7375735f736c6f74734445717569766f636174696f6e50726f6f66081848656164657201d50208496401d902001001206f6666656e646572d90201084964000110736c6f74dd020110536c6f7400013066697273745f686561646572d50201184865616465720001347365636f6e645f686561646572d50201184865616465720000d502102873705f72756e74696d651c67656e65726963186865616465721848656164657208184e756d62657201301048617368000014012c706172656e745f68617368340130486173683a3a4f75747075740001186e756d6265722c01184e756d62657200012873746174655f726f6f74340130486173683a3a4f757470757400013c65787472696e736963735f726f6f74340130486173683a3a4f75747075740001186469676573743c01184469676573740000d9020c4473705f636f6e73656e7375735f626162650c617070185075626c69630000040004013c737232353531393a3a5075626c69630000dd02084873705f636f6e73656e7375735f736c6f747310536c6f740000040030010c7536340000e102082873705f73657373696f6e3c4d656d6265727368697050726f6f6600000c011c73657373696f6e10013053657373696f6e496e646578000128747269655f6e6f646573790201305665633c5665633c75383e3e00013c76616c696461746f725f636f756e7410013856616c696461746f72436f756e740000e5020c4473705f636f6e73656e7375735f626162651c64696765737473504e657874436f6e66696744657363726970746f7200010408563108010463e9020128287536342c2075363429000134616c6c6f7765645f736c6f7473ed020130416c6c6f776564536c6f747300010000e90200000408303000ed02084473705f636f6e73656e7375735f6261626530416c6c6f776564536c6f747300010c305072696d617279536c6f7473000000745072696d617279416e645365636f6e64617279506c61696e536c6f74730001006c5072696d617279416e645365636f6e64617279565246536c6f747300020000f1020c3870616c6c65745f6772616e6470611870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66f50201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f661d030140543a3a4b65794f776e657250726f6f6600001009015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66f50201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f661d030140543a3a4b65794f776e657250726f6f6600012409015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e000d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e306e6f74655f7374616c6c656408011464656c6179300144426c6f636b4e756d626572466f723c543e00016c626573745f66696e616c697a65645f626c6f636b5f6e756d626572300144426c6f636b4e756d626572466f723c543e0002303d014e6f74652074686174207468652063757272656e7420617574686f7269747920736574206f6620746865204752414e4450412066696e616c6974792067616467657420686173207374616c6c65642e006101546869732077696c6c2074726967676572206120666f7263656420617574686f7269747920736574206368616e67652061742074686520626567696e6e696e67206f6620746865206e6578742073657373696f6e2c20746f6101626520656e6163746564206064656c61796020626c6f636b7320616674657220746861742e20546865206064656c6179602073686f756c64206265206869676820656e6f75676820746f20736166656c7920617373756d654901746861742074686520626c6f636b207369676e616c6c696e672074686520666f72636564206368616e67652077696c6c206e6f742062652072652d6f7267656420652e672e203130303020626c6f636b732e5d0154686520626c6f636b2070726f64756374696f6e207261746520287768696368206d617920626520736c6f77656420646f776e2062656361757365206f662066696e616c697479206c616767696e67292073686f756c64510162652074616b656e20696e746f206163636f756e74207768656e2063686f6f73696e6720746865206064656c6179602e20546865204752414e44504120766f74657273206261736564206f6e20746865206e65775501617574686f726974792077696c6c20737461727420766f74696e67206f6e20746f70206f662060626573745f66696e616c697a65645f626c6f636b5f6e756d6265726020666f72206e65772066696e616c697a65644d01626c6f636b732e2060626573745f66696e616c697a65645f626c6f636b5f6e756d626572602073686f756c64206265207468652068696768657374206f6620746865206c61746573742066696e616c697a6564c4626c6f636b206f6620616c6c2076616c696461746f7273206f6620746865206e657720617574686f72697479207365742e00584f6e6c792063616c6c61626c6520627920726f6f742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef502085073705f636f6e73656e7375735f6772616e6470614445717569766f636174696f6e50726f6f660804480134044e0130000801187365745f6964300114536574496400013065717569766f636174696f6ef902014845717569766f636174696f6e3c482c204e3e0000f902085073705f636f6e73656e7375735f6772616e6470613045717569766f636174696f6e0804480134044e013001081c507265766f74650400fd0201890166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265766f74653c0a482c204e3e2c20417574686f726974795369676e61747572652c3e00000024507265636f6d6d69740400110301910166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265636f6d6d69740a3c482c204e3e2c20417574686f726974795369676e61747572652c3e00010000fd02084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456010103045301050300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273740d03011828562c2053290001187365636f6e640d03011828562c20532900000103084066696e616c6974795f6772616e6470611c507265766f74650804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000005030c5073705f636f6e73656e7375735f6772616e6470610c617070245369676e61747572650000040009030148656432353531393a3a5369676e6174757265000009030000034000000008000d030000040801030503001103084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456011503045301050300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273741903011828562c2053290001187365636f6e641903011828562c20532900001503084066696e616c6974795f6772616e64706124507265636f6d6d69740804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000019030000040815030503001d03081c73705f636f726510566f69640001000021030c3870616c6c65745f696e64696365731870616c6c65741043616c6c04045400011414636c61696d040114696e64657810013c543a3a4163636f756e74496e6465780000309841737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e00dc5061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00f02d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e207472616e7366657208010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e6465780001305d0141737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6eb86973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0025012d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e1066726565040114696e64657810013c543a3a4163636f756e74496e646578000230944672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e005d015061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e000d012d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e0084456d6974732060496e646578467265656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e38666f7263655f7472616e736665720c010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e646578000118667265657a65200110626f6f6c0003345501466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c7265616479e868656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00a42d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e41012d2060667265657a65603a2069662073657420746f206074727565602c2077696c6c20667265657a652074686520696e64657820736f2069742063616e6e6f74206265207472616e736665727265642e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e18667265657a65040114696e64657810013c543a3a4163636f756e74496e6465780004304101467265657a6520616e20696e64657820736f2069742077696c6c20616c7761797320706f696e7420746f207468652073656e646572206163636f756e742e205468697320636f6e73756d657320746865206465706f7369742e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d757374206861766520616c6e6f6e2d66726f7a656e206163636f756e742060696e646578602e00ac2d2060696e646578603a2074686520696e64657820746f2062652066726f7a656e20696e20706c6163652e0088456d6974732060496e64657846726f7a656e60206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e25030c4070616c6c65745f64656d6f63726163791870616c6c65741043616c6c04045400014c1c70726f706f736508012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00011476616c75656d01013042616c616e63654f663c543e0000249c50726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e001501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737480686176652066756e647320746f20636f76657220746865206465706f7369742e00d42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e15012d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e0044456d697473206050726f706f736564602e187365636f6e6404012070726f706f73616c6502012450726f70496e646578000118b45369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e64657211016d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e00c82d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e10766f74650801247265665f696e6465786502013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e00021c3101566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3bb86f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00dc2d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e842d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e40656d657267656e63795f63616e63656c0401247265665f696e64657810013c5265666572656e64756d496e6465780003204d015363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d652c7265666572656e64756d2e00f8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e00d02d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e003c5765696768743a20604f283129602e4065787465726e616c5f70726f706f736504012070726f706f73616c29030140426f756e64656443616c6c4f663c543e0004182d015363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c2c7265666572656e64756d2e00e8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e6465787465726e616c5f70726f706f73655f6d616a6f7269747904012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00052c55015363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c655c616e2065787465726e616c207265666572656e64756d2e00ec546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f283129606065787465726e616c5f70726f706f73655f64656661756c7404012070726f706f73616c29030140426f756e64656443616c6c4f663c543e00062c45015363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f807363686564756c6520616e2065787465726e616c207265666572656e64756d2e00e8546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f2831296028666173745f747261636b0c013470726f706f73616c5f6861736834011c543a3a48617368000134766f74696e675f706572696f64300144426c6f636b4e756d626572466f723c543e00011464656c6179300144426c6f636b4e756d626572466f723c543e0007404d015363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c65646101696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e65e8627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e00d0546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e00f42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e5d012d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f88094d75737420626520616c776179732067726561746572207468616e207a65726f2e350109466f72206046617374547261636b4f726967696e60206d75737420626520657175616c206f722067726561746572207468616e206046617374547261636b566f74696e67506572696f64602e51012d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265b82020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e0040456d697473206053746172746564602e00385765696768743a20604f28312960347665746f5f65787465726e616c04013470726f706f73616c5f6861736834011c543a3a48617368000824b85665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e00d8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e002d012d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e003c456d69747320605665746f6564602e00fc5765696768743a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f657273604463616e63656c5f7265666572656e64756d0401247265665f696e6465786502013c5265666572656e64756d496e64657800091c5052656d6f76652061207265666572656e64756d2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e00d42d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e004423205765696768743a20604f283129602e2064656c65676174650c0108746fc10201504163636f756e7449644c6f6f6b75704f663c543e000128636f6e76696374696f6e35030128436f6e76696374696f6e00011c62616c616e636518013042616c616e63654f663c543e000a50390144656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e0055015468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f7220746865c874696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a7420202d2062652064656c65676174696e6720616c72656164793b206f72590120202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656494202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e0045012d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e55012d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e20746865410120206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e61012d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d757374206e6f74b420206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e0048456d697473206044656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e28756e64656c6567617465000b30cc556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e005d01546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64dc6f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062655463757272656e746c792064656c65676174696e672e0050456d6974732060556e64656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e58636c6561725f7075626c69635f70726f706f73616c73000c1470436c6561727320616c6c207075626c69632070726f706f73616c732e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e003c5765696768743a20604f283129602e18756e6c6f636b040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000d1ca0556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00b82d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e00bc5765696768743a20604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e2c72656d6f76655f766f7465040114696e64657810013c5265666572656e64756d496e646578000e6c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e000c49663a882d20746865207265666572656e64756d207761732063616e63656c6c65642c206f727c2d20746865207265666572656e64756d206973206f6e676f696e672c206f72902d20746865207265666572656e64756d2068617320656e64656420737563682074686174fc20202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f72d420202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f728420202d20746865206163636f756e74206d61646520612073706c697420766f74655d012e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72655866756e6473206265696e6720617661696c61626c652e00a849662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643aec2d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64dc2d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64bc2d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f76657259012e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c766559012a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756de46f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e004901546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465887265676973746572656420666f72207265666572656e64756d2060696e646578602e00f42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e4472656d6f76655f6f746865725f766f7465080118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c5265666572656e64756d496e646578000f3c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e004d0149662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f2d016072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c5501656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7298626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e004d012d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f725420207265666572656e64756d2060696e646578602ef42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e24626c61636b6c69737408013470726f706f73616c5f6861736834011c543a3a4861736800013c6d617962655f7265665f696e6465783903015c4f7074696f6e3c5265666572656e64756d496e6465783e00103c45015065726d616e656e746c7920706c61636520612070726f706f73616c20696e746f2074686520626c61636b6c6973742e20546869732070726576656e74732069742066726f6d2065766572206265696e673c70726f706f73656420616761696e2e00510149662063616c6c6564206f6e206120717565756564207075626c6963206f722065787465726e616c2070726f706f73616c2c207468656e20746869732077696c6c20726573756c7420696e206974206265696e67510172656d6f7665642e2049662074686520607265665f696e6465786020737570706c69656420697320616e20616374697665207265666572656e64756d2077697468207468652070726f706f73616c20686173682c687468656e2069742077696c6c2062652063616e63656c6c65642e00ec546865206469737061746368206f726967696e206f6620746869732063616c6c206d7573742062652060426c61636b6c6973744f726967696e602e00f82d206070726f706f73616c5f68617368603a205468652070726f706f73616c206861736820746f20626c61636b6c697374207065726d616e656e746c792e45012d20607265665f696e646578603a20416e206f6e676f696e67207265666572656e64756d2077686f73652068617368206973206070726f706f73616c5f68617368602c2077686963682077696c6c2062652863616e63656c6c65642e0041015765696768743a20604f28702960202874686f756768206173207468697320697320616e20686967682d70726976696c6567652064697370617463682c20776520617373756d65206974206861732061502020726561736f6e61626c652076616c7565292e3c63616e63656c5f70726f706f73616c04012870726f705f696e6465786502012450726f70496e64657800111c4852656d6f766520612070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c50726f706f73616c4f726967696e602e00d02d206070726f705f696e646578603a2054686520696e646578206f66207468652070726f706f73616c20746f2063616e63656c2e00e45765696768743a20604f28702960207768657265206070203d205075626c696350726f70733a3a3c543e3a3a6465636f64655f6c656e282960307365745f6d657461646174610801146f776e6572c001344d657461646174614f776e65720001286d617962655f686173683d03013c4f7074696f6e3c543a3a486173683e00123cd8536574206f7220636c6561722061206d65746164617461206f6620612070726f706f73616c206f722061207265666572656e64756d2e002c506172616d65746572733acc2d20606f726967696e603a204d75737420636f72726573706f6e6420746f2074686520604d657461646174614f776e6572602e3d01202020202d206045787465726e616c4f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479417070726f766560402020202020207468726573686f6c642e5901202020202d206045787465726e616c44656661756c744f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479416761696e737460402020202020207468726573686f6c642e4501202020202d206045787465726e616c4d616a6f726974794f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053696d706c654d616a6f7269747960402020202020207468726573686f6c642ec8202020202d20605369676e65646020627920612063726561746f7220666f722061207075626c69632070726f706f73616c2ef4202020202d20605369676e65646020746f20636c6561722061206d6574616461746120666f7220612066696e6973686564207265666572656e64756d2ee4202020202d2060526f6f746020746f207365742061206d6574616461746120666f7220616e206f6e676f696e67207265666572656e64756d2eb42d20606f776e6572603a20616e206964656e746966696572206f662061206d65746164617461206f776e65722e51012d20606d617962655f68617368603a205468652068617368206f6620616e206f6e2d636861696e2073746f72656420707265696d6167652e20604e6f6e656020746f20636c6561722061206d657461646174612e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e290310346672616d655f737570706f72741874726169747324707265696d616765731c426f756e64656408045401b9020448012d03010c184c656761637904011068617368340124483a3a4f757470757400000018496e6c696e65040031030134426f756e646564496e6c696e65000100184c6f6f6b757008011068617368340124483a3a4f757470757400010c6c656e10010c753332000200002d030c2873705f72756e74696d65187472616974732c426c616b6554776f3235360000000031030c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000035030c4070616c6c65745f64656d6f637261637928636f6e76696374696f6e28436f6e76696374696f6e00011c104e6f6e65000000204c6f636b65643178000100204c6f636b65643278000200204c6f636b65643378000300204c6f636b65643478000400204c6f636b65643578000500204c6f636b6564367800060000390304184f7074696f6e04045401100108104e6f6e6500000010536f6d6504001000000100003d0304184f7074696f6e04045401340108104e6f6e6500000010536f6d65040034000001000041030c4470616c6c65745f636f6c6c6563746976651870616c6c65741043616c6c0804540004490001182c7365745f6d656d626572730c012c6e65775f6d656d626572733d0201445665633c543a3a4163636f756e7449643e0001147072696d658801504f7074696f6e3c543a3a4163636f756e7449643e0001246f6c645f636f756e7410012c4d656d626572436f756e74000060805365742074686520636f6c6c6563746976652773206d656d626572736869702e0045012d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642ee02d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e59012d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e205573656420666f7250202077656967687420657374696d6174696f6e2e00d4546865206469737061746368206f6620746869732063616c6c206d75737420626520605365744d656d626572734f726967696e602e0051014e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d61784d656d6265727360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c2062757421012020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e002823205741524e494e473a005901546865206070616c6c65742d636f6c6c656374697665602063616e20616c736f206265206d616e61676564206279206c6f676963206f757473696465206f66207468652070616c6c6574207468726f75676820746865b8696d706c656d656e746174696f6e206f6620746865207472616974205b604368616e67654d656d62657273605d2e5501416e792063616c6c20746f20607365745f6d656d6265727360206d757374206265206361726566756c207468617420746865206d656d6265722073657420646f65736e277420676574206f7574206f662073796e63a477697468206f74686572206c6f676963206d616e6167696e6720746865206d656d626572207365742e0038232320436f6d706c65786974793a502d20604f284d50202b204e29602077686572653ae020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429e020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564299820202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564291c6578656375746508012070726f706f73616cb902017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646502010c753332000124f0446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e00a84f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e0038232320436f6d706c65786974793a5c2d20604f2842202b204d202b205029602077686572653ad82d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429882d20604d60206d656d626572732d636f756e742028636f64652d626f756e64656429a82d2060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c601c70726f706f73650c01247468726573686f6c646502012c4d656d626572436f756e7400012070726f706f73616cb902017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646502010c753332000238f84164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e00845265717569726573207468652073656e64657220746f206265206d656d6265722e004101607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029546f722070757420757020666f7220766f74696e672e0034232320436f6d706c6578697479ac2d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c420202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653af4202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c20326029fc202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d2032602910766f74650c012070726f706f73616c34011c543a3a48617368000114696e6465786502013450726f706f73616c496e64657800011c617070726f7665200110626f6f6c000324f041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e008c5265717569726573207468652073656e64657220746f2062652061206d656d6265722e0049015472616e73616374696f6e20666565732077696c6c2062652077616976656420696620746865206d656d62657220697320766f74696e67206f6e20616e7920706172746963756c61722070726f706f73616c5101666f72207468652066697273742074696d6520616e64207468652063616c6c206973207375636365737366756c2e2053756273657175656e7420766f7465206368616e6765732077696c6c206368617267652061106665652e34232320436f6d706c657869747909012d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564294c646973617070726f76655f70726f706f73616c04013470726f706f73616c5f6861736834011c543a3a486173680005285901446973617070726f766520612070726f706f73616c2c20636c6f73652c20616e642072656d6f76652069742066726f6d207468652073797374656d2c207265676172646c657373206f66206974732063757272656e741873746174652e00884d7573742062652063616c6c65642062792074686520526f6f74206f726967696e2e002c506172616d65746572733a1d012a206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20746861742073686f756c6420626520646973617070726f7665642e0034232320436f6d706c6578697479ac4f285029207768657265205020697320746865206e756d626572206f66206d61782070726f706f73616c7314636c6f736510013470726f706f73616c5f6861736834011c543a3a48617368000114696e6465786502013450726f706f73616c496e64657800015470726f706f73616c5f7765696768745f626f756e642801185765696768740001306c656e6774685f626f756e646502010c7533320006604d01436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e0055014d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e00490149662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f7465206966206974206973bc68617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e00490149662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e732501756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e00610149662074686520636c6f7365206f7065726174696f6e20636f6d706c65746573207375636365737366756c6c79207769746820646973617070726f76616c2c20746865207472616e73616374696f6e206665652077696c6c5d016265207761697665642e204f746865727769736520657865637574696f6e206f662074686520617070726f766564206f7065726174696f6e2077696c6c206265206368617267656420746f207468652063616c6c65722e0061012b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642470726f706f73616c2e61012b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b65642076696135016073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e0034232320436f6d706c6578697479742d20604f2842202b204d202b205031202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c820202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652ea420202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e45030c3870616c6c65745f76657374696e671870616c6c65741043616c6c0404540001181076657374000024b8556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e005d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e28766573745f6f74686572040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e00012cb8556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051012d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e3c7665737465645f7472616e73666572080118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65490301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00023464437265617465206120766573746564207472616e736665722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00cc2d2060746172676574603a20546865206163636f756e7420726563656976696e6720746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e54666f7263655f7665737465645f7472616e736665720c0118736f75726365c10201504163636f756e7449644c6f6f6b75704f663c543e000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c65490301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00033860466f726365206120766573746564207472616e736665722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00e82d2060736f75726365603a20546865206163636f756e742077686f73652066756e64732073686f756c64206265207472616e736665727265642e11012d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e3c6d657267655f7363686564756c657308013c7363686564756c65315f696e64657810010c75333200013c7363686564756c65325f696e64657810010c7533320004545d014d657267652074776f2076657374696e67207363686564756c657320746f6765746865722c206372656174696e672061206e65772076657374696e67207363686564756c65207468617420756e6c6f636b73206f7665725501746865206869676865737420706f737369626c6520737461727420616e6420656e6420626c6f636b732e20496620626f7468207363686564756c6573206861766520616c7265616479207374617274656420746865590163757272656e7420626c6f636b2077696c6c206265207573656420617320746865207363686564756c652073746172743b207769746820746865206361766561742074686174206966206f6e65207363686564756c655d0169732066696e6973686564206279207468652063757272656e7420626c6f636b2c20746865206f746865722077696c6c206265207472656174656420617320746865206e6577206d6572676564207363686564756c652c2c756e6d6f6469666965642e00f84e4f54453a20496620607363686564756c65315f696e646578203d3d207363686564756c65325f696e6465786020746869732069732061206e6f2d6f702e41014e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b207072696f7220746f206d657267696e672e61014e4f54453a20496620626f7468207363686564756c6573206861766520656e646564206279207468652063757272656e7420626c6f636b2c206e6f206e6577207363686564756c652077696c6c206265206372656174656464616e6420626f74682077696c6c2062652072656d6f7665642e006c4d6572676564207363686564756c6520617474726962757465733a35012d20607374617274696e675f626c6f636b603a20604d4158287363686564756c65312e7374617274696e675f626c6f636b2c207363686564756c6564322e7374617274696e675f626c6f636b2c48202063757272656e745f626c6f636b29602e21012d2060656e64696e675f626c6f636b603a20604d4158287363686564756c65312e656e64696e675f626c6f636b2c207363686564756c65322e656e64696e675f626c6f636b29602e59012d20606c6f636b6564603a20607363686564756c65312e6c6f636b65645f61742863757272656e745f626c6f636b29202b207363686564756c65322e6c6f636b65645f61742863757272656e745f626c6f636b29602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00e82d20607363686564756c65315f696e646578603a20696e646578206f6620746865206669727374207363686564756c6520746f206d657267652eec2d20607363686564756c65325f696e646578603a20696e646578206f6620746865207365636f6e64207363686564756c6520746f206d657267652e74666f7263655f72656d6f76655f76657374696e675f7363686564756c65080118746172676574c102018c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263650001387363686564756c655f696e64657810010c7533320005187c466f7263652072656d6f766520612076657374696e67207363686564756c6500c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00c82d2060746172676574603a20416e206163636f756e7420746861742068617320612076657374696e67207363686564756c6515012d20607363686564756c655f696e646578603a205468652076657374696e67207363686564756c6520696e64657820746861742073686f756c642062652072656d6f766564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e49030c3870616c6c65745f76657374696e673076657374696e675f696e666f2c56657374696e67496e666f081c42616c616e636501182c426c6f636b4e756d6265720130000c01186c6f636b656418011c42616c616e63650001247065725f626c6f636b18011c42616c616e63650001387374617274696e675f626c6f636b30012c426c6f636b4e756d62657200004d030c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c65741043616c6c04045400011810766f7465080114766f7465733d0201445665633c543a3a4163636f756e7449643e00011476616c75656d01013042616c616e63654f663c543e00004c5901566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746fe07365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e005d0155706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e642061206465706f73697420616d6f756e742069734d0172657365727665642e20546865206465706f736974206973206261736564206f6e20746865206e756d626572206f6620766f74657320616e642063616e2062652075706461746564206f7665722074696d652e004c5468652060766f746573602073686f756c643a4420202d206e6f7420626520656d7074792e550120202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e6411012020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e0049014966206076616c756560206973206d6f7265207468616e206077686f60277320667265652062616c616e63652c207468656e20746865206d6178696d756d206f66207468652074776f20697320757365642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e6700550149742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f202a2a4e4f542a2a20706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865a86c6f636b20616e64206b65657020736f6d6520666f722066757274686572206f7065726174696f6e732e3072656d6f76655f766f7465720001146c52656d6f766520606f726967696e60206173206120766f7465722e00b8546869732072656d6f76657320746865206c6f636b20616e642072657475726e7320746865206465706f7369742e00fc546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420616e64206265206120766f7465722e407375626d69745f63616e64696461637904013c63616e6469646174655f636f756e746502010c75333200023c11015375626d6974206f6e6573656c6620666f722063616e6469646163792e204120666978656420616d6f756e74206f66206465706f736974206973207265636f726465642e005d01416c6c2063616e64696461746573206172652077697065642061742074686520656e64206f6620746865207465726d2e205468657920656974686572206265636f6d652061206d656d6265722f72756e6e65722d75702ccc6f72206c65617665207468652073797374656d207768696c65207468656972206465706f73697420697320736c61736865642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e67005d014576656e20696620612063616e64696461746520656e6473207570206265696e672061206d656d6265722c2074686579206d7573742063616c6c205b6043616c6c3a3a72656e6f756e63655f63616e646964616379605d5901746f20676574207468656972206465706f736974206261636b2e204c6f73696e67207468652073706f7420696e20616e20656c656374696f6e2077696c6c20616c77617973206c65616420746f206120736c6173682e000901546865206e756d626572206f662063757272656e742063616e64696461746573206d7573742062652070726f7669646564206173207769746e65737320646174612e34232320436f6d706c6578697479a44f2843202b206c6f672843292920776865726520432069732063616e6469646174655f636f756e742e4872656e6f756e63655f63616e64696461637904012872656e6f756e63696e675103012852656e6f756e63696e670003504d0152656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c3c6f7574636f6d65732065786973743a0049012d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c20746865206465706f736974206973f02020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e61012d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c20746865206465706f73697420697320756e72657365727665642c2072657475726e656420616e648c20206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e55012d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c20746865206465706f73697420697320756e726573657276656420616e64206f726967696e2069735501202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e6101202053696d696c617220746f205b6072656d6f76655f6d656d626572605d2853656c663a3a72656d6f76655f6d656d626572292c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865795901202061726520696d6d6564696174656c7920757365642e20496620746865207072696d652069732072656e6f756e63696e672c207468656e206e6f207072696d652077696c6c20657869737420756e74696c207468653420206e65787420726f756e642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642c20616e642068617665206f6e65206f66207468652061626f766520726f6c65732ee05468652074797065206f662072656e6f756e63696e67206d7573742062652070726f7669646564206173207769746e65737320646174612e0034232320436f6d706c6578697479dc20202d2052656e6f756e63696e673a3a43616e64696461746528636f756e74293a204f28636f756e74202b206c6f6728636f756e7429297020202d2052656e6f756e63696e673a3a4d656d6265723a204f2831297820202d2052656e6f756e63696e673a3a52756e6e657255703a204f2831293472656d6f76655f6d656d6265720c010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000128736c6173685f626f6e64200110626f6f6c000138726572756e5f656c656374696f6e200110626f6f6c000440590152656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f667c746865206f7574676f696e67206d656d62657220697320736c61736865642e005501496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c616365732074686555016f7574676f696e67206d656d6265722e204f74686572776973652c2069662060726572756e5f656c656374696f6e60206973206074727565602c2061206e65772070687261676d656e20656c656374696f6e2069737c737461727465642c20656c73652c206e6f7468696e672068617070656e732e00590149662060736c6173685f626f6e64602069732073657420746f20747275652c2074686520626f6e64206f6620746865206d656d626572206265696e672072656d6f76656420697320736c61736865642e20456c73652c3c69742069732072657475726e65642e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0041014e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e0034232320436f6d706c657869747905012d20436865636b2064657461696c73206f662072656d6f76655f616e645f7265706c6163655f6d656d626572282920616e6420646f5f70687261676d656e28292e50636c65616e5f646566756e63745f766f746572730801286e756d5f766f7465727310010c75333200012c6e756d5f646566756e637410010c7533320005244501436c65616e20616c6c20766f746572732077686f2061726520646566756e63742028692e652e207468657920646f206e6f7420736572766520616e7920707572706f736520617420616c6c292e20546865ac6465706f736974206f66207468652072656d6f76656420766f74657273206172652072657475726e65642e0001015468697320697320616e20726f6f742066756e6374696f6e20746f2062652075736564206f6e6c7920666f7220636c65616e696e67207468652073746174652e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0034232320436f6d706c65786974798c2d20436865636b2069735f646566756e63745f766f74657228292064657461696c732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5103086470616c6c65745f656c656374696f6e735f70687261676d656e2852656e6f756e63696e6700010c184d656d6265720000002052756e6e657255700001002443616e64696461746504006502010c7533320002000055030c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c65741043616c6c0404540001143c7375626d69745f756e7369676e65640801307261775f736f6c7574696f6e590301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e00011c7769746e65737329040158536f6c7574696f6e4f72536e617073686f7453697a65000038a45375626d6974206120736f6c7574696f6e20666f722074686520756e7369676e65642070686173652e00c8546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f6e6f6e655f5f2e003d0154686973207375626d697373696f6e20697320636865636b6564206f6e2074686520666c792e204d6f72656f7665722c207468697320756e7369676e656420736f6c7574696f6e206973206f6e6c79550176616c696461746564207768656e207375626d697474656420746f2074686520706f6f6c2066726f6d20746865202a2a6c6f63616c2a2a206e6f64652e204566666563746976656c792c2074686973206d65616e735d0174686174206f6e6c79206163746976652076616c696461746f72732063616e207375626d69742074686973207472616e73616374696f6e207768656e20617574686f72696e67206120626c6f636b202873696d696c617240746f20616e20696e686572656e74292e005901546f2070726576656e7420616e7920696e636f727265637420736f6c7574696f6e2028616e642074687573207761737465642074696d652f776569676874292c2074686973207472616e73616374696f6e2077696c6c4d0170616e69632069662074686520736f6c7574696f6e207375626d6974746564206279207468652076616c696461746f7220697320696e76616c696420696e20616e79207761792c206566666563746976656c799c70757474696e6720746865697220617574686f72696e6720726577617264206174207269736b2e00e04e6f206465706f736974206f7220726577617264206973206173736f63696174656420776974682074686973207375626d697373696f6e2e6c7365745f6d696e696d756d5f756e747275737465645f73636f72650401406d617962655f6e6578745f73636f72652d0401544f7074696f6e3c456c656374696f6e53636f72653e000114b05365742061206e65772076616c756520666f7220604d696e696d756d556e7472757374656453636f7265602e00d84469737061746368206f726967696e206d75737420626520616c69676e656420776974682060543a3a466f7263654f726967696e602e00f05468697320636865636b2063616e206265207475726e6564206f66662062792073657474696e67207468652076616c756520746f20604e6f6e65602e747365745f656d657267656e63795f656c656374696f6e5f726573756c74040120737570706f72747331040158537570706f7274733c543a3a4163636f756e7449643e0002205901536574206120736f6c7574696f6e20696e207468652071756575652c20746f2062652068616e646564206f757420746f2074686520636c69656e74206f6620746869732070616c6c657420696e20746865206e6578748863616c6c20746f2060456c656374696f6e50726f76696465723a3a656c656374602e004501546869732063616e206f6e6c79206265207365742062792060543a3a466f7263654f726967696e602c20616e64206f6e6c79207768656e207468652070686173652069732060456d657267656e6379602e00610154686520736f6c7574696f6e206973206e6f7420636865636b656420666f7220616e7920666561736962696c69747920616e6420697320617373756d656420746f206265207472757374776f727468792c20617320616e795101666561736962696c69747920636865636b20697473656c662063616e20696e207072696e6369706c652063617573652074686520656c656374696f6e2070726f6365737320746f206661696c202864756520746f686d656d6f72792f77656967687420636f6e73747261696e73292e187375626d69740401307261775f736f6c7574696f6e590301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e0003249c5375626d6974206120736f6c7574696f6e20666f7220746865207369676e65642070686173652e00d0546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f7369676e65645f5f2e005d0154686520736f6c7574696f6e20697320706f74656e7469616c6c79207175657565642c206261736564206f6e2074686520636c61696d65642073636f726520616e642070726f6365737365642061742074686520656e64506f6620746865207369676e65642070686173652e005d0141206465706f73697420697320726573657276656420616e64207265636f7264656420666f722074686520736f6c7574696f6e2e204261736564206f6e20746865206f7574636f6d652c2074686520736f6c7574696f6e15016d696768742062652072657761726465642c20736c61736865642c206f722067657420616c6c206f7220612070617274206f6620746865206465706f736974206261636b2e4c676f7665726e616e63655f66616c6c6261636b0801406d617962655f6d61785f766f746572733903012c4f7074696f6e3c7533323e0001446d617962655f6d61785f746172676574733903012c4f7074696f6e3c7533323e00041080547269676765722074686520676f7665726e616e63652066616c6c6261636b2e004901546869732063616e206f6e6c792062652063616c6c6564207768656e205b6050686173653a3a456d657267656e6379605d20697320656e61626c65642c20617320616e20616c7465726e617469766520746fc063616c6c696e67205b6043616c6c3a3a7365745f656d657267656e63795f656c656374696f6e5f726573756c74605d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5903089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173652c526177536f6c7574696f6e040453015d03000c0120736f6c7574696f6e5d0301045300011473636f7265e00134456c656374696f6e53636f7265000114726f756e6410010c75333200005d03085874616e676c655f746573746e65745f72756e74696d65384e706f73536f6c7574696f6e31360000400118766f74657331610300000118766f746573326d0300000118766f74657333810300000118766f746573348d0300000118766f74657335990300000118766f74657336a50300000118766f74657337b10300000118766f74657338bd0300000118766f74657339c9030000011c766f7465733130d5030000011c766f7465733131e1030000011c766f7465733132ed030000011c766f7465733133f9030000011c766f746573313405040000011c766f746573313511040000011c766f74657331361d04000000610300000265030065030000040865026903006903000006e901006d0300000271030071030000040c65027503690300750300000408690379030079030000067d03007d030c3473705f61726974686d65746963287065725f7468696e67731850657255313600000400e901010c7531360000810300000285030085030000040c650289036903008903000003020000007503008d0300000291030091030000040c6502950369030095030000030300000075030099030000029d03009d030000040c6502a103690300a10300000304000000750300a503000002a90300a9030000040c6502ad03690300ad0300000305000000750300b103000002b50300b5030000040c6502b903690300b90300000306000000750300bd03000002c10300c1030000040c6502c503690300c50300000307000000750300c903000002cd0300cd030000040c6502d103690300d10300000308000000750300d503000002d90300d9030000040c6502dd03690300dd0300000309000000750300e103000002e50300e5030000040c6502e903690300e9030000030a000000750300ed03000002f10300f1030000040c6502f503690300f5030000030b000000750300f903000002fd0300fd030000040c6502010469030001040000030c000000750300050400000209040009040000040c65020d046903000d040000030d000000750300110400000215040015040000040c6502190469030019040000030e0000007503001d0400000221040021040000040c6502250469030025040000030f0000007503002904089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736558536f6c7574696f6e4f72536e617073686f7453697a650000080118766f746572736502010c75333200011c746172676574736502010c75333200002d0404184f7074696f6e04045401e00108104e6f6e6500000010536f6d650400e000000100003104000002350400350400000408003904003904084473705f6e706f735f656c656374696f6e731c537570706f727404244163636f756e744964010000080114746f74616c18013c457874656e64656442616c616e6365000118766f74657273d001845665633c284163636f756e7449642c20457874656e64656442616c616e6365293e00003d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c65741043616c6c04045400017810626f6e6408011476616c75656d01013042616c616e63654f663c543e0001147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000040610154616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c80626520746865206163636f756e74207468617420636f6e74726f6c732069742e002d016076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e002101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e003c456d6974732060426f6e646564602e34232320436f6d706c6578697479d02d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e1c2d204f2831292e642d20546872656520657874726120444220656e74726965732e004d014e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e65645901756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20286f7220657175616c20746f20302920616e6420676574732072656d6f76656420617320647573742e28626f6e645f65787472610401386d61785f6164646974696f6e616c6d01013042616c616e63654f663c543e000138610141646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757030666f72207374616b696e672e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e004d01557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e5501556e6c696b65205b60626f6e64605d2853656c663a3a626f6e6429206f72205b60756e626f6e64605d2853656c663a3a756e626f6e642920746869732066756e6374696f6e20646f6573206e6f7420696d706f7365bc616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e003c456d6974732060426f6e646564602e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e1c2d204f2831292e18756e626f6e6404011476616c75656d01013042616c616e63654f663c543e00024c51015363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e64fc706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e2101543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0045014f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665bc7468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e0031014e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d6178556e6c6f636b696e674368756e6b736029410163616e20636f2d657869737473206174207468652073616d652074696d652e20496620746865726520617265206e6f20756e6c6f636b696e67206368756e6b7320736c6f747320617661696c61626c6545015b6043616c6c3a3a77697468647261775f756e626f6e646564605d2069732063616c6c656420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e00390149662061207573657220656e636f756e74657273207468652060496e73756666696369656e74426f6e6460206572726f72207768656e2063616c6c696e6720746869732065787472696e7369632c1901746865792073686f756c642063616c6c20606368696c6c6020666972737420696e206f7264657220746f206672656520757020746865697220626f6e6465642066756e64732e0044456d6974732060556e626f6e646564602e009453656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e4477697468647261775f756e626f6e6465640401486e756d5f736c617368696e675f7370616e7310010c75333200035c290152656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e0055015468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722469742077616e74732e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722e0048456d697473206057697468647261776e602e006853656520616c736f205b6043616c6c3a3a756e626f6e64605d2e0034232320506172616d65746572730051012d20606e756d5f736c617368696e675f7370616e736020696e6469636174657320746865206e756d626572206f66206d6574616461746120736c617368696e67207370616e7320746f20636c656172207768656e5501746869732063616c6c20726573756c747320696e206120636f6d706c6574652072656d6f76616c206f6620616c6c2074686520646174612072656c6174656420746f20746865207374617368206163636f756e742e3d01496e207468697320636173652c2074686520606e756d5f736c617368696e675f7370616e7360206d757374206265206c6172676572206f7220657175616c20746f20746865206e756d626572206f665d01736c617368696e67207370616e73206173736f636961746564207769746820746865207374617368206163636f756e7420696e20746865205b60536c617368696e675370616e73605d2073746f7261676520747970652c25016f7468657277697365207468652063616c6c2077696c6c206661696c2e205468652063616c6c20776569676874206973206469726563746c792070726f706f7274696f6e616c20746f54606e756d5f736c617368696e675f7370616e73602e0034232320436f6d706c6578697479d84f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f766509014e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e2076616c69646174650401147072656673f8013856616c696461746f725072656673000414e44465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e206e6f6d696e61746504011c74617267657473410401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e0005280d014465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c65786974792d012d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e29050177686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542028543a3a4d61784e6f6d696e6174696f6e73292ed42d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e146368696c6c000628c44465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e502d20436f6e7461696e73206f6e6520726561642ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e247365745f70617965650401147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000730b42852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479182d204f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e242d2d2d2d2d2d2d2d2d387365745f636f6e74726f6c6c657200083845012852652d29736574732074686520636f6e74726f6c6c6572206f66206120737461736820746f2074686520737461736820697473656c662e20546869732066756e6374696f6e2070726576696f75736c794d01616363657074656420612060636f6e74726f6c6c65726020617267756d656e7420746f207365742074686520636f6e74726f6c6c657220746f20616e206163636f756e74206f74686572207468616e207468655901737461736820697473656c662e20546869732066756e6374696f6e616c69747920686173206e6f77206265656e2072656d6f7665642c206e6f77206f6e6c792073657474696e672074686520636f6e74726f6c6c65728c746f207468652073746173682c206966206974206973206e6f7420616c72656164792e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479104f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e4c7365745f76616c696461746f725f636f756e7404010c6e65776502010c75333200091890536574732074686520696465616c206e756d626572206f662076616c696461746f72732e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c6578697479104f28312960696e6372656173655f76616c696461746f725f636f756e740401286164646974696f6e616c6502010c753332000a1ce8496e6372656d656e74732074686520696465616c206e756d626572206f662076616c696461746f727320757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e547363616c655f76616c696461746f725f636f756e74040118666163746f72f501011c50657263656e74000b1c11015363616c652075702074686520696465616c206e756d626572206f662076616c696461746f7273206279206120666163746f7220757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e34666f7263655f6e6f5f65726173000c34ac466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e3901546875732074686520656c656374696f6e2070726f63657373206d6179206265206f6e676f696e67207768656e20746869732069732063616c6c65642e20496e2074686973206361736520746865dc656c656374696f6e2077696c6c20636f6e74696e756520756e74696c20746865206e65787420657261206973207472696767657265642e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f28312934666f7263655f6e65775f657261000d384901466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c2062659c726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f283129447365745f696e76756c6e657261626c6573040134696e76756c6e657261626c65733d0201445665633c543a3a4163636f756e7449643e000e0cc8536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e34666f7263655f756e7374616b650801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c753332000f200901466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e50666f7263655f6e65775f6572615f616c776179730010240101466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e5463616e63656c5f64656665727265645f736c61736808010c657261100120457261496e646578000134736c6173685f696e6469636573450401205665633c7533323e0011149443616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e009843616e2062652063616c6c6564206279207468652060543a3a41646d696e4f726967696e602e000101506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e387061796f75745f7374616b65727308013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780012341901506179206f7574206e6578742070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e206572612e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e00490154686520726577617264207061796f757420636f756c6420626520706167656420696e20636173652074686572652061726520746f6f206d616e79206e6f6d696e61746f7273206261636b696e67207468655d016076616c696461746f725f7374617368602e20546869732063616c6c2077696c6c207061796f757420756e7061696420706167657320696e20616e20617363656e64696e67206f726465722e20546f20636c61696d2061b4737065636966696320706167652c2075736520607061796f75745f7374616b6572735f62795f70616765602e6000f0496620616c6c2070616765732061726520636c61696d65642c2069742072657475726e7320616e206572726f722060496e76616c696450616765602e187265626f6e6404011476616c75656d01013042616c616e63654f663c543e00131cdc5265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e00d4546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479d02d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73882d20426f756e64656420627920604d6178556e6c6f636b696e674368756e6b73602e28726561705f73746173680801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c7533320014485d0152656d6f766520616c6c2064617461207374727563747572657320636f6e6365726e696e672061207374616b65722f7374617368206f6e636520697420697320617420612073746174652077686572652069742063616e0501626520636f6e736964657265642060647573746020696e20746865207374616b696e672073797374656d2e2054686520726571756972656d656e7473206172653a000501312e207468652060746f74616c5f62616c616e636560206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e1101322e206f722c2074686520606c65646765722e746f74616c60206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e6101332e206f722c206578697374656e7469616c206465706f736974206973207a65726f20616e64206569746865722060746f74616c5f62616c616e636560206f7220606c65646765722e746f74616c60206973207a65726f2e00550154686520666f726d65722063616e2068617070656e20696e206361736573206c696b65206120736c6173683b20746865206c6174746572207768656e20612066756c6c7920756e626f6e646564206163636f756e7409016973207374696c6c20726563656976696e67207374616b696e67207265776172647320696e206052657761726444657374696e6174696f6e3a3a5374616b6564602e00310149742063616e2062652063616c6c656420627920616e796f6e652c206173206c6f6e672061732060737461736860206d65657473207468652061626f766520726571756972656d656e74732e00dc526566756e647320746865207472616e73616374696f6e20666565732075706f6e207375636365737366756c20657865637574696f6e2e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e106b69636b04010c77686f410401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e00152ce052656d6f76652074686520676976656e206e6f6d696e6174696f6e732066726f6d207468652063616c6c696e672076616c696461746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e004d012d206077686f603a2041206c697374206f66206e6f6d696e61746f72207374617368206163636f756e74732077686f20617265206e6f6d696e6174696e6720746869732076616c696461746f72207768696368c0202073686f756c64206e6f206c6f6e676572206265206e6f6d696e6174696e6720746869732076616c696461746f722e0055014e6f74653a204d616b696e6720746869732063616c6c206f6e6c79206d616b65732073656e736520696620796f7520666972737420736574207468652076616c696461746f7220707265666572656e63657320746f78626c6f636b20616e792066757274686572206e6f6d696e6174696f6e732e4c7365745f7374616b696e675f636f6e666967731c01486d696e5f6e6f6d696e61746f725f626f6e6449040158436f6e6669674f703c42616c616e63654f663c543e3e0001486d696e5f76616c696461746f725f626f6e6449040158436f6e6669674f703c42616c616e63654f663c543e3e00014c6d61785f6e6f6d696e61746f725f636f756e744d040134436f6e6669674f703c7533323e00014c6d61785f76616c696461746f725f636f756e744d040134436f6e6669674f703c7533323e00013c6368696c6c5f7468726573686f6c6451040144436f6e6669674f703c50657263656e743e0001386d696e5f636f6d6d697373696f6e55040144436f6e6669674f703c50657262696c6c3e0001486d61785f7374616b65645f7265776172647351040144436f6e6669674f703c50657263656e743e001644ac5570646174652074686520766172696f7573207374616b696e6720636f6e66696775726174696f6e73202e0025012a20606d696e5f6e6f6d696e61746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f2062652061206e6f6d696e61746f722e25012a20606d696e5f76616c696461746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f20626520612076616c696461746f722e55012a20606d61785f6e6f6d696e61746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e2062652061206e6f6d696e61746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e55012a20606d61785f76616c696461746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e20626520612076616c696461746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e59012a20606368696c6c5f7468726573686f6c64603a2054686520726174696f206f6620606d61785f6e6f6d696e61746f725f636f756e7460206f7220606d61785f76616c696461746f725f636f756e74602077686963681901202073686f756c642062652066696c6c656420696e206f7264657220666f722074686520606368696c6c5f6f7468657260207472616e73616374696f6e20746f20776f726b2e61012a20606d696e5f636f6d6d697373696f6e603a20546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e550120205468697320697320636865636b6564206f6e6c792075706f6e2063616c6c696e67206076616c6964617465602e204578697374696e672076616c696461746f727320617265206e6f742061666665637465642e00c452756e74696d654f726967696e206d75737420626520526f6f7420746f2063616c6c20746869732066756e6374696f6e2e0035014e4f54453a204578697374696e67206e6f6d696e61746f727320616e642076616c696461746f72732077696c6c206e6f742062652061666665637465642062792074686973207570646174652e1101746f206b69636b2070656f706c6520756e64657220746865206e6577206c696d6974732c20606368696c6c5f6f74686572602073686f756c642062652063616c6c65642e2c6368696c6c5f6f746865720401147374617368000130543a3a4163636f756e74496400176841014465636c61726520612060636f6e74726f6c6c65726020746f2073746f702070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e004101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2c206275742063616e2062652063616c6c656420627920616e796f6e652e0059014966207468652063616c6c6572206973207468652073616d652061732074686520636f6e74726f6c6c6572206265696e672074617267657465642c207468656e206e6f206675727468657220636865636b7320617265d8656e666f726365642c20616e6420746869732066756e6374696f6e2062656861766573206a757374206c696b6520606368696c6c602e005d014966207468652063616c6c657220697320646966666572656e74207468616e2074686520636f6e74726f6c6c6572206265696e672074617267657465642c2074686520666f6c6c6f77696e6720636f6e646974696f6e73306d757374206265206d65743a001d012a2060636f6e74726f6c6c657260206d7573742062656c6f6e6720746f2061206e6f6d696e61746f722077686f20686173206265636f6d65206e6f6e2d6465636f6461626c652c000c4f723a003d012a204120604368696c6c5468726573686f6c6460206d7573742062652073657420616e6420636865636b656420776869636820646566696e657320686f7720636c6f736520746f20746865206d6178550120206e6f6d696e61746f7273206f722076616c696461746f7273207765206d757374207265616368206265666f72652075736572732063616e207374617274206368696c6c696e67206f6e652d616e6f746865722e59012a204120604d61784e6f6d696e61746f72436f756e746020616e6420604d617856616c696461746f72436f756e7460206d75737420626520736574207768696368206973207573656420746f2064657465726d696e65902020686f7720636c6f73652077652061726520746f20746865207468726573686f6c642e5d012a204120604d696e4e6f6d696e61746f72426f6e646020616e6420604d696e56616c696461746f72426f6e6460206d7573742062652073657420616e6420636865636b65642c2077686963682064657465726d696e65735101202069662074686973206973206120706572736f6e20746861742073686f756c64206265206368696c6c6564206265636175736520746865792068617665206e6f74206d657420746865207468726573686f6c64402020626f6e642072657175697265642e005501546869732063616e2062652068656c7066756c20696620626f6e6420726571756972656d656e74732061726520757064617465642c20616e64207765206e65656420746f2072656d6f7665206f6c642075736572739877686f20646f206e6f74207361746973667920746865736520726571756972656d656e74732e68666f7263655f6170706c795f6d696e5f636f6d6d697373696f6e04013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400180c4501466f72636520612076616c696461746f7220746f2068617665206174206c6561737420746865206d696e696d756d20636f6d6d697373696f6e2e20546869732077696c6c206e6f74206166666563742061610176616c696461746f722077686f20616c726561647920686173206120636f6d6d697373696f6e2067726561746572207468616e206f7220657175616c20746f20746865206d696e696d756d2e20416e79206163636f756e743863616e2063616c6c20746869732e487365745f6d696e5f636f6d6d697373696f6e04010c6e6577f4011c50657262696c6c00191025015365747320746865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e005901546869732063616c6c20686173206c6f7765722070726976696c65676520726571756972656d656e7473207468616e20607365745f7374616b696e675f636f6e6669676020616e642063616e2062652063616c6c6564cc6279207468652060543a3a41646d696e4f726967696e602e20526f6f742063616e20616c776179732063616c6c20746869732e587061796f75745f7374616b6572735f62795f706167650c013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780001107061676510011050616765001a443101506179206f757420612070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e2065726120616e6420706167652e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e31012d2060706167656020697320746865207061676520696e646578206f66206e6f6d696e61746f727320746f20706179206f757420776974682076616c7565206265747765656e203020616e64b02020606e756d5f6e6f6d696e61746f7273202f20543a3a4d61784578706f737572655061676553697a65602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e003d01496620612076616c696461746f7220686173206d6f7265207468616e205b60436f6e6669673a3a4d61784578706f737572655061676553697a65605d206e6f6d696e61746f7273206261636b696e6729017468656d2c207468656e20746865206c697374206f66206e6f6d696e61746f72732069732070616765642c207769746820656163682070616765206265696e672063617070656420617455015b60436f6e6669673a3a4d61784578706f737572655061676553697a65602e5d20496620612076616c696461746f7220686173206d6f7265207468616e206f6e652070616765206f66206e6f6d696e61746f72732c49017468652063616c6c206e6565647320746f206265206d61646520666f72206561636820706167652073657061726174656c7920696e206f7264657220666f7220616c6c20746865206e6f6d696e61746f727355016261636b696e6720612076616c696461746f7220746f207265636569766520746865207265776172642e20546865206e6f6d696e61746f727320617265206e6f7420736f72746564206163726f73732070616765736101616e6420736f2069742073686f756c64206e6f7420626520617373756d6564207468652068696768657374207374616b657220776f756c64206265206f6e2074686520746f706d6f7374207061676520616e642076696365490176657273612e204966207265776172647320617265206e6f7420636c61696d656420696e205b60436f6e6669673a3a486973746f72794465707468605d20657261732c207468657920617265206c6f73742e307570646174655f7061796565040128636f6e74726f6c6c6572000130543a3a4163636f756e744964001b18e04d6967726174657320616e206163636f756e742773206052657761726444657374696e6174696f6e3a3a436f6e74726f6c6c65726020746fa46052657761726444657374696e6174696f6e3a3a4163636f756e7428636f6e74726f6c6c657229602e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e003101546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966207468652060706179656560206973207375636365737366756c6c79206d696772617465642e686465707265636174655f636f6e74726f6c6c65725f626174636804012c636f6e74726f6c6c657273590401f4426f756e6465645665633c543a3a4163636f756e7449642c20543a3a4d6178436f6e74726f6c6c657273496e4465707265636174696f6e42617463683e001c1c5d01557064617465732061206261746368206f6620636f6e74726f6c6c6572206163636f756e747320746f20746865697220636f72726573706f6e64696e67207374617368206163636f756e7420696620746865792061726561016e6f74207468652073616d652e2049676e6f72657320616e7920636f6e74726f6c6c6572206163636f756e7473207468617420646f206e6f742065786973742c20616e6420646f6573206e6f74206f706572617465206966b874686520737461736820616e6420636f6e74726f6c6c65722061726520616c7265616479207468652073616d652e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e00b4546865206469737061746368206f726967696e206d7573742062652060543a3a41646d696e4f726967696e602e38726573746f72655f6c65646765721001147374617368000130543a3a4163636f756e7449640001406d617962655f636f6e74726f6c6c65728801504f7074696f6e3c543a3a4163636f756e7449643e00012c6d617962655f746f74616c5d0401504f7074696f6e3c42616c616e63654f663c543e3e00013c6d617962655f756e6c6f636b696e6761040115014f7074696f6e3c426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a0a4d6178556e6c6f636b696e674368756e6b733e3e001d2c0501526573746f72657320746865207374617465206f662061206c656467657220776869636820697320696e20616e20696e636f6e73697374656e742073746174652e00dc54686520726571756972656d656e747320746f20726573746f72652061206c6564676572206172652074686520666f6c6c6f77696e673a642a2054686520737461736820697320626f6e6465643b206f720d012a20546865207374617368206973206e6f7420626f6e64656420627574206974206861732061207374616b696e67206c6f636b206c65667420626568696e643b206f7225012a204966207468652073746173682068617320616e206173736f636961746564206c656467657220616e642069747320737461746520697320696e636f6e73697374656e743b206f721d012a20496620746865206c6564676572206973206e6f7420636f72727570746564202a6275742a20697473207374616b696e67206c6f636b206973206f7574206f662073796e632e00610154686520606d617962655f2a6020696e70757420706172616d65746572732077696c6c206f76657277726974652074686520636f72726573706f6e64696e67206461746120616e64206d65746164617461206f662074686559016c6564676572206173736f6369617465642077697468207468652073746173682e2049662074686520696e70757420706172616d657465727320617265206e6f74207365742c20746865206c65646765722077696c6c9062652072657365742076616c7565732066726f6d206f6e2d636861696e2073746174652e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e4104000002c10200450400000210004904103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200004d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200005104103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f501010c104e6f6f700000000c5365740400f5010104540001001852656d6f7665000200005504103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000059040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e00005d0404184f7074696f6e04045401180108104e6f6e6500000010536f6d650400180000010000610404184f7074696f6e0404540165040108104e6f6e6500000010536f6d6504006504000001000065040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540169040453000004006d0401185665633c543e00006904083870616c6c65745f7374616b696e672c556e6c6f636b4368756e6b041c42616c616e636501180008011476616c75656d01011c42616c616e636500010c65726165020120457261496e64657800006d0400000269040071040c3870616c6c65745f73657373696f6e1870616c6c65741043616c6c040454000108207365745f6b6579730801106b6579737504011c543a3a4b65797300011470726f6f6638011c5665633c75383e000024e453657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e1d01416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722ec05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e00d0546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e0034232320436f6d706c657869747959012d20604f283129602e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f69647328296020776869636820697320202066697865642e2870757267655f6b657973000130c852656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e00c05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e005501546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265205369676e656420616e6420746865206163636f756e74206d757374206265206569746865722062655d01636f6e7665727469626c6520746f20612076616c696461746f72204944207573696e672074686520636861696e2773207479706963616c2061646472657373696e672073797374656d20287468697320757375616c6c7951016d65616e73206265696e67206120636f6e74726f6c6c6572206163636f756e7429206f72206469726563746c7920636f6e7665727469626c6520696e746f20612076616c696461746f722049442028776869636894757375616c6c79206d65616e73206265696e672061207374617368206163636f756e74292e0034232320436f6d706c65786974793d012d20604f2831296020696e206e756d626572206f66206b65792074797065732e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f6698202060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e75040c5874616e676c655f746573746e65745f72756e74696d65186f70617175652c53657373696f6e4b65797300000c011062616265d90201c43c42616265206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c696300011c6772616e647061a801d03c4772616e647061206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000124696d5f6f6e6c696e655d0101d43c496d4f6e6c696e65206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000079040c3c70616c6c65745f74726561737572791870616c6c65741043616c6c0804540004490001182c7370656e645f6c6f63616c080118616d6f756e746d01013c42616c616e63654f663c542c20493e00012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000344b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e0045014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c656173742060616d6f756e74602e002c2323232044657461696c7345014e4f54453a20466f72207265636f72642d6b656570696e6720707572706f7365732c207468652070726f706f736572206973206465656d656420746f206265206571756976616c656e7420746f207468653062656e65666963696172792e003823232320506172616d657465727341012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602ee82d206062656e6566696369617279603a205468652064657374696e6174696f6e206163636f756e7420666f7220746865207472616e736665722e00242323204576656e747300b4456d697473205b604576656e743a3a5370656e64417070726f766564605d206966207375636365737366756c2e3c72656d6f76655f617070726f76616c04012c70726f706f73616c5f69646502013450726f706f73616c496e6465780004542d01466f72636520612070726576696f75736c7920617070726f7665642070726f706f73616c20746f2062652072656d6f7665642066726f6d2074686520617070726f76616c2071756575652e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c7300c0546865206f726967696e616c206465706f7369742077696c6c206e6f206c6f6e6765722062652072657475726e65642e003823232320506172616d6574657273a02d206070726f706f73616c5f6964603a2054686520696e646578206f6620612070726f706f73616c003823232320436f6d706c6578697479ac2d204f2841292077686572652060416020697320746865206e756d626572206f6620617070726f76616c730028232323204572726f727345012d205b604572726f723a3a50726f706f73616c4e6f74417070726f766564605d3a20546865206070726f706f73616c5f69646020737570706c69656420776173206e6f7420666f756e6420696e2074686551012020617070726f76616c2071756575652c20692e652e2c207468652070726f706f73616c20686173206e6f74206265656e20617070726f7665642e205468697320636f756c6420616c736f206d65616e207468655901202070726f706f73616c20646f6573206e6f7420657869737420616c746f6765746865722c2074687573207468657265206973206e6f2077617920697420776f756c642068617665206265656e20617070726f766564542020696e2074686520666972737420706c6163652e147370656e6410012861737365745f6b696e64840144426f783c543a3a41737365744b696e643e000118616d6f756e746d010150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000178426f783c42656e65666963696172794c6f6f6b75704f663c542c20493e3e00012876616c69645f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000568b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e001d014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c65617374550160616d6f756e7460206f66206061737365745f6b696e646020696e20746865206e61746976652061737365742e2054686520616d6f756e74206f66206061737365745f6b696e646020697320636f6e766572746564d4666f7220617373657274696f6e207573696e6720746865205b60436f6e6669673a3a42616c616e6365436f6e766572746572605d2e002823232044657461696c7300490143726561746520616e20617070726f766564207370656e6420666f72207472616e7366657272696e6720612073706563696669632060616d6f756e7460206f66206061737365745f6b696e646020746f2061610164657369676e617465642062656e65666963696172792e20546865207370656e64206d75737420626520636c61696d6564207573696e672074686520607061796f75746020646973706174636861626c652077697468696e74746865205b60436f6e6669673a3a5061796f7574506572696f64605d2e003823232320506172616d657465727315012d206061737365745f6b696e64603a20416e20696e64696361746f72206f662074686520737065636966696320617373657420636c61737320746f206265207370656e742e41012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602eb82d206062656e6566696369617279603a205468652062656e6566696369617279206f6620746865207370656e642e55012d206076616c69645f66726f6d603a2054686520626c6f636b206e756d6265722066726f6d20776869636820746865207370656e642063616e20626520636c61696d65642e2049742063616e20726566657220746f1901202074686520706173742069662074686520726573756c74696e67207370656e6420686173206e6f74207965742065787069726564206163636f7264696e6720746f20746865450120205b60436f6e6669673a3a5061796f7574506572696f64605d2e20496620604e6f6e65602c20746865207370656e642063616e20626520636c61696d656420696d6d6564696174656c792061667465722c2020617070726f76616c2e00242323204576656e747300c8456d697473205b604576656e743a3a41737365745370656e64417070726f766564605d206966207375636365737366756c2e187061796f7574040114696e6465781001285370656e64496e64657800064c38436c61696d2061207370656e642e00482323204469737061746368204f726967696e00384d757374206265207369676e6564002823232044657461696c730055015370656e6473206d75737420626520636c61696d65642077697468696e20736f6d652074656d706f72616c20626f756e64732e2041207370656e64206d617920626520636c61696d65642077697468696e206f6e65d45b60436f6e6669673a3a5061796f7574506572696f64605d2066726f6d20746865206076616c69645f66726f6d6020626c6f636b2e5501496e2063617365206f662061207061796f7574206661696c7572652c20746865207370656e6420737461747573206d75737420626520757064617465642077697468207468652060636865636b5f73746174757360dc646973706174636861626c65206265666f7265207265747279696e672077697468207468652063757272656e742066756e6374696f6e2e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e74730090456d697473205b604576656e743a3a50616964605d206966207375636365737366756c2e30636865636b5f737461747573040114696e6465781001285370656e64496e64657800074c2901436865636b2074686520737461747573206f6620746865207370656e6420616e642072656d6f76652069742066726f6d207468652073746f726167652069662070726f6365737365642e00482323204469737061746368204f726967696e003c4d757374206265207369676e65642e002823232044657461696c730001015468652073746174757320636865636b20697320612070726572657175697369746520666f72207265747279696e672061206661696c6564207061796f75742e490149662061207370656e64206861732065697468657220737563636565646564206f7220657870697265642c2069742069732072656d6f7665642066726f6d207468652073746f726167652062792074686973ec66756e6374696f6e2e20496e207375636820696e7374616e6365732c207472616e73616374696f6e20666565732061726520726566756e6465642e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300f8456d697473205b604576656e743a3a5061796d656e744661696c6564605d20696620746865207370656e64207061796f757420686173206661696c65642e0101456d697473205b604576656e743a3a5370656e6450726f636573736564605d20696620746865207370656e64207061796f75742068617320737563636565642e28766f69645f7370656e64040114696e6465781001285370656e64496e6465780008407c566f69642070726576696f75736c7920617070726f766564207370656e642e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c73001d0141207370656e6420766f6964206973206f6e6c7920706f737369626c6520696620746865207061796f757420686173206e6f74206265656e20617474656d70746564207965742e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300c0456d697473205b604576656e743a3a41737365745370656e64566f69646564605d206966207375636365737366756c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e7d0404184f7074696f6e04045401300108104e6f6e6500000010536f6d65040030000001000081040c3c70616c6c65745f626f756e746965731870616c6c65741043616c6c0804540004490001243870726f706f73655f626f756e747908011476616c75656d01013c42616c616e63654f663c542c20493e00012c6465736372697074696f6e38011c5665633c75383e0000305450726f706f73652061206e657720626f756e74792e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051015061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c206173510160446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e2049742077696c6c20626520756e72657365727665642075706f6e20617070726f76616c2c646f7220736c6173686564207768656e2072656a65637465642e00f82d206063757261746f72603a205468652063757261746f72206163636f756e742077686f6d2077696c6c206d616e616765207468697320626f756e74792e642d2060666565603a205468652063757261746f72206665652e25012d206076616c7565603a2054686520746f74616c207061796d656e7420616d6f756e74206f66207468697320626f756e74792c2063757261746f722066656520696e636c756465642ec02d20606465736372697074696f6e603a20546865206465736372697074696f6e206f66207468697320626f756e74792e38617070726f76655f626f756e7479040124626f756e74795f69646502012c426f756e7479496e64657800011c5d01417070726f7665206120626f756e74792070726f706f73616c2e2041742061206c617465722074696d652c2074686520626f756e74792077696c6c2062652066756e64656420616e64206265636f6d6520616374697665a8616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e3c70726f706f73655f63757261746f720c0124626f756e74795f69646502012c426f756e7479496e64657800011c63757261746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013c42616c616e63654f663c542c20493e0002189450726f706f736520612063757261746f7220746f20612066756e64656420626f756e74792e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e40756e61737369676e5f63757261746f72040124626f756e74795f69646502012c426f756e7479496e6465780003447c556e61737369676e2063757261746f722066726f6d206120626f756e74792e001d01546869732066756e6374696f6e2063616e206f6e6c792062652063616c6c656420627920746865206052656a6563744f726967696e602061207369676e6564206f726967696e2e003d01496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e602c20776520617373756d652074686174207468652063757261746f7220697331016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c2077652077696c6c20736c617368207468652063757261746f72207768656e20706f737369626c652e006101496620746865206f726967696e206973207468652063757261746f722c2077652074616b6520746869732061732061207369676e20746865792061726520756e61626c6520746f20646f207468656972206a6f6220616e645d01746865792077696c6c696e676c7920676976652075702e20576520636f756c6420736c617368207468656d2c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f207265636f76657220746865697235016465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966206974206973206162757365642e29005d0146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e6520696620616e64206f6e6c79206966207468652063757261746f722069732022696e616374697665222e205468697320616c6c6f77736101616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f7574207468617420612063757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e64390177652073686f756c64207069636b2061206e65772063757261746f722e20496e20746869732063617365207468652063757261746f722073686f756c6420616c736f20626520736c61736865642e0034232320436f6d706c65786974791c2d204f2831292e386163636570745f63757261746f72040124626f756e74795f69646502012c426f756e7479496e64657800041c94416363657074207468652063757261746f7220726f6c6520666f72206120626f756e74792e290141206465706f7369742077696c6c2062652072657365727665642066726f6d2063757261746f7220616e6420726566756e642075706f6e207375636365737366756c207061796f75742e00904d6179206f6e6c792062652063616c6c65642066726f6d207468652063757261746f722e0034232320436f6d706c65786974791c2d204f2831292e3061776172645f626f756e7479080124626f756e74795f69646502012c426f756e7479496e64657800012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e0005285901417761726420626f756e747920746f20612062656e6566696369617279206163636f756e742e205468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647338616674657220612064656c61792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f2061776172642e19012d206062656e6566696369617279603a205468652062656e6566696369617279206163636f756e742077686f6d2077696c6c207265636569766520746865207061796f75742e0034232320436f6d706c65786974791c2d204f2831292e30636c61696d5f626f756e7479040124626f756e74795f69646502012c426f756e7479496e646578000620ec436c61696d20746865207061796f75742066726f6d20616e206177617264656420626f756e7479206166746572207061796f75742064656c61792e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652062656e6566696369617279206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f20636c61696d2e0034232320436f6d706c65786974791c2d204f2831292e30636c6f73655f626f756e7479040124626f756e74795f69646502012c426f756e7479496e646578000724390143616e63656c20612070726f706f736564206f722061637469766520626f756e74792e20416c6c207468652066756e64732077696c6c2062652073656e7420746f20747265617375727920616e64cc7468652063757261746f72206465706f7369742077696c6c20626520756e726573657276656420696620706f737369626c652e00c84f6e6c792060543a3a52656a6563744f726967696e602069732061626c6520746f2063616e63656c206120626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f2063616e63656c2e0034232320436f6d706c65786974791c2d204f2831292e50657874656e645f626f756e74795f657870697279080124626f756e74795f69646502012c426f756e7479496e64657800011872656d61726b38011c5665633c75383e000824ac457874656e6420746865206578706972792074696d65206f6620616e2061637469766520626f756e74792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f20657874656e642e8c2d206072656d61726b603a206164646974696f6e616c20696e666f726d6174696f6e2e0034232320436f6d706c65786974791c2d204f2831292e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e85040c5470616c6c65745f6368696c645f626f756e746965731870616c6c65741043616c6c04045400011c406164645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800011476616c75656d01013042616c616e63654f663c543e00012c6465736372697074696f6e38011c5665633c75383e00004c5c4164642061206e6577206368696c642d626f756e74792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f6620706172656e74dc626f756e747920616e642074686520706172656e7420626f756e7479206d75737420626520696e2022616374697665222073746174652e0005014368696c642d626f756e74792067657473206164646564207375636365737366756c6c7920262066756e642067657473207472616e736665727265642066726f6d0901706172656e7420626f756e747920746f206368696c642d626f756e7479206163636f756e742c20696620706172656e7420626f756e74792068617320656e6f7567686c66756e64732c20656c7365207468652063616c6c206661696c732e000d01557070657220626f756e6420746f206d6178696d756d206e756d626572206f662061637469766520206368696c6420626f756e7469657320746861742063616e206265a8616464656420617265206d616e61676564207669612072756e74696d6520747261697420636f6e666967985b60436f6e6669673a3a4d61784163746976654368696c64426f756e7479436f756e74605d2e0001014966207468652063616c6c20697320737563636573732c2074686520737461747573206f66206368696c642d626f756e7479206973207570646174656420746f20224164646564222e004d012d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e747920666f72207768696368206368696c642d626f756e7479206973206265696e672061646465642eb02d206076616c7565603a2056616c756520666f7220657865637574696e67207468652070726f706f73616c2edc2d20606465736372697074696f6e603a2054657874206465736372697074696f6e20666f7220746865206368696c642d626f756e74792e3c70726f706f73655f63757261746f72100140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800011c63757261746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013042616c616e63654f663c543e00013ca050726f706f73652063757261746f7220666f722066756e646564206368696c642d626f756e74792e000d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652063757261746f72206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e20224164646564222073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6405017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202243757261746f7250726f706f73656422206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792eb42d206063757261746f72603a2041646472657373206f66206368696c642d626f756e74792063757261746f722eec2d2060666565603a207061796d656e742066656520746f206368696c642d626f756e74792063757261746f7220666f7220657865637574696f6e2e386163636570745f63757261746f72080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800024cb4416363657074207468652063757261746f7220726f6c6520666f7220746865206368696c642d626f756e74792e00f4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f662074686973346368696c642d626f756e74792e00ec41206465706f7369742077696c6c2062652072657365727665642066726f6d207468652063757261746f7220616e6420726566756e642075706f6e887375636365737366756c207061796f7574206f722063616e63656c6c6174696f6e2e00f846656520666f722063757261746f722069732064656475637465642066726f6d2063757261746f7220666565206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e202243757261746f7250726f706f736564222073746174652c20666f722070726f63657373696e6720746865090163616c6c2e20416e64207374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202241637469766522206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e40756e61737369676e5f63757261746f72080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800038894556e61737369676e2063757261746f722066726f6d2061206368696c642d626f756e74792e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c2063616e20626520656974686572206052656a6563744f726967696e602c206f72dc7468652063757261746f72206f662074686520706172656e7420626f756e74792c206f7220616e79207369676e6564206f726967696e2e00f8466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e20616e6420746865206368696c642d626f756e7479010163757261746f722c20706172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f7220746869732063616c6c20746f0901776f726b2e20576520616c6c6f77206368696c642d626f756e74792063757261746f7220616e6420543a3a52656a6563744f726967696e20746f2065786563757465c8746869732063616c6c20697272657370656374697665206f662074686520706172656e7420626f756e74792073746174652e00dc496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e60206f72207468650501706172656e7420626f756e74792063757261746f722c20776520617373756d65207468617420746865206368696c642d626f756e74792063757261746f722069730d016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e000501496620746865206f726967696e20697320746865206368696c642d626f756e74792063757261746f722c2077652074616b6520746869732061732061207369676e09017468617420746865792061726520756e61626c6520746f20646f207468656972206a6f622c20616e64206172652077696c6c696e676c7920676976696e672075702e0901576520636f756c6420736c61736820746865206465706f7369742c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f20756e7265736572766511017468656972206465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966386974206973206162757365642e2900050146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e652069666620746865206368696c642d626f756e74792063757261746f72206973090122696e616374697665222e204578706972792075706461746520647565206f6620706172656e7420626f756e7479206973207573656420746f20657374696d6174659c696e616374697665207374617465206f66206368696c642d626f756e74792063757261746f722e000d015468697320616c6c6f777320616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f757420746861742061206368696c642d626f756e7479090163757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e642077652073686f756c64207069636b2061206e6577f86f6e652e20496e2074686973206361736520746865206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e0001015374617465206f66206368696c642d626f756e7479206973206d6f76656420746f204164646564207374617465206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e4861776172645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e64657800012c62656e6566696369617279c10201504163636f756e7449644c6f6f6b75704f663c543e000444904177617264206368696c642d626f756e747920746f20612062656e65666963696172792e00f85468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647320616674657220612064656c61792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652074686520706172656e742063757261746f72206f727463757261746f72206f662074686973206368696c642d626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e0009014368696c642d626f756e7479206d75737420626520696e206163746976652073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6411017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202250656e64696e675061796f757422206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e942d206062656e6566696369617279603a2042656e6566696369617279206163636f756e742e48636c61696d5f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e6465780005400501436c61696d20746865207061796f75742066726f6d20616e2061776172646564206368696c642d626f756e7479206166746572207061796f75742064656c61792e00ec546865206469737061746368206f726967696e20666f7220746869732063616c6c206d617920626520616e79207369676e6564206f726967696e2e00050143616c6c20776f726b7320696e646570656e64656e74206f6620706172656e7420626f756e74792073746174652c204e6f206e65656420666f7220706172656e7474626f756e747920746f20626520696e206163746976652073746174652e0011015468652042656e65666963696172792069732070616964206f757420776974682061677265656420626f756e74792076616c75652e2043757261746f7220666565206973947061696420262063757261746f72206465706f73697420697320756e72657365727665642e0005014368696c642d626f756e7479206d75737420626520696e202250656e64696e675061796f7574222073746174652c20666f722070726f63657373696e6720746865fc63616c6c2e20416e6420696e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e6c7375636365737366756c2063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e48636c6f73655f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646502012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646502012c426f756e7479496e646578000658110143616e63656c20612070726f706f736564206f7220616374697665206368696c642d626f756e74792e204368696c642d626f756e7479206163636f756e742066756e64730901617265207472616e7366657272656420746f20706172656e7420626f756e7479206163636f756e742e20546865206368696c642d626f756e74792063757261746f72986465706f736974206d617920626520756e726573657276656420696620706f737369626c652e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652065697468657220706172656e742063757261746f72206f724860543a3a52656a6563744f726967696e602e00f0496620746865207374617465206f66206368696c642d626f756e74792069732060416374697665602c2063757261746f72206465706f7369742069732c756e72657365727665642e00f4496620746865207374617465206f66206368696c642d626f756e7479206973206050656e64696e675061796f7574602c2063616c6c206661696c7320267872657475726e73206050656e64696e675061796f757460206572726f722e000d01466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e2c20706172656e7420626f756e7479206d75737420626520696ef06163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f20776f726b2e20466f72206f726967696e90543a3a52656a6563744f726967696e20657865637574696f6e20697320666f726365642e000101496e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89040c4070616c6c65745f626167735f6c6973741870616c6c65741043616c6c08045400044900010c1472656261670401286469736c6f6361746564c10201504163636f756e7449644c6f6f6b75704f663c543e00002859014465636c617265207468617420736f6d6520606469736c6f636174656460206163636f756e74206861732c207468726f7567682072657761726473206f722070656e616c746965732c2073756666696369656e746c7951016368616e676564206974732073636f726520746861742069742073686f756c642070726f7065726c792066616c6c20696e746f206120646966666572656e7420626167207468616e206974732063757272656e74106f6e652e001d01416e796f6e652063616e2063616c6c20746869732066756e6374696f6e2061626f757420616e7920706f74656e7469616c6c79206469736c6f6361746564206163636f756e742e00490157696c6c20616c7761797320757064617465207468652073746f7265642073636f7265206f6620606469736c6f63617465646020746f2074686520636f72726563742073636f72652c206261736564206f6e406053636f726550726f7669646572602e00d4496620606469736c6f63617465646020646f6573206e6f74206578697374732c2069742072657475726e7320616e206572726f722e3c7075745f696e5f66726f6e745f6f6604011c6c696768746572c10201504163636f756e7449644c6f6f6b75704f663c543e000128d04d6f7665207468652063616c6c65722773204964206469726563746c7920696e2066726f6e74206f6620606c696768746572602e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642063616e206f6e6c792062652063616c6c656420627920746865204964206f663501746865206163636f756e7420676f696e6720696e2066726f6e74206f6620606c696768746572602e2046656520697320706179656420627920746865206f726967696e20756e64657220616c6c3863697263756d7374616e6365732e00384f6e6c7920776f726b732069663a00942d20626f7468206e6f646573206172652077697468696e207468652073616d65206261672cd02d20616e6420606f726967696e602068617320612067726561746572206053636f726560207468616e20606c696768746572602e547075745f696e5f66726f6e745f6f665f6f7468657208011c68656176696572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c6c696768746572c10201504163636f756e7449644c6f6f6b75704f663c543e00020c110153616d65206173205b6050616c6c65743a3a7075745f696e5f66726f6e745f6f66605d2c206275742069742063616e2062652063616c6c656420627920616e796f6e652e00c8466565206973207061696420627920746865206f726967696e20756e64657220616c6c2063697263756d7374616e6365732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d040c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c65741043616c6c040454000168106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002845015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f746500cc2a20416e206163636f756e742063616e206f6e6c792062652061206d656d626572206f6620612073696e676c6520706f6f6c2ed82a20416e206163636f756e742063616e6e6f74206a6f696e207468652073616d6520706f6f6c206d756c7469706c652074696d65732e41012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726104011465787472619104015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e30636c61696d5f7061796f757400022055014120626f6e646564206d656d6265722063616e20757365207468697320746f20636c61696d207468656972207061796f7574206261736564206f6e20746865207265776172647320746861742074686520706f6f6c610168617320616363756d756c617465642073696e6365207468656972206c61737420636c61696d6564207061796f757420284f522073696e6365206a6f696e696e6720696620746869732069732074686569722066697273743d0174696d6520636c61696d696e672072657761726473292e20546865207061796f75742077696c6c206265207472616e7366657272656420746f20746865206d656d6265722773206163636f756e742e004901546865206d656d6265722077696c6c206561726e20726577617264732070726f2072617461206261736564206f6e20746865206d656d62657273207374616b65207673207468652073756d206f6620746865d06d656d6265727320696e2074686520706f6f6c73207374616b652e205265776172647320646f206e6f742022657870697265222e0041015365652060636c61696d5f7061796f75745f6f746865726020746f20636c61696d2072657761726473206f6e20626568616c66206f6620736f6d6520606f746865726020706f6f6c206d656d6265722e18756e626f6e640801386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640801386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e0001486e756d5f736c617368696e675f7370616e7310010c7533320005585501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500f42d204966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e61012d2049662074686520706f6f6c2068617320616e792070656e64696e6720736c6173682c20776520616c736f2074727920746f20736c61736820746865206d656d626572206265666f7265206c657474696e67207468656d5d0177697468647261772e20546869732063616c63756c6174696f6e206164647320736f6d6520776569676874206f7665726865616420616e64206973206f6e6c7920646566656e736976652e20496e207265616c6974792c5501706f6f6c20736c6173686573206d7573742068617665206265656e20616c7265616479206170706c69656420766961207065726d697373696f6e6c657373205b6043616c6c3a3a6170706c795f736c617368605d2e18637265617465100118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f6964140118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f72733d0201445665633c543a3a4163636f756e7449643e0008307c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e001823204e6f7465005d01496e206164646974696f6e20746f20612060726f6f7460206f7220606e6f6d696e61746f726020726f6c65206f6620606f726967696e602c20706f6f6c2773206465706f7369746f72206e6565647320746f2068617665f86174206c6561737420606465706f7369746f725f6d696e5f626f6e646020696e2074686520706f6f6c20746f207374617274206e6f6d696e6174696e672e247365745f737461746508011c706f6f6c5f6964100118506f6f6c496400011473746174651d010124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731801346d696e5f6a6f696e5f626f6e6495040158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6495040158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7399040134436f6e6669674f703c7533323e00012c6d61785f6d656d6265727399040134436f6e6669674f703c7533323e0001506d61785f6d656d626572735f7065725f706f6f6c99040134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e9d040144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d757374206265605b60436f6e6669673a3a41646d696e4f726967696e605d2e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f74a1040158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f72a1040158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e636572a1040158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d40704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004101546865206469737061746368206f726967696e206f6620746869732063616c6c2063616e206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463683a59012a205768656e20706f6f6c206465706f7369746f7220686173206c657373207468616e20604d696e4e6f6d696e61746f72426f6e6460207374616b65642c206f74686572776973652020706f6f6c206d656d626572735c202061726520756e61626c6520746f20756e626f6e642e009c2320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463683ad82a205468652063616c6c6572206861732061206e6f6d696e61746f72206f7220726f6f7420726f6c65206f662074686520706f6f6c2e490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720801186d656d626572c10201504163636f756e7449644c6f6f6b75704f663c543e00011465787472619104015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373436f6d706f756e6460206f7220605065726d697373696f6e6c657373416c6c602e507365745f636c61696d5f7065726d697373696f6e0401287065726d697373696f6ea504013c436c61696d5065726d697373696f6e000f1c4901416c6c6f7773206120706f6f6c206d656d62657220746f20736574206120636c61696d207065726d697373696f6e20746f20616c6c6f77206f7220646973616c6c6f77207065726d697373696f6e6c65737360626f6e64696e6720616e64207769746864726177696e672e002c2320417267756d656e747300782a20606f726967696e60202d204d656d626572206f66206120706f6f6c2eb82a20607065726d697373696f6e60202d20546865207065726d697373696f6e20746f206265206170706c6965642e48636c61696d5f7061796f75745f6f746865720401146f74686572000130543a3a4163636f756e7449640010100101606f726967696e602063616e20636c61696d207061796f757473206f6e20736f6d6520706f6f6c206d656d62657220606f7468657260277320626568616c662e005501506f6f6c206d656d62657220606f7468657260206d7573742068617665206120605065726d697373696f6e6c657373576974686472617760206f7220605065726d697373696f6e6c657373416c6c6020636c61696da87065726d697373696f6e20666f7220746869732063616c6c20746f206265207375636365737366756c2e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6cc869732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e2c6170706c795f736c6173680401386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e001724884170706c7920612070656e64696e6720736c617368206f6e2061206d656d6265722e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e005d015468652070656e64696e6720736c61736820616d6f756e74206f6620746865206d656d626572206d75737420626520657175616c206f72206d6f7265207468616e20604578697374656e7469616c4465706f736974602e5101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79206163636f756e74292e2049662074686520657865637574696f6e49016973207375636365737366756c2c2066656520697320726566756e64656420616e642063616c6c6572206d6179206265207265776172646564207769746820612070617274206f662074686520736c6173680d016261736564206f6e20746865205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d20636f6e66696775726174696f6e2e486d6967726174655f64656c65676174696f6e0401386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e0018241d014d696772617465732064656c6567617465642066756e64732066726f6d2074686520706f6f6c206163636f756e7420746f2074686520606d656d6265725f6163636f756e74602e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e002901546869732069732061207065726d697373696f6e2d6c6573732063616c6c20616e6420726566756e647320616e792066656520696620636c61696d206973207375636365737366756c2e005d0149662074686520706f6f6c20686173206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746865207374616b656420746f6b656e73206f6620706f6f6c206d656d62657273290163616e206265206d6f76656420616e642068656c6420696e207468656972206f776e206163636f756e742e20536565205b60616461707465723a3a44656c65676174655374616b65605d786d6967726174655f706f6f6c5f746f5f64656c65676174655f7374616b6504011c706f6f6c5f6964100118506f6f6c4964001924f44d69677261746520706f6f6c2066726f6d205b60616461707465723a3a5374616b655374726174656779547970653a3a5472616e73666572605d20746fa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e004101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792c20616e6420726566756e647320616e7920666565206966207375636365737366756c2e00490149662074686520706f6f6c2068617320616c7265616479206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746869732063616c6c2077696c6c206661696c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e9104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324426f6e644578747261041c42616c616e6365011801082c4672656542616c616e6365040018011c42616c616e63650000001c52657761726473000100009504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200009904085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200009d04085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f766500020000a104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f766500020000a504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000a9040c4070616c6c65745f7363686564756c65721870616c6c65741043616c6c040454000128207363686564756c651001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00000470416e6f6e796d6f75736c79207363686564756c652061207461736b2e1863616e63656c0801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001049443616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e387363686564756c655f6e616d656414010869640401205461736b4e616d650001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000204585363686564756c652061206e616d6564207461736b2e3063616e63656c5f6e616d656404010869640401205461736b4e616d650003047843616e63656c2061206e616d6564207363686564756c6564207461736b2e387363686564756c655f61667465721001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000404a8416e6f6e796d6f75736c79207363686564756c652061207461736b20616674657220612064656c61792e507363686564756c655f6e616d65645f616674657214010869640401205461736b4e616d650001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963ad0401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000504905363686564756c652061206e616d6564207461736b20616674657220612064656c61792e247365745f72657472790c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0006305901536574206120726574727920636f6e66696775726174696f6e20666f722061207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069742077696c6c5501626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c2069742473756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3c7365745f72657472795f6e616d65640c010869640401205461736b4e616d6500011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0007305d01536574206120726574727920636f6e66696775726174696f6e20666f722061206e616d6564207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069745d0177696c6c20626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c3069742073756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3063616e63656c5f72657472790401107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e000804a852656d6f7665732074686520726574727920636f6e66696775726174696f6e206f662061207461736b2e4863616e63656c5f72657472795f6e616d656404010869640401205461736b4e616d65000904bc43616e63656c2074686520726574727920636f6e66696775726174696f6e206f662061206e616d6564207461736b2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ead0404184f7074696f6e0404540139010108104e6f6e6500000010536f6d65040039010000010000b1040c3c70616c6c65745f707265696d6167651870616c6c65741043616c6c040454000114346e6f74655f707265696d616765040114627974657338011c5665633c75383e000010745265676973746572206120707265696d616765206f6e2d636861696e2e00550149662074686520707265696d616765207761732070726576696f75736c79207265717565737465642c206e6f2066656573206f72206465706f73697473206172652074616b656e20666f722070726f766964696e67550174686520707265696d6167652e204f74686572776973652c2061206465706f7369742069732074616b656e2070726f706f7274696f6e616c20746f207468652073697a65206f662074686520707265696d6167652e3c756e6e6f74655f707265696d6167650401106861736834011c543a3a48617368000118dc436c65617220616e20756e72657175657374656420707265696d6167652066726f6d207468652072756e74696d652073746f726167652e00fc496620606c656e602069732070726f76696465642c207468656e2069742077696c6c2062652061206d7563682063686561706572206f7065726174696f6e2e0001012d206068617368603a205468652068617368206f662074686520707265696d61676520746f2062652072656d6f7665642066726f6d207468652073746f72652eb82d20606c656e603a20546865206c656e677468206f662074686520707265696d616765206f66206068617368602e40726571756573745f707265696d6167650401106861736834011c543a3a48617368000210410152657175657374206120707265696d6167652062652075706c6f6164656420746f2074686520636861696e20776974686f757420706179696e6720616e792066656573206f72206465706f736974732e00550149662074686520707265696d6167652072657175657374732068617320616c7265616479206265656e2070726f7669646564206f6e2d636861696e2c20776520756e7265736572766520616e79206465706f7369743901612075736572206d6179206861766520706169642c20616e642074616b652074686520636f6e74726f6c206f662074686520707265696d616765206f7574206f662074686569722068616e64732e48756e726571756573745f707265696d6167650401106861736834011c543a3a4861736800030cbc436c65617220612070726576696f75736c79206d616465207265717565737420666f72206120707265696d6167652e002d014e4f54453a2054484953204d555354204e4f542042452043414c4c4544204f4e20606861736860204d4f52452054494d4553205448414e2060726571756573745f707265696d616765602e38656e737572655f75706461746564040118686173686573c10101305665633c543a3a486173683e00040cc4456e7375726520746861742074686520612062756c6b206f66207072652d696d616765732069732075706772616465642e003d015468652063616c6c65722070617973206e6f20666565206966206174206c6561737420393025206f66207072652d696d616765732077657265207375636365737366756c6c7920757064617465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb5040c3c70616c6c65745f74785f70617573651870616c6c65741043616c6c04045400010814706175736504012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e00001034506175736520612063616c6c2e00b843616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a50617573654f726967696e605d2ec0456d69747320616e205b604576656e743a3a43616c6c506175736564605d206576656e74206f6e20737563636573732e1c756e70617573650401146964656e745101015052756e74696d6543616c6c4e616d654f663c543e00011040556e2d706175736520612063616c6c2e00c043616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a556e70617573654f726967696e605d2ec8456d69747320616e205b604576656e743a3a43616c6c556e706175736564605d206576656e74206f6e20737563636573732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb9040c4070616c6c65745f696d5f6f6e6c696e651870616c6c65741043616c6c04045400010424686561727462656174080124686561727462656174bd0401704865617274626561743c426c6f636b4e756d626572466f723c543e3e0001247369676e6174757265c10401bc3c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000c38232320436f6d706c65786974793afc2d20604f284b2960207768657265204b206973206c656e677468206f6620604b6579736020286865617274626561742e76616c696461746f72735f6c656e298820202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b60040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ebd04084070616c6c65745f696d5f6f6e6c696e6524486561727462656174042c426c6f636b4e756d626572013000100130626c6f636b5f6e756d62657230012c426c6f636b4e756d62657200013473657373696f6e5f696e64657810013053657373696f6e496e64657800013c617574686f726974795f696e64657810012441757468496e64657800013876616c696461746f72735f6c656e10010c7533320000c104104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139245369676e61747572650000040009030148737232353531393a3a5369676e61747572650000c5040c3c70616c6c65745f6964656e746974791870616c6c65741043616c6c040454000158346164645f72656769737472617204011c6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00001c7841646420612072656769737472617220746f207468652073797374656d2e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060543a3a5265676973747261724f726967696e602e00a82d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e0094456d6974732060526567697374726172416464656460206966207375636365737366756c2e307365745f6964656e74697479040110696e666fc904016c426f783c543a3a4964656e74697479496e666f726d6174696f6e3e000128290153657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e005501496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7450666f7220746865206e6577206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e008c2d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e0088456d69747320604964656e7469747953657460206966207375636365737366756c2e207365745f7375627304011073756273510501645665633c28543a3a4163636f756e7449642c2044617461293e0002248c53657420746865207375622d6163636f756e7473206f66207468652073656e6465722e0055015061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e65642d01616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e00b02d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e38636c6561725f6964656e746974790003203901436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e00ec5061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e0098456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e44726571756573745f6a756467656d656e740801247265675f696e64657865020138526567697374726172496e64657800011c6d61785f6665656d01013042616c616e63654f663c543e00044094526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e0055015061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7418676976656e2e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e001d012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e55012d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a00306060606e6f636f6d70696c65b853656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665650c60606000a4456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e3863616e63656c5f726571756573740401247265675f696e646578100138526567697374726172496e6465780005286843616e63656c20612070726576696f757320726571756573742e00f85061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e0045012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e00ac456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e1c7365745f666565080114696e64657865020138526567697374726172496e64657800010c6665656d01013042616c616e63654f663c543e00061c1901536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e542d2060666565603a20746865206e6577206665652e387365745f6163636f756e745f6964080114696e64657865020138526567697374726172496e64657800010c6e6577c10201504163636f756e7449644c6f6f6b75704f663c543e00071cbc4368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e702d20606e6577603a20746865206e6577206163636f756e742049442e287365745f6669656c6473080114696e64657865020138526567697374726172496e6465780001186669656c6473300129013c543a3a4964656e74697479496e666f726d6174696f6e206173204964656e74697479496e666f726d6174696f6e50726f76696465723e3a3a0a4669656c64734964656e74696669657200081ca853657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e0d012d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e4470726f766964655f6a756467656d656e741001247265675f696e64657865020138526567697374726172496e646578000118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e0001246a756467656d656e745905015c4a756467656d656e743c42616c616e63654f663c543e3e0001206964656e7469747934011c543a3a4861736800093cb850726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74b06f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e0021012d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e55012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e49012d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e5d012d20606964656e74697479603a205468652068617368206f6620746865205b604964656e74697479496e666f726d6174696f6e50726f7669646572605d20666f72207468617420746865206a756467656d656e742069732c202070726f76696465642e00b04e6f74653a204a756467656d656e747320646f206e6f74206170706c7920746f206120757365726e616d652e0094456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e346b696c6c5f6964656e74697479040118746172676574c10201504163636f756e7449644c6f6f6b75704f663c543e000a30410152656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e0061015061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c6564206279450160536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564806d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e00f8546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206d617463682060543a3a466f7263654f726967696e602e0055012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e0094456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e1c6164645f73756208010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d504011044617461000b1cac4164642074686520676976656e206163636f756e7420746f207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656e616d655f73756208010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d504011044617461000c10cc416c74657220746865206173736f636961746564206e616d65206f662074686520676976656e207375622d6163636f756e742e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656d6f76655f73756204010c737562c10201504163636f756e7449644c6f6f6b75704f663c543e000d1cc052656d6f76652074686520676976656e206163636f756e742066726f6d207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e20717569745f737562000e288c52656d6f7665207468652073656e6465722061732061207375622d6163636f756e742e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c206265207265706174726961746564b4746f207468652073656e64657220282a6e6f742a20746865206f726967696e616c206465706f7369746f72292e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d7573742068617665206120726567697374657265643c73757065722d6964656e746974792e0045014e4f54453a20546869732073686f756c64206e6f74206e6f726d616c6c7920626520757365642c206275742069732070726f766964656420696e207468652063617365207468617420746865206e6f6e2d1101636f6e74726f6c6c6572206f6620616e206163636f756e74206973206d616c6963696f75736c7920726567697374657265642061732061207375622d6163636f756e742e586164645f757365726e616d655f617574686f726974790c0124617574686f72697479c10201504163636f756e7449644c6f6f6b75704f663c543e00011873756666697838011c5665633c75383e000128616c6c6f636174696f6e10010c753332000f10550141646420616e20604163636f756e744964602077697468207065726d697373696f6e20746f206772616e7420757365726e616d65732077697468206120676976656e20607375666669786020617070656e6465642e00590154686520617574686f726974792063616e206772616e7420757020746f2060616c6c6f636174696f6e6020757365726e616d65732e20546f20746f7020757020746865697220616c6c6f636174696f6e2c2074686579490173686f756c64206a75737420697373756520286f7220726571756573742076696120676f7665726e616e6365292061206e657720606164645f757365726e616d655f617574686f72697479602063616c6c2e6472656d6f76655f757365726e616d655f617574686f72697479040124617574686f72697479c10201504163636f756e7449644c6f6f6b75704f663c543e001004c452656d6f76652060617574686f72697479602066726f6d2074686520757365726e616d6520617574686f7269746965732e407365745f757365726e616d655f666f720c010c77686fc10201504163636f756e7449644c6f6f6b75704f663c543e000120757365726e616d6538011c5665633c75383e0001247369676e61747572655d0501704f7074696f6e3c543a3a4f6666636861696e5369676e61747572653e0011240d015365742074686520757365726e616d6520666f72206077686f602e204d7573742062652063616c6c6564206279206120757365726e616d6520617574686f726974792e00550154686520617574686f72697479206d757374206861766520616e2060616c6c6f636174696f6e602e2055736572732063616e20656974686572207072652d7369676e20746865697220757365726e616d6573206f7248616363657074207468656d206c617465722e003c557365726e616d6573206d7573743ad820202d204f6e6c7920636f6e7461696e206c6f776572636173652041534349492063686172616374657273206f72206469676974732e350120202d205768656e20636f6d62696e656420776974682074686520737566666978206f66207468652069737375696e6720617574686f72697479206265205f6c657373207468616e5f207468656020202020604d6178557365726e616d654c656e677468602e3c6163636570745f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0012084d01416363657074206120676976656e20757365726e616d65207468617420616e2060617574686f7269747960206772616e7465642e205468652063616c6c206d75737420696e636c756465207468652066756c6c88757365726e616d652c20617320696e2060757365726e616d652e737566666978602e5c72656d6f76655f657870697265645f617070726f76616c040120757365726e616d657d01012c557365726e616d653c543e00130c610152656d6f766520616e206578706972656420757365726e616d6520617070726f76616c2e2054686520757365726e616d652077617320617070726f76656420627920616e20617574686f7269747920627574206e657665725501616363657074656420627920746865207573657220616e64206d757374206e6f77206265206265796f6e64206974732065787069726174696f6e2e205468652063616c6c206d75737420696e636c756465207468659c66756c6c20757365726e616d652c20617320696e2060757365726e616d652e737566666978602e507365745f7072696d6172795f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0014043101536574206120676976656e20757365726e616d6520617320746865207072696d6172792e2054686520757365726e616d652073686f756c6420696e636c75646520746865207375666669782e6072656d6f76655f64616e676c696e675f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e001508550152656d6f7665206120757365726e616d65207468617420636f72726573706f6e647320746f20616e206163636f756e742077697468206e6f206964656e746974792e20457869737473207768656e20612075736572c067657473206120757365726e616d6520627574207468656e2063616c6c732060636c6561725f6964656e74697479602e04704964656e746974792070616c6c6574206465636c61726174696f6e2ec9040c3c70616c6c65745f6964656e74697479186c6567616379304964656e74697479496e666f04284669656c644c696d697400002401286164646974696f6e616ccd040190426f756e6465645665633c28446174612c2044617461292c204669656c644c696d69743e00011c646973706c6179d5040110446174610001146c6567616cd50401104461746100010c776562d50401104461746100011072696f74d504011044617461000114656d61696cd50401104461746100013c7067705f66696e6765727072696e744d0501404f7074696f6e3c5b75383b2032305d3e000114696d616765d50401104461746100011c74776974746572d5040110446174610000cd040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d104045300000400490501185665633c543e0000d10400000408d504d50400d5040c3c70616c6c65745f6964656e746974791474797065731044617461000198104e6f6e6500000010526177300400d9040000010010526177310400dd040000020010526177320400e1040000030010526177330400e5040000040010526177340400480000050010526177350400e9040000060010526177360400ed040000070010526177370400f1040000080010526177380400a9020000090010526177390400f50400000a001452617731300400f90400000b001452617731310400fd0400000c001452617731320400010500000d001452617731330400050500000e001452617731340400090500000f0014526177313504000d05000010001452617731360400490100001100145261773137040011050000120014526177313804001505000013001452617731390400190500001400145261773230040095010000150014526177323104001d050000160014526177323204002105000017001452617732330400250500001800145261773234040029050000190014526177323504002d0500001a001452617732360400310500001b001452617732370400350500001c001452617732380400390500001d0014526177323904003d0500001e001452617733300400410500001f001452617733310400450500002000145261773332040004000021002c426c616b6554776f323536040004000022001853686132353604000400002300244b656363616b323536040004000024002c53686154687265653235360400040000250000d904000003000000000800dd04000003010000000800e104000003020000000800e504000003030000000800e904000003050000000800ed04000003060000000800f104000003070000000800f504000003090000000800f9040000030a0000000800fd040000030b000000080001050000030c000000080005050000030d000000080009050000030e00000008000d050000030f00000008001105000003110000000800150500000312000000080019050000031300000008001d050000031500000008002105000003160000000800250500000317000000080029050000031800000008002d0500000319000000080031050000031a000000080035050000031b000000080039050000031c00000008003d050000031d000000080041050000031e000000080045050000031f00000008004905000002d104004d0504184f7074696f6e0404540195010108104e6f6e6500000010536f6d65040095010000010000510500000255050055050000040800d5040059050c3c70616c6c65745f6964656e74697479147479706573244a756467656d656e74041c42616c616e63650118011c1c556e6b6e6f776e0000001c46656550616964040018011c42616c616e636500010028526561736f6e61626c65000200244b6e6f776e476f6f64000300244f75744f6644617465000400284c6f775175616c697479000500244572726f6e656f7573000600005d0504184f7074696f6e0404540161050108104e6f6e6500000010536f6d650400610500000100006105082873705f72756e74696d65384d756c74695369676e617475726500010c1c45643235353139040009030148656432353531393a3a5369676e61747572650000001c53723235353139040009030148737232353531393a3a5369676e617475726500010014456364736104000502014065636473613a3a5369676e61747572650002000065050c3870616c6c65745f7574696c6974791870616c6c65741043616c6c04045400011814626174636804011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000487c53656e642061206261746368206f662064697370617463682063616c6c732e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e005501546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e31016576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e207468655501604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d6164654d01616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c65746564604c6576656e74206973206465706f73697465642e3461735f64657269766174697665080114696e646578e901010c75313600011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000134dc53656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e00550146696c7465722066726f6d206f726967696e206172652070617373656420616c6f6e672e205468652063616c6c2077696c6c2062652064697370617463686564207769746820616e206f726967696e207768696368bc757365207468652073616d652066696c74657220617320746865206f726967696e206f6620746869732063616c6c2e0045014e4f54453a20496620796f75206e65656420746f20656e73757265207468617420616e79206163636f756e742d62617365642066696c746572696e67206973206e6f7420686f6e6f7265642028692e652e61016265636175736520796f7520657870656374206070726f78796020746f2068617665206265656e2075736564207072696f7220696e207468652063616c6c20737461636b20616e6420796f7520646f206e6f742077616e7451017468652063616c6c207265737472696374696f6e7320746f206170706c7920746f20616e79207375622d6163636f756e7473292c207468656e20757365206061735f6d756c74695f7468726573686f6c645f31607c696e20746865204d756c74697369672070616c6c657420696e73746561642e00f44e4f54453a205072696f7220746f2076657273696f6e202a31322c2074686973207761732063616c6c6564206061735f6c696d697465645f737562602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2462617463685f616c6c04011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000234ec53656e642061206261746368206f662064697370617463682063616c6c7320616e642061746f6d6963616c6c792065786563757465207468656d2e21015468652077686f6c65207472616e73616374696f6e2077696c6c20726f6c6c6261636b20616e64206661696c20696620616e79206f66207468652063616c6c73206661696c65642e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c64697370617463685f617308012461735f6f726967696e6d050154426f783c543a3a50616c6c6574734f726967696e3e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000318c84469737061746368657320612066756e6374696f6e2063616c6c207769746820612070726f7669646564206f726967696e2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e0034232320436f6d706c65786974791c2d204f2831292e2c666f7263655f626174636804011463616c6c736905017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0004347c53656e642061206261746368206f662064697370617463682063616c6c732ed4556e6c696b6520606261746368602c20697420616c6c6f7773206572726f727320616e6420776f6e277420696e746572727570742e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e004d014966206f726967696e20697320726f6f74207468656e207468652063616c6c732061726520646973706174636820776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c776974685f77656967687408011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000518c4446973706174636820612066756e6374696f6e2063616c6c2077697468206120737065636966696564207765696768742e002d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b8526f6f74206f726967696e20746f20737065636966792074686520776569676874206f66207468652063616c6c2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e6905000002b902006d05085874616e676c655f746573746e65745f72756e74696d65304f726967696e43616c6c65720001101873797374656d0400710501746672616d655f73797374656d3a3a4f726967696e3c52756e74696d653e0001001c436f756e63696c0400750501010170616c6c65745f636f6c6c6563746976653a3a4f726967696e3c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d0020457468657265756d04007905015c70616c6c65745f657468657265756d3a3a4f726967696e00210010566f696404001d0301410173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a0a5f5f707269766174653a3a566f69640003000071050c346672616d655f737570706f7274206469737061746368245261774f726967696e04244163636f756e7449640100010c10526f6f74000000185369676e656404000001244163636f756e744964000100104e6f6e65000200007505084470616c6c65745f636f6c6c656374697665245261774f726967696e08244163636f756e7449640100044900010c1c4d656d62657273080010012c4d656d626572436f756e74000010012c4d656d626572436f756e74000000184d656d62657204000001244163636f756e744964000100205f5068616e746f6d000200007905083c70616c6c65745f657468657265756d245261774f726967696e0001044c457468657265756d5472616e73616374696f6e04009101011048313630000000007d050c3c70616c6c65745f6d756c74697369671870616c6c65741043616c6c0404540001105061735f6d756c74695f7468726573686f6c645f310801446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000305101496d6d6564696174656c792064697370617463682061206d756c74692d7369676e61747572652063616c6c207573696e6720612073696e676c6520617070726f76616c2066726f6d207468652063616c6c65722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e003d012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f206172652070617274206f662074686501016d756c74692d7369676e61747572652c2062757420646f206e6f7420706172746963697061746520696e2074686520617070726f76616c2070726f636573732e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e00b8526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c742e0034232320436f6d706c657869747919014f285a202b204329207768657265205a20697320746865206c656e677468206f66207468652063616c6c20616e6420432069747320657865637574696f6e207765696768742e2061735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74810501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0001286d61785f77656967687428011857656967687400019c5501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e00b049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e001d014e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f20757365190160617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e005901526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f746865727769736555016f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642cdc6d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e0034232320436f6d706c6578697479502d20604f2853202b205a202b2043616c6c29602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e21012d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e6c2d2054686520776569676874206f6620746865206063616c6c602e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e40617070726f76655f61735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74810501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00012463616c6c5f686173680401205b75383b2033325d0001286d61785f7765696768742801185765696768740002785501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0035014e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e3c63616e63656c5f61735f6d756c74691001247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f726965733d0201445665633c543a3a4163636f756e7449643e00012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e00012463616c6c5f686173680401205b75383b2033325d000354550143616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c79c4666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e5d012d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c787472616e73616374696f6e20666f7220746869732064697370617463682ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e302d204f6e65206576656e742e842d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e702d2053746f726167653a2072656d6f766573206f6e65206974656d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e810504184f7074696f6e0404540189010108104e6f6e6500000010536f6d6504008901000001000085050c3c70616c6c65745f657468657265756d1870616c6c65741043616c6c040454000104207472616e7361637404012c7472616e73616374696f6e8905012c5472616e73616374696f6e000004845472616e7361637420616e20457468657265756d207472616e73616374696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89050c20657468657265756d2c7472616e73616374696f6e345472616e73616374696f6e563200010c184c656761637904008d0501444c65676163795472616e73616374696f6e0000001c4549503239333004009d050148454950323933305472616e73616374696f6e0001001c454950313535390400a9050148454950313535395472616e73616374696f6e000200008d050c20657468657265756d2c7472616e73616374696f6e444c65676163795472616e73616374696f6e00001c01146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e70757438011442797465730001247369676e6174757265950501505472616e73616374696f6e5369676e6174757265000091050c20657468657265756d2c7472616e73616374696f6e445472616e73616374696f6e416374696f6e0001081043616c6c04009101011048313630000000184372656174650001000095050c20657468657265756d2c7472616e73616374696f6e505472616e73616374696f6e5369676e617475726500000c010476990501545472616e73616374696f6e5265636f76657279496400010472340110483235360001047334011048323536000099050c20657468657265756d2c7472616e73616374696f6e545472616e73616374696f6e5265636f7665727949640000040030010c75363400009d050c20657468657265756d2c7472616e73616374696f6e48454950323933305472616e73616374696f6e00002c0120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a10501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000a105000002a50500a5050c20657468657265756d2c7472616e73616374696f6e384163636573734c6973744974656d000008011c616464726573739101011c4164647265737300013073746f726167655f6b657973c10101245665633c483235363e0000a9050c20657468657265756d2c7472616e73616374696f6e48454950313535395472616e73616374696f6e0000300120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173c90101105532353600013c6d61785f6665655f7065725f676173c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e910501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a10501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000ad050c2870616c6c65745f65766d1870616c6c65741043616c6c04045400011020776974686472617708011c61646472657373910101104831363000011476616c756518013042616c616e63654f663c543e000004e057697468647261772062616c616e63652066726f6d2045564d20696e746f2063757272656e63792f62616c616e6365732070616c6c65742e1063616c6c240118736f7572636591010110483136300001187461726765749101011048313630000114696e70757438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0001045d01497373756520616e2045564d2063616c6c206f7065726174696f6e2e20546869732069732073696d696c617220746f2061206d6573736167652063616c6c207472616e73616374696f6e20696e20457468657265756d2e18637265617465200118736f757263659101011048313630000110696e697438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0002085101497373756520616e2045564d20637265617465206f7065726174696f6e2e20546869732069732073696d696c617220746f206120636f6e7472616374206372656174696f6e207472616e73616374696f6e20696e24457468657265756d2e1c63726561746532240118736f757263659101011048313630000110696e697438011c5665633c75383e00011073616c743401104832353600011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b10501304f7074696f6e3c553235363e0001146e6f6e6365b10501304f7074696f6e3c553235363e00012c6163636573735f6c697374b50501585665633c28483136302c205665633c483235363e293e0003047c497373756520616e2045564d2063726561746532206f7065726174696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb10504184f7074696f6e04045401c9010108104e6f6e6500000010536f6d650400c9010000010000b505000002b90500b905000004089101c10100bd050c4870616c6c65745f64796e616d69635f6665651870616c6c65741043616c6c040454000104646e6f74655f6d696e5f6761735f70726963655f746172676574040118746172676574c901011055323536000000040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec1050c3c70616c6c65745f626173655f6665651870616c6c65741043616c6c040454000108507365745f626173655f6665655f7065725f67617304010c666565c901011055323536000000387365745f656c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000100040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5050c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c65741043616c6c04045400010478686f746669785f696e635f6163636f756e745f73756666696369656e7473040124616464726573736573c90501245665633c483136303e0000100502496e6372656d656e74206073756666696369656e74736020666f72206578697374696e67206163636f756e747320686176696e672061206e6f6e7a65726f20606e6f6e63656020627574207a65726f206073756666696369656e7473602c2060636f6e73756d6572736020616e64206070726f766964657273602076616c75652e2d0154686973207374617465207761732063617573656420627920612070726576696f75732062756720696e2045564d20637265617465206163636f756e7420646973706174636861626c652e006501416e79206163636f756e747320696e2074686520696e707574206c697374206e6f742073617469736679696e67207468652061626f766520636f6e646974696f6e2077696c6c2072656d61696e20756e61666665637465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec905000002910100cd050c5470616c6c65745f61697264726f705f636c61696d731870616c6c65741043616c6c04045400011814636c61696d0c011064657374d10501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d10501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d50501544d756c7469416464726573735369676e6174757265000060904d616b65206120636c61696d20746f20636f6c6c65637420796f757220746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a0501412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653a943e2028636f6e666967757265642070726566697820737472696e672928616464726573732900a4616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732ee057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d696e745f636c61696d10010c77686fd90101304d756c74694164647265737300011476616c756518013042616c616e63654f663c543e00014076657374696e675f7363686564756c65e1050179014f7074696f6e3c426f756e6465645665633c0a2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e292c20543a3a0a4d617856657374696e675363686564756c65733e2c3e00012473746174656d656e74f10501544f7074696f6e3c53746174656d656e744b696e643e00013ca84d696e742061206e657720636c61696d20746f20636f6c6c656374206e617469766520746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e002c506172616d65746572733af02d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2ef02d206076616c7565603a20546865206e756d626572206f66206e617469766520746f6b656e7320746861742077696c6c20626520636c61696d65642e2d012d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f72207468657365206e617469766520746f6b656e732e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e1d01576520617373756d6520776f7273742063617365207468617420626f74682076657374696e6720616e642073746174656d656e74206973206265696e6720696e7365727465642e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e30636c61696d5f61747465737410011064657374d10501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d10501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d50501544d756c7469416464726573735369676e617475726500012473746174656d656e7438011c5665633c75383e00026c09014d616b65206120636c61696d20746f20636f6c6c65637420796f7572206e617469766520746f6b656e73206279207369676e696e6720612073746174656d656e742e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a2901412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653ac03e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e7429004901616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973c06578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e39012d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e207468653020207369676e61747572652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732efc57656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d5f617474657374602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d6f76655f636c61696d08010c6f6c64d90101304d756c74694164647265737300010c6e6577d90101304d756c7469416464726573730004005c666f7263655f7365745f6578706972795f636f6e6669670801306578706972795f626c6f636b300144426c6f636b4e756d626572466f723c543e00011064657374d90101304d756c74694164647265737300050878536574207468652076616c756520666f7220657870697279636f6e6669678443616e206f6e6c792062652063616c6c656420627920466f7263654f726967696e30636c61696d5f7369676e656404011064657374d10501504f7074696f6e3c4d756c7469416464726573733e00060460436c61696d2066726f6d207369676e6564206f726967696e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed10504184f7074696f6e04045401d9010108104e6f6e6500000010536f6d650400d9010000010000d5050c5470616c6c65745f61697264726f705f636c61696d73147574696c73544d756c7469416464726573735369676e61747572650001080c45564d0400d905013845636473615369676e6174757265000000184e61746976650400dd050140537232353531395369676e617475726500010000d905105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733845636473615369676e617475726500000400050201205b75383b2036355d0000dd050c5470616c6c65745f61697264726f705f636c61696d73147574696c7340537232353531395369676e617475726500000400090301245369676e61747572650000e10504184f7074696f6e04045401e5050108104e6f6e6500000010536f6d650400e5050000010000e5050c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e905045300000400ed0501185665633c543e0000e9050000040c18183000ed05000002e90500f10504184f7074696f6e04045401f5050108104e6f6e6500000010536f6d650400f5050000010000f505085470616c6c65745f61697264726f705f636c61696d733453746174656d656e744b696e640001081c526567756c6172000000105361666500010000f9050c3070616c6c65745f70726f78791870616c6c65741043616c6c0404540001281470726f78790c01107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065fd0501504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000244d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f726973656420666f72207468726f75676830606164645f70726f7879602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e246164645f70726f78790c012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e0001244501526567697374657220612070726f7879206163636f756e7420666f72207468652073656e64657220746861742069732061626c6520746f206d616b652063616c6c73206f6e2069747320626568616c662e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a11012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f206d616b6520612070726f78792efc2d206070726f78795f74797065603a20546865207065726d697373696f6e7320616c6c6f77656420666f7220746869732070726f7879206163636f756e742e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e3072656d6f76655f70726f78790c012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00021ca8556e726567697374657220612070726f7879206163636f756e7420666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a25012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f2072656d6f766520617320612070726f78792e41012d206070726f78795f74797065603a20546865207065726d697373696f6e732063757272656e746c7920656e61626c656420666f72207468652072656d6f7665642070726f7879206163636f756e742e3872656d6f76655f70726f78696573000318b4556e726567697374657220616c6c2070726f7879206163636f756e747320666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0041015741524e494e473a2054686973206d61792062652063616c6c6564206f6e206163636f756e74732063726561746564206279206070757265602c20686f776576657220696620646f6e652c207468656e590174686520756e726573657276656420666565732077696c6c20626520696e61636365737369626c652e202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a2c6372656174655f707572650c012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e000114696e646578e901010c7531360004483901537061776e2061206672657368206e6577206163636f756e7420746861742069732067756172616e7465656420746f206265206f746865727769736520696e61636365737369626c652c20616e64fc696e697469616c697a65206974207769746820612070726f7879206f66206070726f78795f747970656020666f7220606f726967696e602073656e6465722e006c5265717569726573206120605369676e656460206f726967696e2e0051012d206070726f78795f74797065603a205468652074797065206f66207468652070726f78792074686174207468652073656e6465722077696c6c2062652072656769737465726564206173206f766572207468654d016e6577206163636f756e742e20546869732077696c6c20616c6d6f737420616c7761797320626520746865206d6f7374207065726d697373697665206050726f7879547970656020706f737369626c6520746f78616c6c6f7720666f72206d6178696d756d20666c65786962696c6974792e51012d2060696e646578603a204120646973616d626967756174696f6e20696e6465782c20696e206361736520746869732069732063616c6c6564206d756c7469706c652074696d657320696e207468652073616d655d017472616e73616374696f6e2028652e672e207769746820607574696c6974793a3a626174636860292e20556e6c65737320796f75277265207573696e67206062617463686020796f752070726f6261626c79206a7573744077616e7420746f20757365206030602e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e0051014661696c73207769746820604475706c69636174656020696620746869732068617320616c7265616479206265656e2063616c6c656420696e2074686973207472616e73616374696f6e2c2066726f6d207468659873616d652073656e6465722c2077697468207468652073616d6520706172616d65746572732e00e44661696c732069662074686572652061726520696e73756666696369656e742066756e647320746f2070617920666f72206465706f7369742e246b696c6c5f7075726514011c737061776e6572c10201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f787954797065000114696e646578e901010c7531360001186865696768742c0144426c6f636b4e756d626572466f723c543e0001246578745f696e6465786502010c753332000540a052656d6f76657320612070726576696f75736c7920737061776e656420707572652070726f78792e0049015741524e494e473a202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20416e792066756e64732068656c6420696e2069742077696c6c20626534696e61636365737369626c652e0059015265717569726573206120605369676e656460206f726967696e2c20616e64207468652073656e646572206163636f756e74206d7573742068617665206265656e206372656174656420627920612063616c6c20746f94607075726560207769746820636f72726573706f6e64696e6720706172616d65746572732e0039012d2060737061776e6572603a20546865206163636f756e742074686174206f726967696e616c6c792063616c6c65642060707572656020746f206372656174652074686973206163636f756e742e39012d2060696e646578603a2054686520646973616d626967756174696f6e20696e646578206f726967696e616c6c792070617373656420746f206070757265602e2050726f6261626c79206030602eec2d206070726f78795f74797065603a205468652070726f78792074797065206f726967696e616c6c792070617373656420746f206070757265602e29012d2060686569676874603a2054686520686569676874206f662074686520636861696e207768656e207468652063616c6c20746f20607075726560207761732070726f6365737365642e35012d20606578745f696e646578603a205468652065787472696e73696320696e64657820696e207768696368207468652063616c6c20746f20607075726560207761732070726f6365737365642e0035014661696c73207769746820604e6f5065726d697373696f6e6020696e2063617365207468652063616c6c6572206973206e6f7420612070726576696f75736c7920637265617465642070757265dc6163636f756e742077686f7365206070757265602063616c6c2068617320636f72726573706f6e64696e6720706172616d65746572732e20616e6e6f756e63650801107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e00063c05015075626c697368207468652068617368206f6620612070726f78792d63616c6c20746861742077696c6c206265206d61646520696e20746865206675747572652e005d0154686973206d7573742062652063616c6c656420736f6d65206e756d626572206f6620626c6f636b73206265666f72652074686520636f72726573706f6e64696e67206070726f78796020697320617474656d7074656425016966207468652064656c6179206173736f6369617465642077697468207468652070726f78792072656c6174696f6e736869702069732067726561746572207468616e207a65726f2e0011014e6f206d6f7265207468616e20604d617850656e64696e676020616e6e6f756e63656d656e7473206d6179206265206d61646520617420616e79206f6e652074696d652e000901546869732077696c6c2074616b652061206465706f736974206f662060416e6e6f756e63656d656e744465706f736974466163746f72602061732077656c6c206173190160416e6e6f756e63656d656e744465706f736974426173656020696620746865726520617265206e6f206f746865722070656e64696e6720616e6e6f756e63656d656e74732e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420612070726f7879206f6620607265616c602e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656d6f76655f616e6e6f756e63656d656e740801107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e0007287052656d6f7665206120676976656e20616e6e6f756e63656d656e742e0059014d61792062652063616c6c656420627920612070726f7879206163636f756e7420746f2072656d6f766520612063616c6c20746865792070726576696f75736c7920616e6e6f756e63656420616e642072657475726e30746865206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656a6563745f616e6e6f756e63656d656e7408012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e000828b052656d6f76652074686520676976656e20616e6e6f756e63656d656e74206f6620612064656c65676174652e0061014d61792062652063616c6c6564206279206120746172676574202870726f7869656429206163636f756e7420746f2072656d6f766520612063616c6c2074686174206f6e65206f662074686569722064656c6567617465732501286064656c656761746560292068617320616e6e6f756e63656420746865792077616e7420746f20657865637574652e20546865206465706f7369742069732072657475726e65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733af42d206064656c6567617465603a20546865206163636f756e7420746861742070726576696f75736c7920616e6e6f756e636564207468652063616c6c2ebc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652e3c70726f78795f616e6e6f756e63656410012064656c6567617465c10201504163636f756e7449644c6f6f6b75704f663c543e0001107265616cc10201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065fd0501504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cb902017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00092c4d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f72697a656420666f72207468726f75676830606164645f70726f7879602e00a852656d6f76657320616e7920636f72726573706f6e64696e6720616e6e6f756e63656d656e742873292e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732efd0504184f7074696f6e04045401e5010108104e6f6e6500000010536f6d650400e501000001000001060c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c65741043616c6c04045400015c386a6f696e5f6f70657261746f727304012c626f6e645f616d6f756e7418013042616c616e63654f663c543e00003c3501416c6c6f777320616e206163636f756e7420746f206a6f696e20617320616e206f70657261746f72206279207374616b696e672074686520726571756972656420626f6e6420616d6f756e742e003423205065726d697373696f6e7300cc2a204d757374206265207369676e656420627920746865206163636f756e74206a6f696e696e67206173206f70657261746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cc82a2060626f6e645f616d6f756e7460202d20416d6f756e7420746f207374616b65206173206f70657261746f7220626f6e64002023204572726f72730029012a205b604572726f723a3a4465706f7369744f766572666c6f77605d202d20426f6e6420616d6f756e7420776f756c64206f766572666c6f77206465706f73697420747261636b696e6719012a205b604572726f723a3a5374616b654f766572666c6f77605d202d20426f6e6420616d6f756e7420776f756c64206f766572666c6f77207374616b6520747261636b696e67607363686564756c655f6c656176655f6f70657261746f7273000138a85363686564756c657320616e206f70657261746f7220746f206c65617665207468652073797374656d2e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7265012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d204f70657261746f7220616c72656164792068617320612070656e64696e6720756e7374616b6520726571756573745863616e63656c5f6c656176655f6f70657261746f7273000238a843616e63656c732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b652072657175657374206578697374735c657865637574655f6c656176655f6f70657261746f727300033cac45786563757465732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747325012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c617073656420796574486f70657261746f725f626f6e645f6d6f726504013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00043cac416c6c6f777320616e206f70657261746f7220746f20696e637265617365207468656972207374616b652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cc02a20606164646974696f6e616c5f626f6e6460202d204164646974696f6e616c20616d6f756e7420746f207374616b65002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7229012a205b604572726f723a3a5374616b654f766572666c6f77605d202d204164646974696f6e616c20626f6e6420776f756c64206f766572666c6f77207374616b6520747261636b696e67647363686564756c655f6f70657261746f725f756e7374616b65040138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000540b85363686564756c657320616e206f70657261746f7220746f206465637265617365207468656972207374616b652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a2060756e7374616b655f616d6f756e7460202d20416d6f756e7420746f20756e7374616b65002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7265012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d204f70657261746f7220616c72656164792068617320612070656e64696e6720756e7374616b65207265717565737435012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d204f70657261746f722068617320696e73756666696369656e74207374616b6520746f20756e7374616b6560657865637574655f6f70657261746f725f756e7374616b6500063cd045786563757465732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747325012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c6170736564207965745c63616e63656c5f6f70657261746f725f756e7374616b65000738cc43616e63656c732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747328676f5f6f66666c696e6500083884416c6c6f777320616e206f70657261746f7220746f20676f206f66666c696e652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f72e42a205b604572726f723a3a416c72656164794f66666c696e65605d202d204f70657261746f7220697320616c7265616479206f66666c696e6524676f5f6f6e6c696e6500093880416c6c6f777320616e206f70657261746f7220746f20676f206f6e6c696e652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f72dc2a205b604572726f723a3a416c72656164794f6e6c696e65605d202d204f70657261746f7220697320616c7265616479206f6e6c696e651c6465706f7369740c012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00012c65766d5f61646472657373050601304f7074696f6e3c483136303e000a4488416c6c6f77732061207573657220746f206465706f73697420616e2061737365742e003423205065726d697373696f6e7300a42a204d757374206265207369676e656420627920746865206465706f7369746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca42a206061737365745f696460202d204944206f662074686520617373657420746f206465706f736974782a2060616d6f756e7460202d20416d6f756e7420746f206465706f736974982a206065766d5f6164647265737360202d204f7074696f6e616c2045564d2061646472657373002023204572726f727300f82a205b604572726f723a3a4465706f7369744f766572666c6f77605d202d204465706f73697420776f756c64206f766572666c6f7720747261636b696e67c82a205b604572726f723a3a496e76616c69644173736574605d202d204173736574206973206e6f7420737570706f72746564447363686564756c655f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000b40745363686564756c6573206120776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca82a206061737365745f696460202d204944206f662074686520617373657420746f2077697468647261777c2a2060616d6f756e7460202d20416d6f756e7420746f207769746864726177002023204572726f7273000d012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d20496e73756666696369656e742062616c616e636520746f2077697468647261772d012a205b604572726f723a3a50656e64696e67576974686472617752657175657374457869737473605d202d2050656e64696e6720776974686472617720726571756573742065786973747340657865637574655f776974686472617704012c65766d5f61646472657373050601304f7074696f6e3c483136303e000c3c9845786563757465732061207363686564756c656420776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a206065766d5f6164647265737360202d204f7074696f6e616c2045564d2061646472657373002023204572726f72730025012a205b604572726f723a3a4e6f576974686472617752657175657374457869737473605d202d204e6f2070656e64696e672077697468647261772072657175657374206578697374731d012a205b604572726f723a3a5769746864726177506572696f644e6f74456c6170736564605d202d20576974686472617720706572696f6420686173206e6f7420656c61707365643c63616e63656c5f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000d3c9443616e63656c732061207363686564756c656420776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ccc2a206061737365745f696460202d204944206f6620746865206173736574207769746864726177616c20746f2063616e63656cbc2a2060616d6f756e7460202d20416d6f756e74206f6620746865207769746864726177616c20746f2063616e63656c002023204572726f72730025012a205b604572726f723a3a4e6f576974686472617752657175657374457869737473605d202d204e6f2070656e64696e672077697468647261772072657175657374206578697374732064656c65676174651001206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00014c626c75657072696e745f73656c656374696f6e090601d844656c656761746f72426c75657072696e7453656c656374696f6e3c543a3a4d617844656c656761746f72426c75657072696e74733e000e4cfc416c6c6f77732061207573657220746f2064656c656761746520616e20616d6f756e74206f6620616e20617373657420746f20616e206f70657261746f722e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a20606f70657261746f7260202d204f70657261746f7220746f2064656c656761746520746f982a206061737365745f696460202d204944206f6620617373657420746f2064656c65676174657c2a2060616d6f756e7460202d20416d6f756e7420746f2064656c6567617465d82a2060626c75657072696e745f73656c656374696f6e60202d20426c75657072696e742073656c656374696f6e207374726174656779002023204572726f727300f02a205b604572726f723a3a4e6f744f70657261746f72605d202d20546172676574206163636f756e74206973206e6f7420616e206f70657261746f720d012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d20496e73756666696369656e742062616c616e636520746f2064656c656761746509012a205b604572726f723a3a4d617844656c65676174696f6e734578636565646564605d202d20576f756c6420657863656564206d61782064656c65676174696f6e73687363686564756c655f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000f48c85363686564756c65732061207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c9c2a20606f70657261746f7260202d204f70657261746f7220746f20756e7374616b652066726f6d942a206061737365745f696460202d204944206f6620617373657420746f20756e7374616b65782a2060616d6f756e7460202d20416d6f756e7420746f20756e7374616b65002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f7221012a205b604572726f723a3a496e73756666696369656e7444656c65676174696f6e605d202d20496e73756666696369656e742064656c65676174696f6e20746f20756e7374616b6525012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d2050656e64696e6720756e7374616b6520726571756573742065786973747364657865637574655f64656c656761746f725f756e7374616b6500103cec45786563757465732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747315012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c61707365646063616e63656c5f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e001144e843616e63656c732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb82a20606f70657261746f7260202d204f70657261746f7220746f2063616e63656c20756e7374616b652066726f6db02a206061737365745f696460202d204944206f6620617373657420756e7374616b6520746f2063616e63656ca02a2060616d6f756e7460202d20416d6f756e74206f6620756e7374616b6520746f2063616e63656c002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b65207265717565737420657869737473647365745f696e63656e746976655f6170795f616e645f6361700c01207661756c745f6964180128543a3a5661756c74496400010c617079f501014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e001244a853657473207468652041505920616e642063617020666f7220612073706563696669632061737365742e003423205065726d697373696f6e7300902a204d7573742062652063616c6c65642062792074686520666f726365206f726967696e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c782a20607661756c745f696460202d204944206f6620746865207661756c74ac2a206061707960202d20416e6e75616c2070657263656e74616765207969656c6420286d61782031302529b82a206063617060202d205265717569726564206465706f73697420616d6f756e7420666f722066756c6c20415059002023204572726f727300e02a205b604572726f723a3a415059457863656564734d6178696d756d605d202d20415059206578636565647320313025206d6178696d756de02a205b604572726f723a3a43617043616e6e6f7442655a65726f605d202d2043617020616d6f756e742063616e6e6f74206265207a65726f7c77686974656c6973745f626c75657072696e745f666f725f72657761726473040130626c75657072696e745f696430012c426c75657072696e7449640013288c57686974656c69737473206120626c75657072696e7420666f7220726577617264732e003423205065726d697373696f6e7300902a204d7573742062652063616c6c65642062792074686520666f726365206f726967696e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cbc2a2060626c75657072696e745f696460202d204944206f6620626c75657072696e7420746f2077686974656c697374546d616e6167655f61737365745f696e5f7661756c740c01207661756c745f6964180128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6ef901012c4173736574416374696f6e001444844d616e61676520617373657420696420746f207661756c7420726577617264732e003423205065726d697373696f6e7300a42a204d757374206265207369676e656420627920616e20617574686f72697a6564206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c782a20607661756c745f696460202d204944206f6620746865207661756c74782a206061737365745f696460202d204944206f6620746865206173736574ac2a2060616374696f6e60202d20416374696f6e20746f20706572666f726d20284164642f52656d6f766529002023204572726f72730001012a205b604572726f723a3a4173736574416c7265616479496e5661756c74605d202d20417373657420616c72656164792065786973747320696e207661756c74f02a205b604572726f723a3a41737365744e6f74496e5661756c74605d202d20417373657420646f6573206e6f7420657869737420696e207661756c74406164645f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001644bc41646473206120626c75657072696e7420494420746f20612064656c656761746f7227732073656c656374696f6e2e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca42a2060626c75657072696e745f696460202d204944206f6620626c75657072696e7420746f20616464002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f72fc2a205b604572726f723a3a4475706c6963617465426c75657072696e744964605d202d20426c75657072696e7420494420616c72656164792065786973747301012a205b604572726f723a3a4d6178426c75657072696e74734578636565646564605d202d20576f756c6420657863656564206d617820626c75657072696e74730d012a205b604572726f723a3a4e6f74496e46697865644d6f6465605d202d204e6f7420696e20666978656420626c75657072696e742073656c656374696f6e206d6f64654c72656d6f76655f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001740d052656d6f766573206120626c75657072696e742049442066726f6d20612064656c656761746f7227732073656c656374696f6e2e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb02a2060626c75657072696e745f696460202d204944206f6620626c75657072696e7420746f2072656d6f7665002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f72e42a205b604572726f723a3a426c75657072696e7449644e6f74466f756e64605d202d20426c75657072696e74204944206e6f7420666f756e640d012a205b604572726f723a3a4e6f74496e46697865644d6f6465605d202d204e6f7420696e20666978656420626c75657072696e742073656c656374696f6e206d6f646504c85468652063616c6c61626c652066756e6374696f6e73202865787472696e7369637329206f66207468652070616c6c65742e050604184f7074696f6e0404540191010108104e6f6e6500000010536f6d650400910100000100000906107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f726c44656c656761746f72426c75657072696e7453656c656374696f6e04344d6178426c75657072696e7473010d060108144669786564040011060198426f756e6465645665633c426c75657072696e7449642c204d6178426c75657072696e74733e0000000c416c6c000100000d06085874616e676c655f746573746e65745f72756e74696d65584d617844656c656761746f72426c75657072696e74730000000011060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540130045300000400150601185665633c543e00001506000002300019060c3c70616c6c65745f7365727669636573186d6f64756c651043616c6c040454000138406372656174655f626c75657072696e74040124626c75657072696e741d06018053657276696365426c75657072696e743c543a3a436f6e73747261696e74733e0000707c4372656174652061206e6577207365727669636520626c75657072696e742e00810141205365727669636520426c75657072696e7420697320612074656d706c61746520666f722061207365727669636520746861742063616e20626520696e7374616e7469617465642062792075736572732e2054686520626c75657072696e749101646566696e6573207468652073657276696365277320636f6e73747261696e74732c20726571756972656d656e747320616e64206265686176696f722c20696e636c7564696e6720746865206d617374657220626c75657072696e742073657276696365606d616e61676572207265766973696f6e20746f207573652e003423205065726d697373696f6e730019012a20546865206f726967696e206d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206f776e2074686520626c75657072696e74002c2320417267756d656e74730065012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d757374206265207369676e656420627920746865206163636f756e74206372656174696e672074686520626c75657072696e74c42a2060626c75657072696e7460202d20546865207365727669636520626c75657072696e7420636f6e7461696e696e673aa020202d205365727669636520636f6e73747261696e747320616e6420726571756972656d656e7473090120202d204d617374657220626c75657072696e742073657276696365206d616e61676572207265766973696f6e20284c6174657374206f7220537065636966696329d020202d2054656d706c61746520636f6e66696775726174696f6e20666f72207365727669636520696e7374616e74696174696f6e002023204572726f727300b42a205b604572726f723a3a4261644f726967696e605d202d204f726967696e206973206e6f74207369676e65648d012a205b604572726f723a3a4d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64605d202d20537065636966696564204d42534d207265766973696f6e20646f6573206e6f7420657869737459012a205b604572726f723a3a426c75657072696e744372656174696f6e496e746572727570746564605d202d20426c75657072696e74206372656174696f6e20697320696e74657272757074656420627920686f6f6b730024232052657475726e7300850152657475726e73206120604469737061746368526573756c7457697468506f7374496e666f60207768696368206f6e207375636365737320656d6974732061205b604576656e743a3a426c75657072696e7443726561746564605d206576656e7498636f6e7461696e696e6720746865206f776e657220616e6420626c75657072696e742049442e307072655f7265676973746572040130626c75657072696e745f69642c010c75363400017801015072652d7265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e008901546869732066756e6374696f6e20616c6c6f777320616e206163636f756e7420746f207369676e616c20696e74656e7420746f206265636f6d6520616e206f70657261746f7220666f72206120626c75657072696e7420627920656d697474696e677101612060507265526567697374726174696f6e60206576656e742e20546865206f70657261746f72206e6f64652063616e206c697374656e20666f722074686973206576656e7420746f206578656375746520616e7920637573746f6db0726567697374726174696f6e206c6f67696320646566696e656420696e2074686520626c75657072696e742e0071015072652d726567697374726174696f6e20697320746865206669727374207374657020696e20746865206f70657261746f7220726567697374726174696f6e20666c6f772e204166746572207072652d7265676973746572696e672c91016f70657261746f7273206d75737420636f6d706c657465207468652066756c6c20726567697374726174696f6e2070726f636573732062792063616c6c696e6720607265676973746572282960207769746820746865697220707265666572656e6365736c616e6420726567697374726174696f6e20617267756d656e74732e002c2320417267756d656e74730079012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920746865206163636f756e7420746861742077616e747320746f5420206265636f6d6520616e206f70657261746f722e7d012a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f207072652d726567697374657220666f722e204d7573742072656665726c2020746f20616e206578697374696e6720626c75657072696e742e003423205065726d697373696f6e7300982a205468652063616c6c6572206d7573742062652061207369676e6564206163636f756e742e002023204576656e7473005d012a205b604576656e743a3a507265526567697374726174696f6e605d202d20456d6974746564207768656e207072652d726567697374726174696f6e206973207375636365737366756c2c20636f6e7461696e696e673a350120202d20606f70657261746f723a20543a3a4163636f756e74496460202d20546865206163636f756e74204944206f6620746865207072652d7265676973746572696e67206f70657261746f72290120202d2060626c75657072696e745f69643a2075363460202d20546865204944206f662074686520626c75657072696e74206265696e67207072652d7265676973746572656420666f72002023204572726f727300cc2a205b604572726f723a3a4261644f726967696e605d202d20546865206f726967696e20776173206e6f74207369676e65642e207265676973746572100130626c75657072696e745f69642c010c75363400012c707265666572656e6365730102014c4f70657261746f72507265666572656e636573000144726567697374726174696f6e5f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e00011476616c75656d01013042616c616e63654f663c543e00026cf05265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e007501546869732066756e6374696f6e20616c6c6f777320616e206163636f756e7420746f20726567697374657220617320616e206f70657261746f7220666f72206120626c75657072696e742062792070726f766964696e672074686569727d017365727669636520707265666572656e6365732c20726567697374726174696f6e20617267756d656e74732c20616e64207374616b696e672074686520726571756972656420746f6b656e732e20546865206f70657261746f72206d757374790162652061637469766520696e207468652064656c65676174696f6e2073797374656d20616e64206d6179207265717569726520617070726f76616c206265666f726520616363657074696e6720736572766963652072657175657374732e003423205065726d697373696f6e7300942a205468652063616c6c6572206d7573742062652061207369676e6564206163636f756e7401012a205468652063616c6c6572206d75737420626520616e20616374697665206f70657261746f7220696e207468652064656c65676174696f6e2073797374656df82a205468652063616c6c6572206d757374206e6f7420616c7265616479206265207265676973746572656420666f72207468697320626c75657072696e74002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e29012a2060626c75657072696e745f696460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f20726567697374657220666f7219012a2060707265666572656e63657360202d20546865206f70657261746f722773207365727669636520707265666572656e63657320616e6420636f6e66696775726174696f6e21012a2060726567697374726174696f6e5f6172677360202d20526567697374726174696f6e20617267756d656e74732072657175697265642062792074686520626c75657072696e74d82a206076616c756560202d20416d6f756e74206f6620746f6b656e7320746f207374616b6520666f7220726567697374726174696f6e002023204572726f72730069012a205b604572726f723a3a4f70657261746f724e6f74416374697665605d202d2043616c6c6572206973206e6f7420616e20616374697665206f70657261746f7220696e207468652064656c65676174696f6e2073797374656d41012a205b604572726f723a3a416c726561647952656769737465726564605d202d2043616c6c657220697320616c7265616479207265676973746572656420666f72207468697320626c75657072696e7411012a205b604572726f723a3a54797065436865636b605d202d20526567697374726174696f6e20617267756d656e7473206661696c6564207479706520636865636b696e674d012a205b604572726f723a3a496e76616c6964526567697374726174696f6e496e707574605d202d20526567697374726174696f6e20686f6f6b2072656a65637465642074686520726567697374726174696f6e65012a205b604572726f723a3a4d6178536572766963657350657250726f76696465724578636565646564605d202d204f70657261746f72206861732072656163686564206d6178696d756d207365727669636573206c696d697428756e7265676973746572040130626c75657072696e745f69642c010c75363400034c0501556e726567697374657273206120736572766963652070726f76696465722066726f6d2061207370656369666963207365727669636520626c75657072696e742e009101416674657220756e7265676973746572696e672c207468652070726f76696465722077696c6c206e6f206c6f6e6765722072656365697665206e657720736572766963652061737369676e6d656e747320666f72207468697320626c75657072696e742e8501486f77657665722c2074686579206d75737420636f6e74696e756520736572766963696e6720616e79206163746976652061737369676e6d656e747320756e74696c20636f6d706c6574696f6e20746f2061766f69642070656e616c746965732e002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e39012a2060626c75657072696e745f696460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f20756e72656769737465722066726f6d2e003423205065726d697373696f6e7300c42a204d757374206265207369676e65642062792061207265676973746572656420736572766963652070726f7669646572002023204572726f72730031012a205b604572726f723a3a4e6f7452656769737465726564605d202d205468652063616c6c6572206973206e6f74207265676973746572656420666f72207468697320626c75657072696e7431012a205b604572726f723a3a4e6f74416c6c6f776564546f556e7265676973746572605d202d20556e726567697374726174696f6e2069732063757272656e746c79207265737472696374656401012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f74206578697374507570646174655f70726963655f74617267657473080130626c75657072696e745f69642c010c75363400013470726963655f746172676574730902013050726963655461726765747300045021015570646174657320746865207072696365207461726765747320666f7220612072656769737465726564206f70657261746f722773207365727669636520626c75657072696e742e008901416c6c6f777320616e206f70657261746f7220746f206d6f64696679207468656972207072696365207461726765747320666f72206120737065636966696320626c75657072696e74207468657920617265207265676973746572656420666f722e2d01546865206f70657261746f72206d75737420616c7265616479206265207265676973746572656420666f722074686520626c75657072696e7420746f20757064617465207072696365732e002c2320417267756d656e74730049012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920746865206f70657261746f722e51012a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f662074686520626c75657072696e7420746f20757064617465207072696365207461726765747320666f722e45012a206070726963655f746172676574733a2050726963655461726765747360202d20546865206e6577207072696365207461726765747320746f2073657420666f722074686520626c75657072696e742e003423205065726d697373696f6e7300f42a204d757374206265207369676e656420627920612072656769737465726564206f70657261746f7220666f72207468697320626c75657072696e742e002023204572726f72730035012a205b604572726f723a3a4e6f7452656769737465726564605d202d205468652063616c6c6572206973206e6f74207265676973746572656420666f72207468697320626c75657072696e742e71012a205b604572726f723a3a4e6f74416c6c6f776564546f557064617465507269636554617267657473605d202d205072696365207461726765742075706461746573206172652063757272656e746c7920726573747269637465642e05012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f742065786973742e1c7265717565737424012865766d5f6f726967696e050601304f7074696f6e3c483136303e000130626c75657072696e745f69642c010c7536340001447065726d69747465645f63616c6c6572733d0201445665633c543a3a4163636f756e7449643e0001246f70657261746f72733d0201445665633c543a3a4163636f756e7449643e000130726571756573745f617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0001186173736574734102013c5665633c543a3a417373657449643e00010c74746c2c0144426c6f636b4e756d626572466f723c543e0001347061796d656e745f6173736574f101014441737365743c543a3a417373657449643e00011476616c75656d01013042616c616e63654f663c543e0005700101526571756573742061206e65772073657276696365207573696e67206120626c75657072696e7420616e6420737065636966696564206f70657261746f72732e002c2320417267756d656e74730009012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e1d012a206065766d5f6f726967696e3a204f7074696f6e3c483136303e60202d204f7074696f6e616c2045564d206164647265737320666f72204552433230207061796d656e74732efc2a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f662074686520626c75657072696e7420746f207573652ebd012a20607065726d69747465645f63616c6c6572733a205665633c543a3a4163636f756e7449643e60202d204163636f756e747320616c6c6f77656420746f2063616c6c2074686520736572766963652e20496620656d7074792c206f6e6c79206f776e65722063616e2063616c6c2e3d012a20606f70657261746f72733a205665633c543a3a4163636f756e7449643e60202d204c697374206f66206f70657261746f727320746861742077696c6c2072756e2074686520736572766963652e81012a2060726571756573745f617267733a205665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e60202d20426c75657072696e7420696e697469616c697a6174696f6e20617267756d656e74732ef82a20606173736574733a205665633c543a3a417373657449643e60202d2052657175697265642061737365747320666f722074686520736572766963652e31012a206074746c3a20426c6f636b4e756d626572466f723c543e60202d2054696d652d746f2d6c69766520696e20626c6f636b7320666f7220746865207365727669636520726571756573742e61012a20607061796d656e745f61737365743a2041737365743c543a3a417373657449643e60202d204173736574207573656420666f72207061796d656e7420286e61746976652c20637573746f6d206f72204552433230292ee42a206076616c75653a2042616c616e63654f663c543e60202d205061796d656e7420616d6f756e7420666f722074686520736572766963652e003423205065726d697373696f6e730039012a204d757374206265207369676e656420627920616e206163636f756e7420776974682073756666696369656e742062616c616e636520746f2070617920666f722074686520736572766963652e31012a20466f72204552433230207061796d656e74732c207468652045564d206f726967696e206d757374206d61746368207468652063616c6c65722773206d6170706564206163636f756e742e002023204572726f72730021012a205b604572726f723a3a54797065436865636b605d202d205265717565737420617267756d656e7473206661696c20626c75657072696e74207479706520636865636b696e672ee42a205b604572726f723a3a4e6f41737365747350726f7669646564605d202d204e6f206173736574732077657265207370656369666965642e5d012a205b604572726f723a3a4d697373696e6745564d4f726967696e605d202d2045564d206f726967696e20726571756972656420627574206e6f742070726f766964656420666f72204552433230207061796d656e742efc2a205b604572726f723a3a45524332305472616e736665724661696c6564605d202d20455243323020746f6b656e207472616e73666572206661696c65642e41012a205b604572726f723a3a4e6f7452656769737465726564605d202d204f6e65206f72206d6f7265206f70657261746f7273206e6f74207265676973746572656420666f7220626c75657072696e742e05012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f742065786973742e1c617070726f7665080128726571756573745f69642c010c75363400014472657374616b696e675f70657263656e74e106011c50657263656e740006448101417070726f76652061207365727669636520726571756573742c20616c6c6f77696e6720697420746f20626520696e69746961746564206f6e636520616c6c20726571756972656420617070726f76616c73206172652072656365697665642e003423205065726d697373696f6e730001012a2043616c6c6572206d75737420626520612072656769737465726564206f70657261746f7220666f7220746865207365727669636520626c75657072696e74fc2a2043616c6c6572206d75737420626520696e207468652070656e64696e6720617070726f76616c73206c69737420666f7220746869732072657175657374002c2320417267756d656e747300f42a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d7573742062652061207369676e6564206163636f756e74e42a2060726571756573745f696460202d20546865204944206f66207468652073657276696365207265717565737420746f20617070726f766555012a206072657374616b696e675f70657263656e7460202d2050657263656e74616765206f66207374616b656420746f6b656e7320746f206578706f736520746f207468697320736572766963652028302d31303029002023204572726f7273003d012a205b604572726f723a3a417070726f76616c4e6f74526571756573746564605d202d2043616c6c6572206973206e6f7420696e207468652070656e64696e6720617070726f76616c73206c69737429012a205b604572726f723a3a417070726f76616c496e746572727570746564605d202d20417070726f76616c207761732072656a656374656420627920626c75657072696e7420686f6f6b1872656a656374040128726571756573745f69642c010c753634000750d052656a6563742061207365727669636520726571756573742c2070726576656e74696e672069747320696e6974696174696f6e2e006101546865207365727669636520726571756573742077696c6c2072656d61696e20696e207468652073797374656d20627574206d61726b65642061732072656a65637465642e20546865207265717565737465722077696c6cb86e65656420746f20757064617465207468652073657276696365207265717565737420746f2070726f636565642e003423205065726d697373696f6e730055012a2043616c6c6572206d75737420626520612072656769737465726564206f70657261746f7220666f722074686520626c75657072696e74206173736f63696174656420776974682074686973207265717565737419012a2043616c6c6572206d757374206265206f6e65206f6620746865206f70657261746f727320726571756972656420746f20617070726f766520746869732072657175657374002c2320417267756d656e747300f42a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d7573742062652061207369676e6564206163636f756e74e02a2060726571756573745f696460202d20546865204944206f66207468652073657276696365207265717565737420746f2072656a656374002023204572726f7273009d012a205b604572726f723a3a417070726f76616c4e6f74526571756573746564605d202d2043616c6c6572206973206e6f74206f6e65206f6620746865206f70657261746f727320726571756972656420746f20617070726f76652074686973207265717565737499012a205b604572726f723a3a45787065637465644163636f756e744964605d202d204661696c656420746f20636f6e7665727420726566756e64206164647265737320746f206163636f756e74204944207768656e20726566756e64696e67207061796d656e743d012a205b604572726f723a3a52656a656374696f6e496e746572727570746564605d202d2052656a656374696f6e2077617320696e74657272757074656420627920626c75657072696e7420686f6f6b247465726d696e617465040128736572766963655f69642c010c753634000844985465726d696e6174657320612072756e6e696e67207365727669636520696e7374616e63652e003423205065726d697373696f6e7300942a204d757374206265207369676e6564206279207468652073657276696365206f776e6572002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6cec2a2060736572766963655f696460202d20546865206964656e746966696572206f6620746865207365727669636520746f207465726d696e617465002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374f02a205b604572726f723a3a4e6f7452656769737465726564605d202d2053657276696365206f70657261746f72206e6f74207265676973746572656449012a205b604572726f723a3a5465726d696e6174696f6e496e746572727570746564605d202d2053657276696365207465726d696e6174696f6e2077617320696e74657272757074656420627920686f6f6b7301012a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f74207468652073657276696365206f776e65721063616c6c0c0128736572766963655f69642c010c75363400010c6a6f62e50601087538000110617267730d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000954d843616c6c2061206a6f6220696e2074686520736572766963652077697468207468652070726f766964656420617267756d656e74732e003423205065726d697373696f6e7300ec2a204d757374206265207369676e6564206279207468652073657276696365206f776e6572206f722061207065726d69747465642063616c6c6572002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c9c2a2060736572766963655f696460202d205468652073657276696365206964656e7469666965727c2a20606a6f6260202d20546865206a6f6220696e64657820746f2063616c6cac2a20606172677360202d2054686520617267756d656e747320746f207061737320746f20746865206a6f62002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374f42a205b604572726f723a3a4a6f62446566696e6974696f6e4e6f74466f756e64605d202d20546865206a6f6220696e64657820697320696e76616c6964f02a205b604572726f723a3a4d61784669656c64734578636565646564605d202d20546f6f206d616e7920617267756d656e74732070726f7669646564d42a205b604572726f723a3a54797065436865636b605d202d20417267756d656e7473206661696c207479706520636865636b696e6705012a205b604572726f723a3a496e76616c69644a6f6243616c6c496e707574605d202d204a6f622063616c6c207761732072656a656374656420627920686f6f6b7321012a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f74206f776e6572206f72207065726d69747465642063616c6c6572347375626d69745f726573756c740c0128736572766963655f69642c010c75363400011c63616c6c5f69642c010c753634000118726573756c740d0201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000a54b05375626d6974206120726573756c7420666f7220612070726576696f75736c792063616c6c6564206a6f622e002c2320417267756d656e747300882a2060736572766963655f696460202d204944206f66207468652073657276696365802a206063616c6c5f696460202d204944206f6620746865206a6f622063616c6c902a2060726573756c7460202d20566563746f72206f6620726573756c74206669656c6473003423205065726d697373696f6e7300ac2a2043616c6c6572206d75737420626520616e206f70657261746f72206f66207468652073657276696365002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374e42a205b604572726f723a3a4a6f6243616c6c4e6f74466f756e64605d202d205468652063616c6c5f696420646f6573206e6f74206578697374f42a205b604572726f723a3a4a6f62446566696e6974696f6e4e6f74466f756e64605d202d20546865206a6f6220696e64657820697320696e76616c696401012a205b604572726f723a3a4d61784669656c64734578636565646564605d202d20546f6f206d616e7920726573756c74206669656c64732070726f7669646564e42a205b604572726f723a3a54797065436865636b605d202d20526573756c74206669656c6473206661696c207479706520636865636b696e6701012a205b604572726f723a3a496e76616c69644a6f62526573756c74605d202d204a6f6220726573756c74207761732072656a656374656420627920686f6f6b73e82a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f7420616e206f70657261746f7214736c6173680c01206f6666656e646572000130543a3a4163636f756e744964000128736572766963655f69642c010c75363400011c70657263656e74e106011c50657263656e74000b604501536c61736820616e206f70657261746f722773207374616b6520666f7220612073657276696365206279207363686564756c696e67206120646566657272656420736c617368696e6720616374696f6e2e009901546869732066756e6374696f6e207363686564756c6573206120646566657272656420736c617368696e6720616374696f6e20616761696e737420616e206f70657261746f722773207374616b6520666f72206120737065636966696320736572766963652e7d0154686520736c617368206973206e6f74206170706c69656420696d6d6564696174656c792c20627574207261746865722071756575656420746f20626520657865637574656420627920616e6f7468657220656e74697479206c617465722e003423205065726d697373696f6e730061012a205468652063616c6c6572206d75737420626520616e20617574686f72697a656420536c617368204f726967696e20666f72207468652074617267657420736572766963652c2061732064657465726d696e65642062797d0120206071756572795f736c617368696e675f6f726967696e602e204966206e6f20736c617368696e67206f726967696e206973207365742c206f72207468652063616c6c657220646f6573206e6f74206d617463682c207468652063616c6c30202077696c6c206661696c2e002c2320417267756d656e74730049012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e20617574686f72697a656420536c617368204f726967696e2ef02a20606f6666656e64657260202d20546865206163636f756e74204944206f6620746865206f70657261746f7220746f20626520736c61736865642e1d012a2060736572766963655f696460202d20546865204944206f6620746865207365727669636520666f7220776869636820746f20736c61736820746865206f70657261746f722e71012a206070657263656e7460202d205468652070657263656e74616765206f6620746865206f70657261746f722773206578706f736564207374616b6520746f20736c6173682c2061732061206050657263656e74602076616c75652e002023204572726f72730001012a20604e6f536c617368696e674f726967696e60202d204e6f20736c617368696e67206f726967696e2069732073657420666f72207468652073657276696365f02a20604261644f726967696e60202d2043616c6c6572206973206e6f742074686520617574686f72697a656420736c617368696e67206f726967696e31012a20604f6666656e6465724e6f744f70657261746f7260202d20546172676574206163636f756e74206973206e6f7420616e206f70657261746f7220666f72207468697320736572766963651d012a20604f6666656e6465724e6f744163746976654f70657261746f7260202d20546172676574206f70657261746f72206973206e6f742063757272656e746c79206163746976651c6469737075746508010c6572616502010c753332000114696e6465786502010c753332000c4cd8446973707574657320616e642072656d6f76657320616e205b556e6170706c696564536c6173685d2066726f6d2073746f726167652e001d0154686520736c6173682077696c6c206e6f74206265206170706c696564206f6e636520646973707574656420616e64206973207065726d616e656e746c792072656d6f7665642e003423205065726d697373696f6e7300f82a2043616c6c6572206d7573742062652074686520617574686f72697a65642064697370757465206f726967696e20666f72207468652073657276696365002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cbc2a206065726160202d2045726120636f6e7461696e696e672074686520736c61736820746f20646973707574652020b42a2060696e64657860202d20496e646578206f662074686520736c6173682077697468696e2074686520657261002023204572726f72730015012a205b4572726f723a3a4e6f446973707574654f726967696e5d202d205365727669636520686173206e6f2064697370757465206f726967696e20636f6e6669677572656429012a205b44697370617463684572726f723a3a4261644f726967696e5d202d2043616c6c6572206973206e6f742074686520617574686f72697a65642064697370757465206f726967696e009c7570646174655f6d61737465725f626c75657072696e745f736572766963655f6d616e6167657204011c616464726573739101011048313630000d3819015570646174657320746865204d617374657220426c75657072696e742053657276696365204d616e6167657220627920616464696e672061206e6577207265766973696f6e2e003423205065726d697373696f6e730035012a2043616c6c6572206d75737420626520616e20617574686f72697a6564204d617374657220426c75657072696e742053657276696365204d616e6167657220557064617465204f726967696e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca02a20606164647265737360202d204e6577206d616e61676572206164647265737320746f20616464002023204572726f72730085012a205b4572726f723a3a4d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e7345786365656465645d202d204d6178696d756d206e756d626572206f66207265766973696f6e732072656163686564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e1d060c4474616e676c655f7072696d6974697665732073657276696365734053657276696365426c75657072696e7404044300001c01206d6574616461746121060148536572766963654d657461646174613c433e0001106a6f6273310601c8426f756e6465645665633c4a6f62446566696e6974696f6e3c433e2c20433a3a4d61784a6f6273506572536572766963653e00014c726567697374726174696f6e5f706172616d733d06018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000138726571756573745f706172616d733d06018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e00011c6d616e616765725906015c426c75657072696e74536572766963654d616e6167657200015c6d61737465725f6d616e616765725f7265766973696f6e5d0601944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000118676164676574610601244761646765743c433e000021060c4474616e676c655f7072696d6974697665732073657276696365733c536572766963654d6574616461746104044300002001106e616d652506018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e2d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000118617574686f722d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00012063617465676f72792d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00013c636f64655f7265706f7369746f72792d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e0001106c6f676f2d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c776562736974652d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c6c6963656e73652d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00002506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040029060144426f756e6465645665633c75382c20533e000029060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00002d0604184f7074696f6e0404540125060108104e6f6e6500000010536f6d6504002506000001000031060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013506045300000400550601185665633c543e000035060c4474616e676c655f7072696d697469766573207365727669636573344a6f62446566696e6974696f6e04044300000c01206d65746164617461390601384a6f624d657461646174613c433e000118706172616d733d06018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000118726573756c743d06018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000039060c4474616e676c655f7072696d6974697665732073657276696365732c4a6f624d6574616461746104044300000801106e616d652506018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e2d0601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00003d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014106045300000400510601185665633c543e00004106104474616e676c655f7072696d697469766573207365727669636573146669656c64244669656c645479706500014410566f696400000010426f6f6c0001001455696e743800020010496e74380003001855696e74313600040014496e7431360005001855696e74333200060014496e7433320007001855696e74363400080014496e74363400090018537472696e67000a00144279746573000b00204f7074696f6e616c040041060138426f783c4669656c64547970653e000c00144172726179080030010c753634000041060138426f783c4669656c64547970653e000d00104c697374040041060138426f783c4669656c64547970653e000e0018537472756374080041060138426f783c4669656c64547970653e0000450601e8426f756e6465645665633c28426f783c4669656c64547970653e2c20426f783c4669656c64547970653e292c20436f6e73745533323c33323e3e000f00244163636f756e7449640064000045060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540149060453000004004d0601185665633c543e000049060000040841064106004d060000024906005106000002410600550600000235060059060c4474616e676c655f7072696d6974697665732073657276696365735c426c75657072696e74536572766963654d616e616765720001040c45766d04009101013473705f636f72653a3a48313630000000005d060c4474616e676c655f7072696d697469766573207365727669636573944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000108184c6174657374000000205370656369666963040010010c7533320001000061060c4474616e676c655f7072696d6974697665732073657276696365731847616467657404044300010c105761736d0400650601345761736d4761646765743c433e000000184e61746976650400d906013c4e61746976654761646765743c433e00010024436f6e7461696e65720400dd060148436f6e7461696e65724761646765743c433e0002000065060c4474616e676c655f7072696d697469766573207365727669636573285761736d476164676574040443000008011c72756e74696d656906012c5761736d52756e74696d6500011c736f75726365736d0601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e000069060c4474616e676c655f7072696d6974697665732073657276696365732c5761736d52756e74696d65000108205761736d74696d65000000185761736d6572000100006d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017106045300000400d50601185665633c543e000071060c4474616e676c655f7072696d69746976657320736572766963657330476164676574536f75726365040443000004011c6665746368657275060158476164676574536f75726365466574636865723c433e000075060c4474616e676c655f7072696d6974697665732073657276696365734c476164676574536f75726365466574636865720404430001101049504653040079060190426f756e6465645665633c75382c20433a3a4d617849706673486173684c656e6774683e0000001847697468756204007d060140476974687562466574636865723c433e00010038436f6e7461696e6572496d6167650400b506015c496d6167655265676973747279466574636865723c433e0002001c54657374696e670400d106013854657374466574636865723c433e0003000079060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00007d060c4474616e676c655f7072696d697469766573207365727669636573344769746875624665746368657204044300001001146f776e65728106018c426f756e646564537472696e673c433a3a4d61784769744f776e65724c656e6774683e0001107265706f89060188426f756e646564537472696e673c433a3a4d61784769745265706f4c656e6774683e00010c74616791060184426f756e646564537472696e673c433a3a4d61784769745461674c656e6774683e00012062696e6172696573990601d0426f756e6465645665633c47616467657442696e6172793c433e2c20433a3a4d617842696e61726965735065724761646765743e00008106104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040085060144426f756e6465645665633c75382c20533e000085060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00008906104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e67040453000004008d060144426f756e6465645665633c75382c20533e00008d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00009106104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040095060144426f756e6465645665633c75382c20533e000095060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000099060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019d06045300000400b10601185665633c543e00009d060c4474616e676c655f7072696d6974697665732073657276696365733047616467657442696e617279040443000010011061726368a10601304172636869746563747572650001086f73a506013c4f7065726174696e6753797374656d0001106e616d65a9060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e0001187368613235360401205b75383b2033325d0000a1060c4474616e676c655f7072696d69746976657320736572766963657330417263686974656374757265000128105761736d000000185761736d36340001001057617369000200185761736936340003000c416d6400040014416d6436340005000c41726d0006001441726d36340007001452697363560008001c5269736356363400090000a5060c4474616e676c655f7072696d6974697665732073657276696365733c4f7065726174696e6753797374656d0001141c556e6b6e6f776e000000144c696e75780001001c57696e646f7773000200144d61634f530003000c42534400040000a906104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400ad060144426f756e6465645665633c75382c20533e0000ad060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000b1060000029d0600b5060c4474616e676c655f7072696d69746976657320736572766963657350496d61676552656769737472794665746368657204044300000c01207265676973747279b90601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e657252656769737472794c656e6774683e000114696d616765c10601b4426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167654e616d654c656e6774683e00010c746167c90601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167655461674c656e6774683e0000b906104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400bd060144426f756e6465645665633c75382c20533e0000bd060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000c106104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c5060144426f756e6465645665633c75382c20533e0000c5060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000c906104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400cd060144426f756e6465645665633c75382c20533e0000cd060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000d1060c4474616e676c655f7072696d6974697665732073657276696365732c546573744665746368657204044300000c0134636172676f5f7061636b616765a9060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124636172676f5f62696ea9060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124626173655f706174682506018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e0000d506000002710600d9060c4474616e676c655f7072696d697469766573207365727669636573304e6174697665476164676574040443000004011c736f75726365736d0601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000dd060c4474616e676c655f7072696d6974697665732073657276696365733c436f6e7461696e6572476164676574040443000004011c736f75726365736d0601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000e106000006f50100e5060000060800e9060c4470616c6c65745f74616e676c655f6c73741870616c6c65741043616c6c040454000150106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c49640000585d015374616b65732066756e64732077697468206120706f6f6c206279207472616e7366657272696e672074686520626f6e64656420616d6f756e742066726f6d206d656d62657220746f20706f6f6c206163636f756e742e003423205065726d697373696f6e7300402a204d757374206265207369676e6564002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c702a2060616d6f756e7460202d20416d6f756e7420746f207374616b65702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944002023204572726f727300e82a205b604572726f723a3a4d696e696d756d426f6e644e6f744d6574605d202d20416d6f756e742062656c6f77206d696e696d756d20626f6e64bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374cc2a205b604572726f723a3a446566656e736976654572726f72605d202d2052657761726420706f6f6c206e6f7420666f756e64001823204e6f746500f02a204d656d626572206d757374206861766520606578697374656e7469616c206465706f736974202b20616d6f756e746020696e206163636f756e74ac2a20506f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a4f70656e605d20737461746528626f6e645f657874726108011c706f6f6c5f6964100118506f6f6c49640001146578747261ed06015c426f6e6445787472613c42616c616e63654f663c543e3e00016cd4426f6e64206164646974696f6e616c2066756e647320696e746f20616e206578697374696e6720706f6f6c20706f736974696f6e2e0029014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d2065697468657220667265652062616c616e6365206f7220616363756d756c6174656420726577617264732eac4175746f6d61746963616c6c792070617973206f757420616c6c2070656e64696e6720726577617264732e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944c42a2060657874726160202d20536f7572636520616e6420616d6f756e74206f66206164646974696f6e616c2066756e6473003423205065726d697373696f6e7300402a204d757374206265207369676e6564c02a204d7573742068617665207065726d697373696f6e20746f20626f6e64206578747261206966206e6f742073656c66002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f02a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b73207065726d697373696f6ecc2a205b604572726f723a3a446566656e736976654572726f72605d202d2052657761726420706f6f6c206e6f7420666f756e64001823204e6f74650031012a2054686973207472616e73616374696f6e207072696f726974697a657320726561646162696c69747920616e6420636f72726563746e657373206f766572206f7074696d697a6174696f6eec2a204d756c7469706c652073746f726167652072656164732f7772697465732061726520706572666f726d656420746f20726575736520636f646505012a205365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f66206f74686572206d656d6265727318756e626f6e640c01386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e0003743101556e626f6e6420706f696e74732066726f6d2061206d656d626572277320706f6f6c20706f736974696f6e2c20636f6c6c656374696e6720616e792070656e64696e6720726577617264732e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a20606d656d6265725f6163636f756e7460202d204163636f756e7420746f20756e626f6e642066726f6d702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944c42a2060756e626f6e64696e675f706f696e747360202d20416d6f756e74206f6620706f696e747320746f20756e626f6e64003423205065726d697373696f6e7300502a205065726d697373696f6e6c6573732069663ad420202d20506f6f6c20697320626c6f636b656420616e642063616c6c657220697320726f6f742f626f756e63657220286b69636b29c820202d20506f6f6c2069732064657374726f79696e6720616e64206d656d626572206973206e6f74206465706f7369746f72f820202d20506f6f6c2069732064657374726f79696e672c206d656d626572206973206465706f7369746f722c20616e6420706f6f6c20697320656d707479a82a205065726d697373696f6e6564202863616c6c6572206d757374206265206d656d626572292069663a6c20202d2043616c6c6572206973206e6f74206465706f7369746f72f820202d2043616c6c6572206973206465706f7369746f722c20706f6f6c2069732064657374726f79696e672c20616e6420706f6f6c20697320656d707479002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374fc2a205b604572726f723a3a4e6f42616c616e6365546f556e626f6e64605d202d204d656d6265722068617320696e73756666696369656e7420706f696e7473f42a205b604572726f723a3a446566656e736976654572726f72605d202d204e6f7420656e6f75676820737061636520696e20756e626f6e6420706f6f6c001823204e6f74656d014966206e6f20756e6c6f636b696e67206368756e6b732061726520617661696c61626c652c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c65642066697273742e6501546865207374616b696e6720696e746572666163652077696c6c20617474656d70742074686973206175746f6d61746963616c6c7920627574206d6179207374696c6c2072657475726e20604e6f4d6f72654368756e6b7360746966206368756e6b732063616e6e6f742062652072656c65617365642e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c75333200044ce457697468647261777320756e626f6e6465642066756e64732066726f6d2074686520706f6f6c2773207374616b696e67206163636f756e742e00390155736566756c20666f7220636c656172696e6720756e6c6f636b696e67206368756e6b73207768656e2074686572652061726520746f6f206d616e7920746f2063616c6c2060756e626f6e64602edc50726576656e747320604e6f4d6f72654368756e6b7360206572726f72732066726f6d20746865207374616b696e672073797374656d2e003423205065726d697373696f6e7300782a2043616e206265207369676e656420627920616e79206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572e82a20606e756d5f736c617368696e675f7370616e7360202d204e756d626572206f6620736c617368696e67207370616e7320746f20636865636b002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374e02a205b604572726f723a3a4e6f7444657374726f79696e67605d202d20506f6f6c20697320696e2064657374726f79696e672073746174654477697468647261775f756e626f6e6465640c01386d656d6265725f6163636f756e74c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000564b8576974686472617720756e626f6e6465642066756e64732066726f6d2061206d656d626572206163636f756e742e003423205065726d697373696f6e7300502a205065726d697373696f6e6c6573732069663adc20202d20506f6f6c20697320696e2064657374726f79206d6f646520616e6420746172676574206973206e6f74206465706f7369746f72d020202d20546172676574206973206465706f7369746f7220616e64206f6e6c79206d656d62657220696e2073756220706f6f6c73b820202d20506f6f6c20697320626c6f636b656420616e642063616c6c657220697320726f6f742f626f756e636572d02a205065726d697373696f6e65642069662063616c6c65722069732074617267657420616e64206e6f74206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb42a20606d656d6265725f6163636f756e7460202d204163636f756e7420746f2077697468647261772066726f6d742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572c42a20606e756d5f736c617368696e675f7370616e7360202d204e756d626572206f6620736c617368696e67207370616e73002023204572726f727300e82a205b604572726f723a3a506f6f6c4d656d6265724e6f74466f756e64605d202d204d656d626572206163636f756e74206e6f7420666f756e64bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374cc2a205b604572726f723a3a537562506f6f6c734e6f74466f756e64605d202d2053756220706f6f6c73206e6f7420666f756e64f02a205b604572726f723a3a43616e6e6f745769746864726177416e79605d202d204e6f20756e626f6e6465642066756e647320617661696c61626c6500bc496620746172676574206973206465706f7369746f722c20706f6f6c2077696c6c2062652064657374726f7965642e18637265617465180118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e0001106e616d65f10601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef90601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e00065c744372656174652061206e65772064656c65676174696f6e20706f6f6c2e003423205065726d697373696f6e730019012a204d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206265636f6d652074686520696e697469616c206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a2060616d6f756e7460202d20416d6f756e7420746f2064656c656761746520746f2074686520706f6f6c982a2060726f6f7460202d204163636f756e7420746f2073657420617320706f6f6c20726f6f74c02a20606e6f6d696e61746f7260202d204163636f756e7420746f2073657420617320706f6f6c206e6f6d696e61746f72b02a2060626f756e63657260202d204163636f756e7420746f2073657420617320706f6f6c20626f756e636572ec2a20606e616d6560202d204f7074696f6e616c20706f6f6c206e616d6520626f756e6465642062792060543a3a4d61784e616d654c656e67746860ec2a206069636f6e60202d204f7074696f6e616c20706f6f6c2069636f6e20626f756e6465642062792060543a3a4d617849636f6e4c656e67746860002023204572726f727300f02a205b604572726f723a3a4f766572666c6f775269736b605d202d20506f6f6c20494420696e6372656d656e7420776f756c64206f766572666c6f77001823204e6f7465000d0143616c6c6572206d75737420686176652060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652066756e64732e4c6372656174655f776974685f706f6f6c5f69641c0118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c10201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c10201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001106e616d65f10601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef90601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000764f04372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c2049442e003423205065726d697373696f6e7300f82a204d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206265636f6d6520746865206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a2060616d6f756e7460202d20416d6f756e7420746f2064656c656761746520746f2074686520706f6f6c982a2060726f6f7460202d204163636f756e7420746f2073657420617320706f6f6c20726f6f74c02a20606e6f6d696e61746f7260202d204163636f756e7420746f2073657420617320706f6f6c206e6f6d696e61746f72b02a2060626f756e63657260202d204163636f756e7420746f2073657420617320706f6f6c20626f756e636572782a2060706f6f6c5f696460202d20506f6f6c20494420746f207265757365742a20606e616d6560202d204f7074696f6e616c20706f6f6c206e616d65742a206069636f6e60202d204f7074696f6e616c20706f6f6c2069636f6e002023204572726f727300d02a205b604572726f723a3a506f6f6c4964496e557365605d202d20506f6f6c20494420697320616c726561647920696e2075736505012a205b604572726f723a3a496e76616c6964506f6f6c4964605d202d20506f6f6c2049442069732067726561746572207468616e206c61737420706f6f6c204944001823204e6f7465000d0143616c6c6572206d75737420686176652060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652066756e64732e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f72733d0201445665633c543a3a4163636f756e7449643e000850a84e6f6d696e6174652076616c696461746f7273206f6e20626568616c66206f662074686520706f6f6c2e003423205065726d697373696f6e7300d42a20506f6f6c206e6f6d696e61746f72206f7220726f6f7420726f6c652063616e206e6f6d696e6174652076616c696461746f7273002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572dc2a206076616c696461746f727360202d204c697374206f662076616c696461746f72206163636f756e747320746f206e6f6d696e617465002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f82a205b604572726f723a3a4e6f744e6f6d696e61746f72605d202d2043616c6c6572206c61636b73206e6f6d696e61746f72207065726d697373696f6e73001823204e6f7465001d01466f727761726473206e6f6d696e6174696f6e2063616c6c20746f207374616b696e672070616c6c6574207573696e6720706f6f6c277320626f6e646564206163636f756e742e247365745f737461746508011c706f6f6c5f6964100118506f6f6c4964000114737461746549020124506f6f6c537461746500095c59015570646174657320746865207374617465206f66206120706f6f6c2e204f6e6365206120706f6f6c20697320696e206044657374726f79696e67602073746174652c206974732073746174652063616e6e6f74206265986368616e67656420616761696e20756e64657220616e792063697263756d7374616e6365732e003423205065726d697373696f6e7300b42a20506f6f6c20626f756e636572206f7220726f6f7420726f6c652063616e2073657420616e7920737461746551012a20416e79206163636f756e742063616e2073657420737461746520746f206044657374726f79696e676020696620706f6f6c206661696c7320606f6b5f746f5f62655f6f70656e6020636f6e646974696f6e73002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572702a2060737461746560202d204e657720737461746520746f20736574002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737461012a205b604572726f723a3a43616e4e6f744368616e67655374617465605d202d20506f6f6c20697320696e2064657374726f79696e67207374617465206f722063616c6c6572206c61636b73207065726d697373696f6e73001823204e6f74650055015374617465206368616e676573206172652076616c696461746564207468726f75676820606f6b5f746f5f62655f6f70656e6020776869636820636865636b7320706f6f6c2070726f70657274696573206c696b658c636f6d6d697373696f6e2c206d656d62657220636f756e7420616e6420726f6c65732e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a44985570646174657320746865206d6574616461746120666f72206120676976656e20706f6f6c2e003423205065726d697373696f6e7300c42a204d7573742062652063616c6c65642062792074686520706f6f6c20626f756e636572206f7220726f6f7420726f6c65002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572882a20606d6574616461746160202d204e6577206d6574616461746120746f20736574002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737431012a205b604572726f723a3a4d65746164617461457863656564734d61784c656e605d202d204d65746164617461206c656e6774682065786365656473206d6178696d756d20616c6c6f77656419012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b73207265717569726564207065726d697373696f6e732c7365745f636f6e666967731001346d696e5f6a6f696e5f626f6e6401070158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6401070158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7305070134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e09070144436f6e6669674f703c50657262696c6c3e000b440501557064617465732074686520676c6f62616c20636f6e66696775726174696f6e20706172616d657465727320666f72206e6f6d696e6174696f6e20706f6f6c732e003423205065726d697373696f6e7300602a204d7573742062652063616c6c656420627920526f6f74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c11012a20606d696e5f6a6f696e5f626f6e6460202d20436f6e666967206f7065726174696f6e20666f72206d696e696d756d20626f6e6420746f206a6f696e206120706f6f6c29012a20606d696e5f6372656174655f626f6e6460202d20436f6e666967206f7065726174696f6e20666f72206d696e696d756d20626f6e6420746f20637265617465206120706f6f6c2020f02a20606d61785f706f6f6c7360202d20436f6e666967206f7065726174696f6e20666f72206d6178696d756d206e756d626572206f6620706f6f6c7329012a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20436f6e666967206f7065726174696f6e20666f72206d6178696d756d20676c6f62616c20636f6d6d697373696f6e002023204572726f727300cc2a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f7420526f6f74307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f740d070158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f720d070158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e6365720d070158436f6e6669674f703c543a3a4163636f756e7449643e000c546c5570646174652074686520726f6c6573206f66206120706f6f6c2e0085015570646174657320726f6f742c206e6f6d696e61746f7220616e6420626f756e63657220726f6c657320666f72206120676976656e20706f6f6c2e20546865206465706f7369746f7220726f6c652063616e6e6f74206265206368616e6765642ec8456d69747320612060526f6c65735570646174656460206576656e74206f6e207375636365737366756c207570646174652e003423205065726d697373696f6e7300882a204f726967696e206d75737420626520526f6f74206f7220706f6f6c20726f6f74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572a82a20606e65775f726f6f7460202d204e657720726f6f7420726f6c6520636f6e66696775726174696f6ed82a20606e65775f6e6f6d696e61746f7260202d204e6577206e6f6d696e61746f7220726f6c6520636f6e66696775726174696f6e2020c02a20606e65775f626f756e63657260202d204e657720626f756e63657220726f6c6520636f6e66696775726174696f6e002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737411012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d204f726967696e20646f6573206e6f742068617665207065726d697373696f6e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d3c25014368696c6c206f6e20626568616c66206f662074686520706f6f6c20627920666f7277617264696e67207468652063616c6c20746f20746865207374616b696e672070616c6c65742e003423205065726d697373696f6e7300d82a204f726967696e206d757374206265207369676e656420627920706f6f6c206e6f6d696e61746f72206f7220726f6f7420726f6c65002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f82a205b604572726f723a3a4e6f744e6f6d696e61746f72605d202d204f726967696e206c61636b73206e6f6d696e6174696f6e207065726d697373696f6e40626f6e645f65787472615f6f746865720c01186d656d626572c10201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001146578747261ed06015c426f6e6445787472613c42616c616e63654f663c543e3e000e500d01426f6e64206164646974696f6e616c2066756e647320666f72206120706f6f6c206d656d62657220696e746f207468656972207265737065637469766520706f6f6c2e003423205065726d697373696f6e730041012a204f726967696e206d757374206d61746368206d656d626572206163636f756e7420666f7220626f6e64696e672066726f6d20667265652062616c616e63652f70656e64696e6720726577617264733d012a20416e79206f726967696e2063616e20626f6e642066726f6d2070656e64696e672072657761726473206966206d656d6265722068617320605065726d697373696f6e6c657373416c6c60206f72b02020605065726d697373696f6e6c657373436f6d706f756e646020636c61696d207065726d697373696f6e73002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6cb02a20606d656d62657260202d20506f6f6c206d656d626572206163636f756e7420746f20626f6e6420666f72742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572fc2a2060657874726160202d20416d6f756e7420746f20626f6e642066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737405012a205b604572726f723a3a506f6f6c4d656d6265724e6f74466f756e64605d202d204163636f756e74206973206e6f742061206d656d626572206f6620706f6f6c19012a205b604572726f723a3a4e6f5065726d697373696f6e605d202d204f726967696e206c61636b73207065726d697373696f6e20746f20626f6e6420666f72206d656d626572387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001140dc536574206f722072656d6f76652074686520636f6d6d697373696f6e207261746520616e6420706179656520666f72206120706f6f6c2e003423205065726d697373696f6e730001012a2043616c6c6572206d757374206861766520636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e20666f722074686520706f6f6c002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c842a2060706f6f6c5f696460202d2054686520706f6f6c206964656e74696669657265012a20606e65775f636f6d6d697373696f6e60202d204f7074696f6e616c20636f6d6d697373696f6e207261746520616e642070617965652e204e6f6e652072656d6f766573206578697374696e6720636f6d6d697373696f6e002023204572726f727300d82a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d2054686520706f6f6c5f696420646f6573206e6f7420657869737449012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b7320636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c001244690153657420746865206d6178696d756d20636f6d6d697373696f6e207261746520666f72206120706f6f6c2e20496e697469616c206d61782063616e2062652073657420746f20616e792076616c75652c2077697468206f6e6c7955016c6f7765722076616c75657320616c6c6f77656420746865726561667465722e2043757272656e7420636f6d6d697373696f6e2077696c6c20626520726564756365642069662061626f7665206e6577206d61782e003423205065726d697373696f6e730001012a2043616c6c6572206d757374206861766520636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e20666f722074686520706f6f6c002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c842a2060706f6f6c5f696460202d2054686520706f6f6c206964656e746966696572d02a20606d61785f636f6d6d697373696f6e60202d20546865206e6577206d6178696d756d20636f6d6d697373696f6e2072617465002023204572726f727300d82a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d2054686520706f6f6c5f696420646f6573206e6f7420657869737449012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b7320636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654d02019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001328a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e002c2320417267756d656e747300a1012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e2e2d012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f2073657420636f6d6d697373696f6e206368616e6765207261746520666f722efc2a20606368616e67655f7261746560202d20546865206e657720636f6d6d697373696f6e206368616e6765207261746520636f6e66696775726174696f6e2e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400142890436c61696d2070656e64696e6720636f6d6d697373696f6e20666f72206120706f6f6c2e007d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e790150656e64696e6720636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e2e20546f74616c2070656e64696e6720636f6d6d697373696f6e44697320726573657420746f207a65726f2e002c2320417267756d656e7473008d012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e09012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f20636c61696d20636f6d6d697373696f6e2066726f6d2e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c4964001530ec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e0d012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f2061646a75737420746865206465706f73697420666f722e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001628cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e004d014f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6c2069732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e4901546869732064657465726d696e6573207768696368206163636f756e74732061726520616c6c6f77656420746f20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e002c2320417267756d656e7473003d012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642062792074686520706f6f6c277320726f6f74206163636f756e742e01012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f20736574207065726d697373696f6e7320666f722eb9012a20607065726d697373696f6e60202d204f7074696f6e616c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20636f6e66696775726174696f6e2e204966204e6f6e652c2072656d6f76657320616e79206578697374696e67207065726d697373696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eed060c4470616c6c65745f74616e676c655f6c737414747970657324426f6e644578747261041c42616c616e6365011801042c4672656542616c616e6365040018011c42616c616e636500000000f10604184f7074696f6e04045401f5060108104e6f6e6500000010536f6d650400f5060000010000f5060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000f90604184f7074696f6e04045401fd060108104e6f6e6500000010536f6d650400fd060000010000fd060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000001070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f76650002000005070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f76650002000009070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f7665000200000d070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f76650002000011070c2c70616c6c65745f7375646f1870616c6c6574144572726f720404540001042c526571756972655375646f0000048053656e646572206d75737420626520746865205375646f206163636f756e742e04684572726f7220666f7220746865205375646f2070616c6c65742e15070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e000019070c3470616c6c65745f61737365747314747970657330417373657444657461696c730c1c42616c616e63650118244163636f756e7449640100384465706f73697442616c616e63650118003001146f776e65720001244163636f756e7449640001186973737565720001244163636f756e74496400011461646d696e0001244163636f756e74496400011c667265657a65720001244163636f756e744964000118737570706c7918011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500012c6d696e5f62616c616e636518011c42616c616e636500013469735f73756666696369656e74200110626f6f6c0001206163636f756e747310010c75333200012c73756666696369656e747310010c753332000124617070726f76616c7310010c7533320001187374617475731d07012c417373657453746174757300001d070c3470616c6c65745f6173736574731474797065732c417373657453746174757300010c104c6976650000001846726f7a656e0001002844657374726f79696e670002000021070000040818000025070c3470616c6c65745f6173736574731474797065733041737365744163636f756e74101c42616c616e63650118384465706f73697442616c616e636501181445787472610184244163636f756e74496401000010011c62616c616e636518011c42616c616e6365000118737461747573290701344163636f756e74537461747573000118726561736f6e2d0701a84578697374656e6365526561736f6e3c4465706f73697442616c616e63652c204163636f756e7449643e00011465787472618401144578747261000029070c3470616c6c65745f617373657473147479706573344163636f756e7453746174757300010c184c69717569640000001846726f7a656e0001001c426c6f636b6564000200002d070c3470616c6c65745f6173736574731474797065733c4578697374656e6365526561736f6e081c42616c616e63650118244163636f756e7449640100011420436f6e73756d65720000002853756666696369656e740001002c4465706f73697448656c64040018011c42616c616e63650002003c4465706f736974526566756e6465640003002c4465706f73697446726f6d08000001244163636f756e744964000018011c42616c616e63650004000031070000040c1800000035070c3470616c6c65745f61737365747314747970657320417070726f76616c081c42616c616e63650118384465706f73697442616c616e6365011800080118616d6f756e7418011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e6365000039070c3470616c6c65745f6173736574731474797065733441737365744d6574616461746108384465706f73697442616c616e6365011834426f756e646564537472696e67013d070014011c6465706f7369741801384465706f73697442616c616e63650001106e616d653d070134426f756e646564537472696e6700011873796d626f6c3d070134426f756e646564537472696e67000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c00003d070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000041070c3470616c6c65745f6173736574731870616c6c6574144572726f720804540004490001542842616c616e63654c6f7700000415014163636f756e742062616c616e6365206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865207472616e7366657220616d6f756e742e244e6f4163636f756e7400010490546865206163636f756e7420746f20616c74657220646f6573206e6f742065786973742e304e6f5065726d697373696f6e000204e8546865207369676e696e67206163636f756e7420686173206e6f207065726d697373696f6e20746f20646f20746865206f7065726174696f6e2e1c556e6b6e6f776e0003047854686520676976656e20617373657420494420697320756e6b6e6f776e2e1846726f7a656e00040474546865206f726967696e206163636f756e742069732066726f7a656e2e14496e5573650005047854686520617373657420494420697320616c72656164792074616b656e2e284261645769746e6573730006046c496e76616c6964207769746e657373206461746120676976656e2e384d696e42616c616e63655a65726f0007048c4d696e696d756d2062616c616e63652073686f756c64206265206e6f6e2d7a65726f2e4c556e617661696c61626c65436f6e73756d657200080c5901556e61626c6520746f20696e6372656d656e742074686520636f6e73756d6572207265666572656e636520636f756e74657273206f6e20746865206163636f756e742e20456974686572206e6f2070726f76696465724d017265666572656e63652065786973747320746f20616c6c6f772061206e6f6e2d7a65726f2062616c616e6365206f662061206e6f6e2d73656c662d73756666696369656e742061737365742c206f72206f6e65f06665776572207468656e20746865206d6178696d756d206e756d626572206f6620636f6e73756d65727320686173206265656e20726561636865642e2c4261644d657461646174610009045c496e76616c6964206d6574616461746120676976656e2e28556e617070726f766564000a04c44e6f20617070726f76616c20657869737473207468617420776f756c6420616c6c6f7720746865207472616e736665722e20576f756c64446965000b04350154686520736f75726365206163636f756e7420776f756c64206e6f74207375727669766520746865207472616e7366657220616e64206974206e6565647320746f207374617920616c6976652e34416c7265616479457869737473000c04845468652061737365742d6163636f756e7420616c7265616479206578697374732e244e6f4465706f736974000d04d45468652061737365742d6163636f756e7420646f65736e2774206861766520616e206173736f636961746564206465706f7369742e24576f756c644275726e000e04c4546865206f7065726174696f6e20776f756c6420726573756c7420696e2066756e6473206265696e67206275726e65642e244c6976654173736574000f0859015468652061737365742069732061206c69766520617373657420616e64206973206163746976656c79206265696e6720757365642e20557375616c6c7920656d697420666f72206f7065726174696f6e7320737563681d016173206073746172745f64657374726f796020776869636820726571756972652074686520617373657420746f20626520696e20612064657374726f79696e672073746174652e3041737365744e6f744c697665001004c8546865206173736574206973206e6f74206c6976652c20616e64206c696b656c79206265696e672064657374726f7965642e3c496e636f7272656374537461747573001104b054686520617373657420737461747573206973206e6f7420746865206578706563746564207374617475732e244e6f7446726f7a656e001204d85468652061737365742073686f756c642062652066726f7a656e206265666f72652074686520676976656e206f7065726174696f6e2e3843616c6c6261636b4661696c65640013048443616c6c6261636b20616374696f6e20726573756c74656420696e206572726f722842616441737365744964001404c8546865206173736574204944206d75737420626520657175616c20746f20746865205b604e65787441737365744964605d2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e45070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454014907045300000400510701185665633c543e000049070c3c70616c6c65745f62616c616e6365731474797065732c42616c616e63654c6f636b041c42616c616e63650118000c01086964a90201384c6f636b4964656e746966696572000118616d6f756e7418011c42616c616e636500011c726561736f6e734d07011c526561736f6e7300004d070c3c70616c6c65745f62616c616e6365731474797065731c526561736f6e7300010c0c466565000000104d6973630001000c416c6c00020000510700000249070055070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540159070453000004005d0701185665633c543e000059070c3c70616c6c65745f62616c616e6365731474797065732c52657365727665446174610844526573657276654964656e74696669657201a9021c42616c616e63650118000801086964a9020144526573657276654964656e746966696572000118616d6f756e7418011c42616c616e636500005d0700000259070061070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016507045300000400710701185665633c543e0000650714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e74080849640169071c42616c616e63650118000801086964690701084964000118616d6f756e7418011c42616c616e636500006907085874616e676c655f746573746e65745f72756e74696d654452756e74696d65486f6c64526561736f6e00010420507265696d61676504006d07016c70616c6c65745f707265696d6167653a3a486f6c64526561736f6e001a00006d070c3c70616c6c65745f707265696d6167651870616c6c657428486f6c64526561736f6e00010420507265696d61676500000000710700000265070075070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017907045300000400890701185665633c543e0000790714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e7408084964017d071c42616c616e636501180008010869647d0701084964000118616d6f756e7418011c42616c616e636500007d07085874616e676c655f746573746e65745f72756e74696d654c52756e74696d65467265657a65526561736f6e0001083c4e6f6d696e6174696f6e506f6f6c7304008107019470616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a467265657a65526561736f6e0018000c4c737404008507017c70616c6c65745f74616e676c655f6c73743a3a467265657a65526561736f6e0034000081070c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e63650000000085070c4470616c6c65745f74616e676c655f6c73741870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e63650000000089070000027907008d070c3c70616c6c65745f62616c616e6365731870616c6c6574144572726f720804540004490001303856657374696e6742616c616e63650000049c56657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75652e544c69717569646974795265737472696374696f6e73000104c84163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2e4c496e73756666696369656e7442616c616e63650002047842616c616e636520746f6f206c6f7720746f2073656e642076616c75652e484578697374656e7469616c4465706f736974000304ec56616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742e34457870656e646162696c697479000404905472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742e5c4578697374696e6756657374696e675363686564756c65000504cc412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e742e2c446561644163636f756e740006048c42656e6566696369617279206163636f756e74206d757374207072652d65786973742e3c546f6f4d616e795265736572766573000704b84e756d626572206f66206e616d65642072657365727665732065786365656420604d61785265736572766573602e30546f6f4d616e79486f6c6473000804f84e756d626572206f6620686f6c647320657863656564206056617269616e74436f756e744f663c543a3a52756e74696d65486f6c64526561736f6e3e602e38546f6f4d616e79467265657a6573000904984e756d626572206f6620667265657a65732065786365656420604d6178467265657a6573602e4c49737375616e63654465616374697661746564000a0401015468652069737375616e63652063616e6e6f74206265206d6f6469666965642073696e636520697420697320616c72656164792064656163746976617465642e2444656c74615a65726f000b04645468652064656c74612063616e6e6f74206265207a65726f2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e91070c3473705f61726974686d657469632c66697865645f706f696e7424466978656455313238000004001801107531323800009507086870616c6c65745f7472616e73616374696f6e5f7061796d656e742052656c6561736573000108245631416e6369656e740000000856320001000099070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454019d07045300000400a10701185665633c543e00009d0700000408d9023000a1070000029d0700a5070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540104045300000400a90701185665633c543e0000a9070000020400ad0704184f7074696f6e04045401b1070108104e6f6e6500000010536f6d650400b1070000010000b1070c4473705f636f6e73656e7375735f626162651c646967657374732450726544696765737400010c1c5072696d6172790400b50701405072696d617279507265446967657374000100385365636f6e64617279506c61696e0400bd07015c5365636f6e64617279506c61696e507265446967657374000200305365636f6e646172795652460400c10701545365636f6e6461727956524650726544696765737400030000b5070c4473705f636f6e73656e7375735f626162651c64696765737473405072696d61727950726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740001347672665f7369676e6174757265b90701305672665369676e61747572650000b907101c73705f636f72651c737232353531390c767266305672665369676e617475726500000801287072655f6f75747075740401305672665072654f757470757400011470726f6f660903012056726650726f6f660000bd070c4473705f636f6e73656e7375735f626162651c646967657374735c5365636f6e64617279506c61696e507265446967657374000008013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740000c1070c4473705f636f6e73656e7375735f626162651c64696765737473545365636f6e6461727956524650726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74dd020110536c6f740001347672665f7369676e6174757265b90701305672665369676e61747572650000c507084473705f636f6e73656e7375735f62616265584261626545706f6368436f6e66696775726174696f6e000008010463e9020128287536342c2075363429000134616c6c6f7765645f736c6f7473ed020130416c6c6f776564536c6f74730000c9070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540139010453000004005d0201185665633c543e0000cd070c2c70616c6c65745f626162651870616c6c6574144572726f7204045400011060496e76616c696445717569766f636174696f6e50726f6f660000043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c69644b65794f776e65727368697050726f6f66000104310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400020415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e50496e76616c6964436f6e66696775726174696f6e0003048c5375626d697474656420636f6e66696775726174696f6e20697320696e76616c69642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed107083870616c6c65745f6772616e6470612c53746f726564537461746504044e01300110104c6976650000003050656e64696e6750617573650801307363686564756c65645f61743001044e00011464656c61793001044e000100185061757365640002003450656e64696e67526573756d650801307363686564756c65645f61743001044e00011464656c61793001044e00030000d507083870616c6c65745f6772616e6470614c53746f72656450656e64696e674368616e676508044e0130144c696d697400001001307363686564756c65645f61743001044e00011464656c61793001044e0001406e6578745f617574686f726974696573d907016c426f756e646564417574686f726974794c6973743c4c696d69743e000118666f726365647d0401244f7074696f6e3c4e3e0000d9070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401a4045300000400a001185665633c543e0000dd070c3870616c6c65745f6772616e6470611870616c6c6574144572726f7204045400011c2c50617573654661696c65640000080501417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665a42865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e30526573756d654661696c65640001081101417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e277420706175736564a028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e344368616e676550656e64696e67000204e8417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e1c546f6f536f6f6e000304bc43616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e60496e76616c69644b65794f776e65727368697050726f6f66000404310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c696445717569766f636174696f6e50726f6f660005043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400060415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee1070000040c00182000e5070c3870616c6c65745f696e64696365731870616c6c6574144572726f720404540001142c4e6f7441737369676e65640000048c54686520696e64657820776173206e6f7420616c72656164792061737369676e65642e204e6f744f776e6572000104a454686520696e6465782069732061737369676e656420746f20616e6f74686572206163636f756e742e14496e5573650002047054686520696e64657820776173206e6f7420617661696c61626c652e2c4e6f745472616e73666572000304c854686520736f7572636520616e642064657374696e6174696f6e206163636f756e747320617265206964656e746963616c2e245065726d616e656e74000404d054686520696e646578206973207065726d616e656e7420616e64206d6179206e6f742062652066726565642f6368616e6765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee9070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ed07045300000400f10701185665633c543e0000ed070000040c1029030000f107000002ed0700f5070000040859041800f9070c4070616c6c65745f64656d6f6372616379147479706573385265666572656e64756d496e666f0c2c426c6f636b4e756d62657201302050726f706f73616c0129031c42616c616e6365011801081c4f6e676f696e670400fd0701c05265666572656e64756d5374617475733c426c6f636b4e756d6265722c2050726f706f73616c2c2042616c616e63653e0000002046696e6973686564080120617070726f766564200110626f6f6c00010c656e6430012c426c6f636b4e756d62657200010000fd070c4070616c6c65745f64656d6f6372616379147479706573405265666572656e64756d5374617475730c2c426c6f636b4e756d62657201302050726f706f73616c0129031c42616c616e636501180014010c656e6430012c426c6f636b4e756d62657200012070726f706f73616c2903012050726f706f73616c0001247468726573686f6c64b40134566f74655468726573686f6c6400011464656c617930012c426c6f636b4e756d62657200011474616c6c790108013854616c6c793c42616c616e63653e000001080c4070616c6c65745f64656d6f63726163791474797065731454616c6c79041c42616c616e63650118000c01106179657318011c42616c616e63650001106e61797318011c42616c616e636500011c7475726e6f757418011c42616c616e6365000005080c4070616c6c65745f64656d6f637261637910766f746518566f74696e67101c42616c616e63650118244163636f756e74496401002c426c6f636b4e756d6265720130204d6178566f746573000108184469726563740c0114766f746573090801f4426f756e6465645665633c285265666572656e64756d496e6465782c204163636f756e74566f74653c42616c616e63653e292c204d6178566f7465733e00012c64656c65676174696f6e731508015044656c65676174696f6e733c42616c616e63653e0001147072696f721908017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0000002844656c65676174696e6714011c62616c616e636518011c42616c616e63650001187461726765740001244163636f756e744964000128636f6e76696374696f6e35030128436f6e76696374696f6e00012c64656c65676174696f6e731508015044656c65676174696f6e733c42616c616e63653e0001147072696f721908017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0001000009080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010d08045300000400110801185665633c543e00000d080000040810b80011080000020d080015080c4070616c6c65745f64656d6f63726163791474797065732c44656c65676174696f6e73041c42616c616e6365011800080114766f74657318011c42616c616e636500011c6361706974616c18011c42616c616e6365000019080c4070616c6c65745f64656d6f637261637910766f7465245072696f724c6f636b082c426c6f636b4e756d62657201301c42616c616e6365011800080030012c426c6f636b4e756d626572000018011c42616c616e636500001d08000004082903b4002108000004083059040025080c4070616c6c65745f64656d6f63726163791870616c6c6574144572726f720404540001602056616c75654c6f770000043456616c756520746f6f206c6f773c50726f706f73616c4d697373696e670001045c50726f706f73616c20646f6573206e6f742065786973743c416c726561647943616e63656c65640002049443616e6e6f742063616e63656c207468652073616d652070726f706f73616c207477696365444475706c696361746550726f706f73616c0003045450726f706f73616c20616c7265616479206d6164654c50726f706f73616c426c61636b6c69737465640004046850726f706f73616c207374696c6c20626c61636b6c6973746564444e6f7453696d706c654d616a6f72697479000504a84e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792c496e76616c69644861736800060430496e76616c69642068617368284e6f50726f706f73616c000704504e6f2065787465726e616c2070726f706f73616c34416c72656164795665746f6564000804984964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365445265666572656e64756d496e76616c696400090484566f746520676976656e20666f7220696e76616c6964207265666572656e64756d2c4e6f6e6557616974696e67000a04504e6f2070726f706f73616c732077616974696e67204e6f74566f746572000b04c454686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e304e6f5065726d697373696f6e000c04c8546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e44416c726561647944656c65676174696e67000d0488546865206163636f756e7420697320616c72656164792064656c65676174696e672e44496e73756666696369656e7446756e6473000e04fc546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e344e6f7444656c65676174696e67000f04a0546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e28566f74657345786973740010085501546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696ce87468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e44496e7374616e744e6f74416c6c6f776564001104d854686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e204e6f6e73656e73650012049444656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e3c57726f6e675570706572426f756e6400130450496e76616c696420757070657220626f756e642e3c4d6178566f74657352656163686564001404804d6178696d756d206e756d626572206f6620766f74657320726561636865642e1c546f6f4d616e79001504804d6178696d756d206e756d626572206f66206974656d7320726561636865642e3c566f74696e67506572696f644c6f7700160454566f74696e6720706572696f6420746f6f206c6f7740507265696d6167654e6f7445786973740017047054686520707265696d61676520646f6573206e6f742065786973742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e29080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00002d08084470616c6c65745f636f6c6c65637469766514566f74657308244163636f756e74496401002c426c6f636b4e756d626572013000140114696e64657810013450726f706f73616c496e6465780001247468726573686f6c6410012c4d656d626572436f756e74000110617965733d0201385665633c4163636f756e7449643e0001106e6179733d0201385665633c4163636f756e7449643e00010c656e6430012c426c6f636b4e756d626572000031080c4470616c6c65745f636f6c6c6563746976651870616c6c6574144572726f7208045400044900012c244e6f744d656d6265720000045c4163636f756e74206973206e6f742061206d656d626572444475706c696361746550726f706f73616c0001047c4475706c69636174652070726f706f73616c73206e6f7420616c6c6f7765643c50726f706f73616c4d697373696e670002044c50726f706f73616c206d7573742065786973742857726f6e67496e646578000304404d69736d61746368656420696e646578344475706c6963617465566f7465000404584475706c696361746520766f74652069676e6f72656448416c7265616479496e697469616c697a6564000504804d656d626572732061726520616c726561647920696e697469616c697a65642120546f6f4561726c79000604010154686520636c6f73652063616c6c20776173206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e40546f6f4d616e7950726f706f73616c73000704fc54686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e4c57726f6e6750726f706f73616c576569676874000804d054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e4c57726f6e6750726f706f73616c4c656e677468000904d054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e545072696d654163636f756e744e6f744d656d626572000a04745072696d65206163636f756e74206973206e6f742061206d656d626572048054686520604572726f726020656e756d206f6620746869732070616c6c65742e35080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014903045300000400390801185665633c543e000039080000024903003d08083870616c6c65745f76657374696e672052656c65617365730001080856300000000856310001000041080c3870616c6c65745f76657374696e671870616c6c6574144572726f72040454000114284e6f7456657374696e6700000484546865206163636f756e7420676976656e206973206e6f742076657374696e672e5441744d617856657374696e675363686564756c65730001082501546865206163636f756e7420616c72656164792068617320604d617856657374696e675363686564756c65736020636f756e74206f66207363686564756c657320616e642074687573510163616e6e6f742061646420616e6f74686572206f6e652e20436f6e7369646572206d657267696e67206578697374696e67207363686564756c657320696e206f7264657220746f2061646420616e6f746865722e24416d6f756e744c6f770002040501416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e605363686564756c65496e6465784f75744f66426f756e6473000304d0416e20696e64657820776173206f7574206f6620626f756e6473206f66207468652076657374696e67207363686564756c65732e54496e76616c69645363686564756c65506172616d730004040d014661696c656420746f206372656174652061206e6577207363686564756c65206265636175736520736f6d6520706172616d657465722077617320696e76616c69642e04744572726f7220666f72207468652076657374696e672070616c6c65742e45080000024908004908086470616c6c65745f656c656374696f6e735f70687261676d656e2853656174486f6c64657208244163636f756e74496401001c42616c616e63650118000c010c77686f0001244163636f756e7449640001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e636500004d08086470616c6c65745f656c656374696f6e735f70687261676d656e14566f74657208244163636f756e74496401001c42616c616e63650118000c0114766f7465733d0201385665633c4163636f756e7449643e0001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e6365000051080c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144572726f7204045400014430556e61626c65546f566f7465000004c043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e1c4e6f566f746573000104944d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e30546f6f4d616e79566f7465730002048443616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e504d6178696d756d566f74657345786365656465640003049843616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e284c6f7742616c616e6365000404c443616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e3c556e61626c65546f506179426f6e6400050478566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2c4d7573744265566f746572000604404d757374206265206120766f7465722e4c4475706c69636174656443616e646964617465000704804475706c6963617465642063616e646964617465207375626d697373696f6e2e44546f6f4d616e7943616e6469646174657300080498546f6f206d616e792063616e646964617465732068617665206265656e20637265617465642e304d656d6265725375626d6974000904884d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e3852756e6e657255705375626d6974000a048852756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e68496e73756666696369656e7443616e64696461746546756e6473000b049443616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e244e6f744d656d626572000c04344e6f742061206d656d6265722e48496e76616c69645769746e65737344617461000d04e05468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e40496e76616c6964566f7465436f756e74000e04cc5468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e44496e76616c696452656e6f756e63696e67000f04fc5468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e48496e76616c69645265706c6163656d656e74001004fc50726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e5508089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365345265616479536f6c7574696f6e08244163636f756e74496400284d617857696e6e65727300000c0120737570706f72747359080198426f756e646564537570706f7274733c4163636f756e7449642c204d617857696e6e6572733e00011473636f7265e00134456c656374696f6e53636f726500011c636f6d70757465dc013c456c656374696f6e436f6d70757465000059080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013504045300000400310401185665633c543e00005d08089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736534526f756e64536e617073686f7408244163636f756e7449640100304461746150726f766964657201610800080118766f74657273690801445665633c4461746150726f76696465723e00011c746172676574733d0201385665633c4163636f756e7449643e000061080000040c003065080065080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e000069080000026108006d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017108045300000400750801185665633c543e000071080000040ce0301000750800000271080079080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365187369676e6564405369676e65645375626d697373696f6e0c244163636f756e74496401001c42616c616e6365011820536f6c7574696f6e015d030010010c77686f0001244163636f756e74496400011c6465706f73697418011c42616c616e63650001307261775f736f6c7574696f6e59030154526177536f6c7574696f6e3c536f6c7574696f6e3e00012063616c6c5f66656518011c42616c616e636500007d080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144572726f7204045400013c6850726544697370617463684561726c795375626d697373696f6e000004645375626d697373696f6e2077617320746f6f206561726c792e6c507265446973706174636857726f6e6757696e6e6572436f756e740001048857726f6e67206e756d626572206f662077696e6e6572732070726573656e7465642e6450726544697370617463685765616b5375626d697373696f6e000204905375626d697373696f6e2077617320746f6f207765616b2c2073636f72652d776973652e3c5369676e6564517565756546756c6c0003044901546865207175657565207761732066756c6c2c20616e642074686520736f6c7574696f6e20776173206e6f7420626574746572207468616e20616e79206f6620746865206578697374696e67206f6e65732e585369676e656443616e6e6f745061794465706f73697400040494546865206f726967696e206661696c656420746f2070617920746865206465706f7369742e505369676e6564496e76616c69645769746e657373000504a05769746e657373206461746120746f20646973706174636861626c6520697320696e76616c69642e4c5369676e6564546f6f4d756368576569676874000604b8546865207369676e6564207375626d697373696f6e20636f6e73756d657320746f6f206d756368207765696768743c4f637743616c6c57726f6e67457261000704984f4357207375626d697474656420736f6c7574696f6e20666f722077726f6e6720726f756e645c4d697373696e67536e617073686f744d65746164617461000804a8536e617073686f74206d657461646174612073686f756c6420657869737420627574206469646e27742e58496e76616c69645375626d697373696f6e496e646578000904d06053656c663a3a696e736572745f7375626d697373696f6e602072657475726e656420616e20696e76616c696420696e6465782e3843616c6c4e6f74416c6c6f776564000a04985468652063616c6c206973206e6f7420616c6c6f776564206174207468697320706f696e742e3846616c6c6261636b4661696c6564000b044c5468652066616c6c6261636b206661696c65642c426f756e644e6f744d6574000c0448536f6d6520626f756e64206e6f74206d657438546f6f4d616e7957696e6e657273000d049c5375626d697474656420736f6c7574696f6e2068617320746f6f206d616e792077696e6e657273645072654469737061746368446966666572656e74526f756e64000e04b85375626d697373696f6e2077617320707265706172656420666f72206120646966666572656e7420726f756e642e040d014572726f72206f66207468652070616c6c657420746861742063616e2062652072657475726e656420696e20726573706f6e736520746f20646973706174636865732e8108083870616c6c65745f7374616b696e67345374616b696e674c656467657204045400001401147374617368000130543a3a4163636f756e744964000114746f74616c6d01013042616c616e63654f663c543e0001186163746976656d01013042616c616e63654f663c543e000124756e6c6f636b696e67650401f0426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a4d6178556e6c6f636b696e674368756e6b733e0001586c65676163795f636c61696d65645f7265776172647385080194426f756e6465645665633c457261496e6465782c20543a3a486973746f727944657074683e000085080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e00008908083870616c6c65745f7374616b696e672c4e6f6d696e6174696f6e7304045400000c011c74617267657473650801b4426f756e6465645665633c543a3a4163636f756e7449642c204d61784e6f6d696e6174696f6e734f663c543e3e0001307375626d69747465645f696e100120457261496e64657800012873757070726573736564200110626f6f6c00008d08083870616c6c65745f7374616b696e6734416374697665457261496e666f0000080114696e646578100120457261496e64657800011473746172747d04012c4f7074696f6e3c7536343e00009108000004081000009508082873705f7374616b696e675450616765644578706f737572654d65746164617461041c42616c616e6365011800100114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e636500013c6e6f6d696e61746f725f636f756e7410010c753332000128706167655f636f756e7410011050616765000099080000040c100010009d08082873705f7374616b696e67304578706f737572655061676508244163636f756e74496401001c42616c616e6365011800080128706167655f746f74616c6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e0000a108083870616c6c65745f7374616b696e673c457261526577617264506f696e747304244163636f756e744964010000080114746f74616c10012c526577617264506f696e74000128696e646976696475616ca508018042547265654d61703c4163636f756e7449642c20526577617264506f696e743e0000a508042042547265654d617008044b010004560110000400a908000000a908000002ad0800ad0800000408001000b108000002b50800b508083870616c6c65745f7374616b696e6738556e6170706c696564536c61736808244163636f756e74496401001c42616c616e636501180014012476616c696461746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f72746572733d0201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000b908000002bd0800bd0800000408101000c10800000408f41800c5080c3870616c6c65745f7374616b696e6720736c617368696e6734536c617368696e675370616e7300001001287370616e5f696e6465781001245370616e496e6465780001286c6173745f7374617274100120457261496e6465780001486c6173745f6e6f6e7a65726f5f736c617368100120457261496e6465780001147072696f72450401345665633c457261496e6465783e0000c9080c3870616c6c65745f7374616b696e6720736c617368696e67285370616e5265636f7264041c42616c616e636501180008011c736c617368656418011c42616c616e6365000120706169645f6f757418011c42616c616e63650000cd08103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144572726f7204045400017c344e6f74436f6e74726f6c6c6572000004644e6f74206120636f6e74726f6c6c6572206163636f756e742e204e6f745374617368000104504e6f742061207374617368206163636f756e742e34416c7265616479426f6e64656400020460537461736820697320616c726561647920626f6e6465642e34416c726561647950616972656400030474436f6e74726f6c6c657220697320616c7265616479207061697265642e30456d7074795461726765747300040460546172676574732063616e6e6f7420626520656d7074792e384475706c6963617465496e646578000504404475706c696361746520696e6465782e44496e76616c6964536c617368496e64657800060484536c617368207265636f726420696e646578206f7574206f6620626f756e64732e40496e73756666696369656e74426f6e6400070c590143616e6e6f74206861766520612076616c696461746f72206f72206e6f6d696e61746f7220726f6c652c20776974682076616c7565206c657373207468616e20746865206d696e696d756d20646566696e65642062793d01676f7665726e616e6365202873656520604d696e56616c696461746f72426f6e646020616e6420604d696e4e6f6d696e61746f72426f6e6460292e20496620756e626f6e64696e67206973207468651501696e74656e74696f6e2c20606368696c6c6020666972737420746f2072656d6f7665206f6e65277320726f6c652061732076616c696461746f722f6e6f6d696e61746f722e304e6f4d6f72654368756e6b730008049043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e344e6f556e6c6f636b4368756e6b000904a043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e3046756e646564546172676574000a04c8417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e48496e76616c6964457261546f526577617264000b0458496e76616c69642065726120746f207265776172642e68496e76616c69644e756d6265724f664e6f6d696e6174696f6e73000c0478496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e484e6f74536f72746564416e64556e69717565000d04804974656d7320617265206e6f7420736f7274656420616e6420756e697175652e38416c7265616479436c61696d6564000e0409015265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e2c496e76616c696450616765000f04844e6f206e6f6d696e61746f7273206578697374206f6e207468697320706167652e54496e636f7272656374486973746f72794465707468001004c0496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e58496e636f7272656374536c617368696e675370616e73001104b0496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e2042616453746174650012043901496e7465726e616c20737461746520686173206265636f6d6520736f6d65686f7720636f7272757074656420616e6420746865206f7065726174696f6e2063616e6e6f7420636f6e74696e75652e38546f6f4d616e795461726765747300130494546f6f206d616e79206e6f6d696e6174696f6e207461726765747320737570706c6965642e244261645461726765740014043d0141206e6f6d696e6174696f6e207461726765742077617320737570706c69656420746861742077617320626c6f636b6564206f72206f7468657277697365206e6f7420612076616c696461746f722e4043616e6e6f744368696c6c4f74686572001504550154686520757365722068617320656e6f75676820626f6e6420616e6420746875732063616e6e6f74206265206368696c6c656420666f72636566756c6c7920627920616e2065787465726e616c20706572736f6e2e44546f6f4d616e794e6f6d696e61746f72730016084d0154686572652061726520746f6f206d616e79206e6f6d696e61746f727320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865207374616b696e67b473657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e44546f6f4d616e7956616c696461746f7273001708550154686572652061726520746f6f206d616e792076616c696461746f722063616e6469646174657320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865d47374616b696e672073657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e40436f6d6d697373696f6e546f6f4c6f77001804e0436f6d6d697373696f6e20697320746f6f206c6f772e204d757374206265206174206c6561737420604d696e436f6d6d697373696f6e602e2c426f756e644e6f744d657400190458536f6d6520626f756e64206973206e6f74206d65742e50436f6e74726f6c6c657244657072656361746564001a04010155736564207768656e20617474656d7074696e6720746f20757365206465707265636174656420636f6e74726f6c6c6572206163636f756e74206c6f6769632e4c43616e6e6f74526573746f72654c6564676572001b045843616e6e6f742072657365742061206c65646765722e6c52657761726444657374696e6174696f6e52657374726963746564001c04ac50726f7669646564207265776172642064657374696e6174696f6e206973206e6f7420616c6c6f7765642e384e6f74456e6f75676846756e6473001d049c4e6f7420656e6f7567682066756e647320617661696c61626c6520746f2077697468647261772e5c5669727475616c5374616b65724e6f74416c6c6f776564001e04a84f7065726174696f6e206e6f7420616c6c6f77656420666f72207669727475616c207374616b6572732e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed108000002d50800d5080000040800750400d90800000408dd083800dd080c1c73705f636f72651863727970746f244b65795479706549640000040048011c5b75383b20345d0000e1080c3870616c6c65745f73657373696f6e1870616c6c6574144572726f7204045400011430496e76616c696450726f6f6600000460496e76616c6964206f776e6572736869702070726f6f662e5c4e6f4173736f63696174656456616c696461746f7249640001049c4e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e344475706c6963617465644b65790002046452656769737465726564206475706c6963617465206b65792e184e6f4b657973000304a44e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e244e6f4163636f756e7400040419014b65792073657474696e67206163636f756e74206973206e6f74206c6976652c20736f206974277320696d706f737369626c6520746f206173736f6369617465206b6579732e04744572726f7220666f72207468652073657373696f6e2070616c6c65742ee50800000408341000e908083c70616c6c65745f74726561737572792050726f706f73616c08244163636f756e74496401001c42616c616e636501180010012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500012c62656e65666963696172790001244163636f756e744964000110626f6e6418011c42616c616e63650000ed080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e0000f108083c70616c6c65745f74726561737572792c5370656e64537461747573142441737365744b696e64018430417373657442616c616e636501182c42656e656669636961727901002c426c6f636b4e756d6265720130245061796d656e74496401840018012861737365745f6b696e6484012441737365744b696e64000118616d6f756e74180130417373657442616c616e636500012c62656e656669636961727900012c42656e656669636961727900012876616c69645f66726f6d30012c426c6f636b4e756d6265720001246578706972655f617430012c426c6f636b4e756d626572000118737461747573f508015c5061796d656e7453746174653c5061796d656e7449643e0000f508083c70616c6c65745f7472656173757279305061796d656e745374617465040849640184010c1c50656e64696e6700000024417474656d7074656404010869648401084964000100184661696c656400020000f90808346672616d655f737570706f72742050616c6c6574496400000400a902011c5b75383b20385d0000fd080c3c70616c6c65745f74726561737572791870616c6c6574144572726f7208045400044900012c30496e76616c6964496e646578000004ac4e6f2070726f706f73616c2c20626f756e7479206f72207370656e64206174207468617420696e6465782e40546f6f4d616e79417070726f76616c7300010480546f6f206d616e7920617070726f76616c7320696e207468652071756575652e58496e73756666696369656e745065726d697373696f6e0002084501546865207370656e64206f726967696e2069732076616c6964206275742074686520616d6f756e7420697420697320616c6c6f77656420746f207370656e64206973206c6f776572207468616e207468654c616d6f756e7420746f206265207370656e742e4c50726f706f73616c4e6f74417070726f7665640003047c50726f706f73616c20686173206e6f74206265656e20617070726f7665642e584661696c6564546f436f6e7665727442616c616e636500040451015468652062616c616e6365206f6620746865206173736574206b696e64206973206e6f7420636f6e7665727469626c6520746f207468652062616c616e6365206f6620746865206e61746976652061737365742e305370656e6445787069726564000504b0546865207370656e6420686173206578706972656420616e642063616e6e6f7420626520636c61696d65642e2c4561726c795061796f7574000604a4546865207370656e64206973206e6f742079657420656c696769626c6520666f72207061796f75742e40416c7265616479417474656d707465640007049c546865207061796d656e742068617320616c7265616479206265656e20617474656d707465642e2c5061796f75744572726f72000804cc54686572652077617320736f6d65206973737565207769746820746865206d656368616e69736d206f66207061796d656e742e304e6f74417474656d70746564000904a4546865207061796f757420776173206e6f742079657420617474656d707465642f636c61696d65642e30496e636f6e636c7573697665000a04c4546865207061796d656e7420686173206e656974686572206661696c6564206e6f7220737563636565646564207965742e04784572726f7220666f72207468652074726561737572792070616c6c65742e0109083c70616c6c65745f626f756e7469657318426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d62657201300018012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000110626f6e6418011c42616c616e636500011873746174757305090190426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00000509083c70616c6c65745f626f756e7469657330426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001182050726f706f73656400000020417070726f7665640001001846756e6465640002003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640003001841637469766508011c63757261746f720001244163636f756e7449640001287570646174655f64756530012c426c6f636b4e756d6265720004003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d6265720005000009090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00000d090c3c70616c6c65745f626f756e746965731870616c6c6574144572726f7208045400044900012c70496e73756666696369656e7450726f706f7365727342616c616e63650000047850726f706f73657227732062616c616e636520697320746f6f206c6f772e30496e76616c6964496e646578000104904e6f2070726f706f73616c206f7220626f756e7479206174207468617420696e6465782e30526561736f6e546f6f4269670002048454686520726561736f6e20676976656e206973206a75737420746f6f206269672e40556e65787065637465645374617475730003048054686520626f756e74792073746174757320697320756e65787065637465642e385265717569726543757261746f720004045c5265717569726520626f756e74792063757261746f722e30496e76616c696456616c756500050454496e76616c696420626f756e74792076616c75652e28496e76616c69644665650006044c496e76616c696420626f756e7479206665652e3450656e64696e675061796f75740007086c4120626f756e7479207061796f75742069732070656e64696e672ef8546f2063616e63656c2074686520626f756e74792c20796f75206d75737420756e61737369676e20616e6420736c617368207468652063757261746f722e245072656d6174757265000804450154686520626f756e746965732063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e504861734163746976654368696c64426f756e7479000904050154686520626f756e74792063616e6e6f7420626520636c6f73656420626563617573652069742068617320616374697665206368696c6420626f756e746965732e34546f6f4d616e79517565756564000a0498546f6f206d616e7920617070726f76616c732061726520616c7265616479207175657565642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e1109085470616c6c65745f6368696c645f626f756e746965732c4368696c64426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d626572013000140134706172656e745f626f756e747910012c426f756e7479496e64657800011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000118737461747573150901a44368696c64426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00001509085470616c6c65745f6368696c645f626f756e74696573444368696c64426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001101441646465640000003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640001001841637469766504011c63757261746f720001244163636f756e7449640002003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d6265720003000019090c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144572726f7204045400010c54506172656e74426f756e74794e6f74416374697665000004a454686520706172656e7420626f756e7479206973206e6f7420696e206163746976652073746174652e64496e73756666696369656e74426f756e747942616c616e6365000104e454686520626f756e74792062616c616e6365206973206e6f7420656e6f75676820746f20616464206e6577206368696c642d626f756e74792e50546f6f4d616e794368696c64426f756e746965730002040d014e756d626572206f66206368696c6420626f756e746965732065786365656473206c696d697420604d61784163746976654368696c64426f756e7479436f756e74602e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e1d090c4070616c6c65745f626167735f6c697374106c697374104e6f646508045400044900001401086964000130543a3a4163636f756e744964000110707265768801504f7074696f6e3c543a3a4163636f756e7449643e0001106e6578748801504f7074696f6e3c543a3a4163636f756e7449643e0001246261675f7570706572300120543a3a53636f726500011473636f7265300120543a3a53636f7265000021090c4070616c6c65745f626167735f6c697374106c6973740c4261670804540004490000080110686561648801504f7074696f6e3c543a3a4163636f756e7449643e0001107461696c8801504f7074696f6e3c543a3a4163636f756e7449643e000025090c4070616c6c65745f626167735f6c6973741870616c6c6574144572726f72080454000449000104104c6973740400290901244c6973744572726f72000004b441206572726f7220696e20746865206c69737420696e7465726661636520696d706c656d656e746174696f6e2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e29090c4070616c6c65745f626167735f6c697374106c697374244c6973744572726f72000110244475706c6963617465000000284e6f7448656176696572000100304e6f74496e53616d65426167000200304e6f64654e6f74466f756e64000300002d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328506f6f6c4d656d626572040454000010011c706f6f6c5f6964100118506f6f6c4964000118706f696e747318013042616c616e63654f663c543e0001706c6173745f7265636f726465645f7265776172645f636f756e74657291070140543a3a526577617264436f756e746572000138756e626f6e64696e675f65726173310901e0426f756e64656442547265654d61703c457261496e6465782c2042616c616e63654f663c543e2c20543a3a4d6178556e626f6e64696e673e000031090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601180453000004003509013842547265654d61703c4b2c20563e00003509042042547265654d617008044b011004560118000400390900000039090000023d09003d09000004081018004109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c426f6e646564506f6f6c496e6e65720404540000140128636f6d6d697373696f6e45090134436f6d6d697373696f6e3c543e0001386d656d6265725f636f756e74657210010c753332000118706f696e747318013042616c616e63654f663c543e000114726f6c65735109015c506f6f6c526f6c65733c543a3a4163636f756e7449643e00011473746174651d010124506f6f6c537461746500004509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784909013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f726174654d0901bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e0000490904184f7074696f6e04045401f40108104e6f6e6500000010536f6d650400f400000100004d0904184f7074696f6e0404540129010108104e6f6e6500000010536f6d650400290100000100005109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e00005509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e74657291070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e00005909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320537562506f6f6c7304045400000801186e6f5f6572615d090134556e626f6e64506f6f6c3c543e000120776974685f6572616109010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e00005d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e000061090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b01100456015d090453000004006509013842547265654d61703c4b2c20563e00006509042042547265654d617008044b01100456015d09000400690900000069090000026d09006d0900000408105d090071090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144572726f7204045400019430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e644163636f756e7442656c6f6e6773546f4f74686572506f6f6c0004084d01416e206163636f756e7420697320616c72656164792064656c65676174696e6720696e20616e6f7468657220706f6f6c2e20416e206163636f756e74206d6179206f6e6c792062656c6f6e6720746f206f6e653c706f6f6c20617420612074696d652e3846756c6c79556e626f6e64696e670005083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740006040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790007044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000814290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0009042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e67000a085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000b04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000c043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000d047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000e04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000f049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e676553746174650010048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001104b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001204ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e73697665040075090138446566656e736976654572726f720013083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001404bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640015041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001604ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001704e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400180409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640019040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001a04a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001b048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001c0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001d049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001e04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001f04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e384e6f7468696e67546f536c617368002004cc4e6f20736c6173682070656e64696e6720746861742063616e206265206170706c69656420746f20746865206d656d6265722e2c536c617368546f6f4c6f77002104a854686520736c61736820616d6f756e7420697320746f6f206c6f7720746f206265206170706c6965642e3c416c72656164794d69677261746564002204150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e2068617320616c7265616479206d6967726174656420746f2064656c6567617465207374616b652e2c4e6f744d69677261746564002304150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e20686173206e6f74206d696772617465642079657420746f2064656c6567617465207374616b652e304e6f74537570706f72746564002404f0546869732063616c6c206973206e6f7420616c6c6f77656420696e207468652063757272656e74207374617465206f66207468652070616c6c65742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e75090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657438446566656e736976654572726f7200011c684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c790004005444656c65676174696f6e556e737570706f727465640005003c536c6173684e6f744170706c6965640006000079090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017d09045300000400850901185665633c543e00007d0904184f7074696f6e0404540181090108104e6f6e6500000010536f6d650400810900000100008109084070616c6c65745f7363686564756c6572245363686564756c656414104e616d6501041043616c6c0129032c426c6f636b4e756d62657201303450616c6c6574734f726967696e016d05244163636f756e7449640100001401206d617962655f69643d0101304f7074696f6e3c4e616d653e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6c2903011043616c6c0001386d617962655f706572696f646963ad0401944f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d6265723e3e0001186f726967696e6d05013450616c6c6574734f726967696e000085090000027d09008909084070616c6c65745f7363686564756c65722c5265747279436f6e6669670418506572696f640130000c0134746f74616c5f72657472696573080108753800012472656d61696e696e670801087538000118706572696f64300118506572696f6400008d090c4070616c6c65745f7363686564756c65721870616c6c6574144572726f72040454000114404661696c6564546f5363686564756c65000004644661696c656420746f207363686564756c6520612063616c6c204e6f74466f756e640001047c43616e6e6f742066696e6420746865207363686564756c65642063616c6c2e5c546172676574426c6f636b4e756d626572496e50617374000204a4476976656e2074617267657420626c6f636b206e756d62657220697320696e2074686520706173742e4852657363686564756c654e6f4368616e6765000304f052657363686564756c65206661696c6564206265636175736520697420646f6573206e6f74206368616e6765207363686564756c65642074696d652e144e616d6564000404d0417474656d707420746f207573652061206e6f6e2d6e616d65642066756e6374696f6e206f6e2061206e616d6564207461736b2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e9109083c70616c6c65745f707265696d616765404f6c645265717565737453746174757308244163636f756e74496401001c42616c616e6365011801082c556e72657175657374656408011c6465706f736974d40150284163636f756e7449642c2042616c616e63652900010c6c656e10010c753332000000245265717565737465640c011c6465706f736974950901704f7074696f6e3c284163636f756e7449642c2042616c616e6365293e000114636f756e7410010c75333200010c6c656e3903012c4f7074696f6e3c7533323e00010000950904184f7074696f6e04045401d40108104e6f6e6500000010536f6d650400d400000100009909083c70616c6c65745f707265696d616765345265717565737453746174757308244163636f756e7449640100185469636b6574018401082c556e7265717565737465640801187469636b65749d09014c284163636f756e7449642c205469636b65742900010c6c656e10010c753332000000245265717565737465640c01306d617962655f7469636b6574a109016c4f7074696f6e3c284163636f756e7449642c205469636b6574293e000114636f756e7410010c7533320001246d617962655f6c656e3903012c4f7074696f6e3c7533323e000100009d0900000408008400a10904184f7074696f6e040454019d090108104e6f6e6500000010536f6d6504009d090000010000a5090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000a9090c3c70616c6c65745f707265696d6167651870616c6c6574144572726f7204045400012418546f6f426967000004a0507265696d61676520697320746f6f206c6172676520746f2073746f7265206f6e2d636861696e2e30416c72656164794e6f746564000104a4507265696d6167652068617320616c7265616479206265656e206e6f746564206f6e2d636861696e2e344e6f74417574686f72697a6564000204c85468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e2e204e6f744e6f746564000304fc54686520707265696d6167652063616e6e6f742062652072656d6f7665642073696e636520697420686173206e6f7420796574206265656e206e6f7465642e2452657175657374656400040409014120707265696d616765206d6179206e6f742062652072656d6f766564207768656e20746865726520617265206f75747374616e64696e672072657175657374732e304e6f745265717565737465640005042d0154686520707265696d61676520726571756573742063616e6e6f742062652072656d6f7665642073696e6365206e6f206f75747374616e64696e672072657175657374732065786973742e1c546f6f4d616e7900060455014d6f7265207468616e20604d41585f484153485f555047524144455f42554c4b5f434f554e54602068617368657320776572652072657175657374656420746f206265207570677261646564206174206f6e63652e18546f6f466577000704e4546f6f206665772068617368657320776572652072657175657374656420746f2062652075706772616465642028692e652e207a65726f292e184e6f436f737400080459014e6f207469636b65742077697468206120636f7374207761732072657475726e6564206279205b60436f6e6669673a3a436f6e73696465726174696f6e605d20746f2073746f72652074686520707265696d6167652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ead090c2873705f7374616b696e671c6f6666656e6365384f6666656e636544657461696c7308205265706f727465720100204f6666656e646572016501000801206f6666656e646572650101204f6666656e6465720001247265706f72746572733d0201345665633c5265706f727465723e0000b1090000040849013800b5090c3c70616c6c65745f74785f70617573651870616c6c6574144572726f720404540001102049735061757365640000044c5468652063616c6c206973207061757365642e284973556e706175736564000104545468652063616c6c20697320756e7061757365642e28556e7061757361626c65000204b45468652063616c6c2069732077686974656c697374656420616e642063616e6e6f74206265207061757365642e204e6f74466f756e64000300048054686520604572726f726020656e756d206f6620746869732070616c6c65742eb9090c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454015d01045300000400bd0901185665633c543e0000bd090000025d0100c1090c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144572726f7204045400010828496e76616c69644b6579000004604e6f6e206578697374656e74207075626c6963206b65792e4c4475706c696361746564486561727462656174000104544475706c696361746564206865617274626561742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ec50900000408c909d90900c9090c3c70616c6c65745f6964656e7469747914747970657330526567697374726174696f6e0c1c42616c616e63650118344d61784a756467656d656e747300304964656e74697479496e666f01c904000c01286a756467656d656e7473cd0901fc426f756e6465645665633c28526567697374726172496e6465782c204a756467656d656e743c42616c616e63653e292c204d61784a756467656d656e74733e00011c6465706f73697418011c42616c616e6365000110696e666fc90401304964656e74697479496e666f0000cd090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d109045300000400d50901185665633c543e0000d1090000040810590500d509000002d10900d90904184f7074696f6e040454017d010108104e6f6e6500000010536f6d6504007d010000010000dd090000040818e10900e1090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e0000e5090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e909045300000400f10901185665633c543e0000e90904184f7074696f6e04045401ed090108104e6f6e6500000010536f6d650400ed090000010000ed090c3c70616c6c65745f6964656e7469747914747970657334526567697374726172496e666f0c1c42616c616e63650118244163636f756e74496401001c49644669656c640130000c011c6163636f756e740001244163636f756e74496400010c66656518011c42616c616e63650001186669656c647330011c49644669656c640000f109000002e90900f5090c3c70616c6c65745f6964656e746974791474797065734c417574686f7269747950726f70657274696573041853756666697801f90900080118737566666978f9090118537566666978000128616c6c6f636174696f6e100128416c6c6f636174696f6e0000f9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000fd0900000408003000010a0c3c70616c6c65745f6964656e746974791870616c6c6574144572726f7204045400016848546f6f4d616e795375624163636f756e74730000045c546f6f206d616e7920737562732d6163636f756e74732e204e6f74466f756e64000104504163636f756e742069736e277420666f756e642e204e6f744e616d6564000204504163636f756e742069736e2774206e616d65642e28456d707479496e64657800030430456d70747920696e6465782e284665654368616e6765640004043c466565206973206368616e6765642e284e6f4964656e74697479000504484e6f206964656e7469747920666f756e642e3c537469636b794a756467656d656e7400060444537469636b79206a756467656d656e742e384a756467656d656e74476976656e000704404a756467656d656e7420676976656e2e40496e76616c69644a756467656d656e7400080448496e76616c6964206a756467656d656e742e30496e76616c6964496e6465780009045454686520696e64657820697320696e76616c69642e34496e76616c6964546172676574000a04585468652074617267657420697320696e76616c69642e44546f6f4d616e7952656769737472617273000b04e84d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e38416c7265616479436c61696d6564000c04704163636f756e7420494420697320616c7265616479206e616d65642e184e6f74537562000d047053656e646572206973206e6f742061207375622d6163636f756e742e204e6f744f776e6564000e04885375622d6163636f756e742069736e2774206f776e65642062792073656e6465722e744a756467656d656e74466f72446966666572656e744964656e74697479000f04d05468652070726f7669646564206a756467656d656e742077617320666f72206120646966666572656e74206964656e746974792e584a756467656d656e745061796d656e744661696c6564001004f84572726f722074686174206f6363757273207768656e20746865726520697320616e20697373756520706179696e6720666f72206a756467656d656e742e34496e76616c6964537566666978001104805468652070726f76696465642073756666697820697320746f6f206c6f6e672e504e6f74557365726e616d65417574686f72697479001204e05468652073656e64657220646f6573206e6f742068617665207065726d697373696f6e20746f206973737565206120757365726e616d652e304e6f416c6c6f636174696f6e001304c454686520617574686f726974792063616e6e6f7420616c6c6f6361746520616e79206d6f726520757365726e616d65732e40496e76616c69645369676e6174757265001404a8546865207369676e6174757265206f6e206120757365726e616d6520776173206e6f742076616c69642e4452657175697265735369676e6174757265001504090153657474696e67207468697320757365726e616d652072657175697265732061207369676e61747572652c20627574206e6f6e65207761732070726f76696465642e3c496e76616c6964557365726e616d65001604b054686520757365726e616d6520646f6573206e6f74206d6565742074686520726571756972656d656e74732e34557365726e616d6554616b656e0017047854686520757365726e616d6520697320616c72656164792074616b656e2e284e6f557365726e616d65001804985468652072657175657374656420757365726e616d6520646f6573206e6f742065786973742e284e6f74457870697265640019042d0154686520757365726e616d652063616e6e6f7420626520666f72636566756c6c792072656d6f76656420626563617573652069742063616e207374696c6c2062652061636365707465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e050a0c3870616c6c65745f7574696c6974791870616c6c6574144572726f7204045400010430546f6f4d616e7943616c6c730000045c546f6f206d616e792063616c6c7320626174636865642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e090a000004080004000d0a083c70616c6c65745f6d756c7469736967204d756c7469736967102c426c6f636b4e756d62657201301c42616c616e63650118244163636f756e7449640100304d6178417070726f76616c7300001001107768656e8901015854696d65706f696e743c426c6f636b4e756d6265723e00011c6465706f73697418011c42616c616e63650001246465706f7369746f720001244163636f756e744964000124617070726f76616c735904018c426f756e6465645665633c4163636f756e7449642c204d6178417070726f76616c733e0000110a0c3c70616c6c65745f6d756c74697369671870616c6c6574144572726f72040454000138404d696e696d756d5468726573686f6c640000047c5468726573686f6c64206d7573742062652032206f7220677265617465722e3c416c7265616479417070726f766564000104ac43616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e444e6f417070726f76616c734e65656465640002049c43616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e44546f6f4665775369676e61746f72696573000304a854686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e48546f6f4d616e795369676e61746f72696573000404ac54686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e545369676e61746f726965734f75744f664f726465720005040d01546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e4c53656e646572496e5369676e61746f726965730006040d015468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e204e6f74466f756e64000704dc4d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e204e6f744f776e65720008042d014f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e2c4e6f54696d65706f696e740009041d014e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e3857726f6e6754696d65706f696e74000a042d014120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e4c556e657870656374656454696d65706f696e74000b04f4412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e3c4d6178576569676874546f6f4c6f77000c04d0546865206d6178696d756d2077656967687420696e666f726d6174696f6e2070726f76696465642077617320746f6f206c6f772e34416c726561647953746f726564000d04a0546865206461746120746f2062652073746f72656420697320616c72656164792073746f7265642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e150a000002190a00190a0000040c89051d0a2d0a001d0a081866705f727063445472616e73616374696f6e53746174757300001c01407472616e73616374696f6e5f68617368340110483235360001447472616e73616374696f6e5f696e64657810010c75333200011066726f6d9101011c41646472657373000108746f0506013c4f7074696f6e3c416464726573733e000140636f6e74726163745f616464726573730506013c4f7074696f6e3c416464726573733e0001106c6f6773210a01205665633c4c6f673e0001286c6f67735f626c6f6f6d250a0114426c6f6f6d0000210a000002bd0100250a0820657468626c6f6f6d14426c6f6f6d00000400290a01405b75383b20424c4f4f4d5f53495a455d0000290a0000030001000008002d0a0c20657468657265756d1c726563656970742452656365697074563300010c184c65676163790400310a014445495036353852656365697074446174610000001c454950323933300400310a01484549503239333052656365697074446174610001001c454950313535390400310a014845495031353539526563656970744461746100020000310a0c20657468657265756d1c72656365697074444549503635385265636569707444617461000010012c7374617475735f636f64650801087538000120757365645f676173c9010110553235360001286c6f67735f626c6f6f6d250a0114426c6f6f6d0001106c6f6773210a01205665633c4c6f673e0000350a0c20657468657265756d14626c6f636b14426c6f636b040454018905000c0118686561646572390a01184865616465720001307472616e73616374696f6e73410a01185665633c543e0001186f6d6d657273450a012c5665633c4865616465723e0000390a0c20657468657265756d186865616465721848656164657200003c012c706172656e745f686173683401104832353600012c6f6d6d6572735f686173683401104832353600012c62656e6566696369617279910101104831363000012873746174655f726f6f74340110483235360001447472616e73616374696f6e735f726f6f743401104832353600013472656365697074735f726f6f74340110483235360001286c6f67735f626c6f6f6d250a0114426c6f6f6d000128646966666963756c7479c9010110553235360001186e756d626572c9010110553235360001246761735f6c696d6974c9010110553235360001206761735f75736564c90101105532353600012474696d657374616d7030010c75363400012865787472615f6461746138011442797465730001206d69785f68617368340110483235360001146e6f6e63653d0a010c48363400003d0a0c38657468657265756d5f747970657310686173680c48363400000400a902011c5b75383b20385d0000410a000002890500450a000002390a00490a0000022d0a004d0a0000021d0a00510a0c3c70616c6c65745f657468657265756d1870616c6c6574144572726f7204045400010840496e76616c69645369676e6174757265000004545369676e617475726520697320696e76616c69642e305072654c6f67457869737473000104d85072652d6c6f672069732070726573656e742c207468657265666f7265207472616e73616374206973206e6f7420616c6c6f7765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e550a082870616c6c65745f65766d30436f64654d65746164617461000008011073697a6530010c75363400011068617368340110483235360000590a00000408910134005d0a0c2870616c6c65745f65766d1870616c6c6574144572726f720404540001342842616c616e63654c6f77000004904e6f7420656e6f7567682062616c616e636520746f20706572666f726d20616374696f6e2c4665654f766572666c6f770001048043616c63756c6174696e6720746f74616c20666565206f766572666c6f7765643c5061796d656e744f766572666c6f770002049043616c63756c6174696e6720746f74616c207061796d656e74206f766572666c6f7765643857697468647261774661696c65640003044c576974686472617720666565206661696c6564384761735072696365546f6f4c6f770004045447617320707269636520697320746f6f206c6f772e30496e76616c69644e6f6e6365000504404e6f6e636520697320696e76616c6964384761734c696d6974546f6f4c6f7700060454476173206c696d697420697320746f6f206c6f772e3c4761734c696d6974546f6f4869676800070458476173206c696d697420697320746f6f20686967682e38496e76616c6964436861696e49640008046054686520636861696e20696420697320696e76616c69642e40496e76616c69645369676e617475726500090464746865207369676e617475726520697320696e76616c69642e285265656e7472616e6379000a043845564d207265656e7472616e6379685472616e73616374696f6e4d757374436f6d6546726f6d454f41000b04244549502d333630372c24556e646566696e6564000c0440556e646566696e6564206572726f722e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e610a0c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c6574144572726f720404540001045c4d617841646472657373436f756e744578636565646564000004784d6178696d756d206164647265737320636f756e74206578636565646564048054686520604572726f726020656e756d206f6620746869732070616c6c65742e650a0000040830d90100690a0c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144572726f7204045400012060496e76616c6964457468657265756d5369676e61747572650000046c496e76616c696420457468657265756d207369676e61747572652e58496e76616c69644e61746976655369676e617475726500010488496e76616c6964204e617469766520287372323535313929207369676e617475726550496e76616c69644e61746976654163636f756e740002047c496e76616c6964204e6174697665206163636f756e74206465636f64696e67405369676e65724861734e6f436c61696d00030478457468657265756d206164647265737320686173206e6f20636c61696d2e4053656e6465724861734e6f436c61696d000404b04163636f756e742049442073656e64696e67207472616e73616374696f6e20686173206e6f20636c61696d2e30506f74556e646572666c6f77000508490154686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061306c6f676963206572726f722e40496e76616c696453746174656d656e740006049041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e4c56657374656442616c616e6365457869737473000704a4546865206163636f756e7420616c7265616479206861732061207665737465642062616c616e63652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e6d0a00000408710a1800710a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401750a045300000400790a01185665633c543e0000750a083070616c6c65745f70726f78793c50726f7879446566696e6974696f6e0c244163636f756e74496401002450726f78795479706501e5012c426c6f636b4e756d6265720130000c012064656c65676174650001244163636f756e74496400012870726f78795f74797065e501012450726f78795479706500011464656c617930012c426c6f636b4e756d6265720000790a000002750a007d0a00000408810a1800810a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401850a045300000400890a01185665633c543e0000850a083070616c6c65745f70726f787930416e6e6f756e63656d656e740c244163636f756e7449640100104861736801342c426c6f636b4e756d6265720130000c01107265616c0001244163636f756e74496400012463616c6c5f686173683401104861736800011868656967687430012c426c6f636b4e756d6265720000890a000002850a008d0a0c3070616c6c65745f70726f78791870616c6c6574144572726f720404540001201c546f6f4d616e79000004210154686572652061726520746f6f206d616e792070726f786965732072656769737465726564206f7220746f6f206d616e7920616e6e6f756e63656d656e74732070656e64696e672e204e6f74466f756e640001047450726f787920726567697374726174696f6e206e6f7420666f756e642e204e6f7450726f7879000204cc53656e646572206973206e6f7420612070726f7879206f6620746865206163636f756e7420746f2062652070726f786965642e2c556e70726f787961626c650003042101412063616c6c20776869636820697320696e636f6d70617469626c652077697468207468652070726f7879207479706527732066696c7465722077617320617474656d707465642e244475706c69636174650004046c4163636f756e7420697320616c726561647920612070726f78792e304e6f5065726d697373696f6e000504150143616c6c206d6179206e6f74206265206d6164652062792070726f78792062656361757365206974206d617920657363616c617465206974732070726976696c656765732e2c556e616e6e6f756e636564000604d0416e6e6f756e63656d656e742c206966206d61646520617420616c6c2c20776173206d61646520746f6f20726563656e746c792e2c4e6f53656c6650726f78790007046443616e6e6f74206164642073656c662061732070726f78792e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e910a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f724d6574616461746114244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301950a344d6178426c75657072696e747301990a001801147374616b6518011c42616c616e636500014064656c65676174696f6e5f636f756e7410010c75333200011c726571756573749d0a01a04f7074696f6e3c4f70657261746f72426f6e644c657373526571756573743c42616c616e63653e3e00012c64656c65676174696f6e73a50a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e000118737461747573b10a01384f70657261746f72537461747573000134626c75657072696e745f696473b50a0178426f756e6465645665633c7533322c204d6178426c75657072696e74733e0000950a085874616e676c655f746573746e65745f72756e74696d65384d617844656c65676174696f6e7300000000990a085874616e676c655f746573746e65745f72756e74696d65544d61784f70657261746f72426c75657072696e7473000000009d0a04184f7074696f6e04045401a10a0108104e6f6e6500000010536f6d650400a10a0000010000a10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f725c4f70657261746f72426f6e644c65737352657175657374041c42616c616e6365011800080118616d6f756e7418011c42616c616e6365000130726571756573745f74696d65100128526f756e64496e6465780000a50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401a90a045300000400ad0a01185665633c543e0000a90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f723444656c656761746f72426f6e640c244163636f756e74496401001c42616c616e636501181c417373657449640118000c012464656c656761746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e0000ad0a000002a90a00b10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72384f70657261746f7253746174757300010c1841637469766500000020496e6163746976650001001c4c656176696e670400100128526f756e64496e64657800020000b50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400450401185665633c543e0000b90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f72536e617073686f7410244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301950a000801147374616b6518011c42616c616e636500012c64656c65676174696f6e73a50a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e0000bd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f724444656c656761746f724d657461646174611c244163636f756e74496401001c42616c616e636501181c4173736574496401184c4d61785769746864726177526571756573747301c10a384d617844656c65676174696f6e7301950a484d6178556e7374616b65526571756573747301c50a344d6178426c75657072696e7473010d06001401206465706f73697473c90a018442547265654d61703c41737365743c417373657449643e2c2042616c616e63653e00014477697468647261775f7265717565737473d50a010901426f756e6465645665633c5769746864726177526571756573743c417373657449642c2042616c616e63653e2c204d6178576974686472617752657175657374733e00012c64656c65676174696f6e73e10a016901426f756e6465645665633c426f6e64496e666f44656c656761746f723c4163636f756e7449642c2042616c616e63652c20417373657449642c204d6178426c75657072696e74733e0a2c204d617844656c65676174696f6e733e00016864656c656761746f725f756e7374616b655f7265717565737473ed0a016d01426f756e6465645665633c426f6e644c657373526571756573743c4163636f756e7449642c20417373657449642c2042616c616e63652c204d6178426c75657072696e74733e2c0a4d6178556e7374616b6552657175657374733e000118737461747573f90a013c44656c656761746f725374617475730000c10a085874616e676c655f746573746e65745f72756e74696d654c4d61785769746864726177526571756573747300000000c50a085874616e676c655f746573746e65745f72756e74696d65484d6178556e7374616b65526571756573747300000000c90a042042547265654d617008044b01f10104560118000400cd0a000000cd0a000002d10a00d10a00000408f1011800d50a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d90a045300000400dd0a01185665633c543e0000d90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c576974686472617752657175657374081c4173736574496401181c42616c616e63650118000c012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e6465780000dd0a000002d90a00e10a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e50a045300000400e90a01185665633c543e0000e50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f7244426f6e64496e666f44656c656761746f7210244163636f756e74496401001c42616c616e636501181c417373657449640118344d6178426c75657072696e7473010d06001001206f70657261746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e00014c626c75657072696e745f73656c656374696f6e090601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000e90a000002e50a00ed0a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401f10a045300000400f50a01185665633c543e0000f10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c426f6e644c6573735265717565737410244163636f756e74496401001c4173736574496401181c42616c616e63650118344d6178426c75657072696e7473010d06001401206f70657261746f720001244163636f756e74496400012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e64657800014c626c75657072696e745f73656c656374696f6e090601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000f50a000002f10a00f90a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c44656c656761746f7253746174757300010818416374697665000000404c656176696e675363686564756c65640400100128526f756e64496e64657800010000fd0a000002f10100010b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647330526577617264436f6e666967081c5661756c74496401181c42616c616e636501180008011c636f6e66696773050b01d442547265654d61703c5661756c7449642c20526577617264436f6e666967466f7241737365745661756c743c42616c616e63653e3e00016477686974656c69737465645f626c75657072696e745f696473150601205665633c7536343e0000050b042042547265654d617008044b0118045601090b0004000d0b000000090b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065731c7265776172647364526577617264436f6e666967466f7241737365745661756c74041c42616c616e636501180008010c617079f501011c50657263656e7400010c63617018011c42616c616e636500000d0b000002110b00110b0000040818090b00150b0c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144572726f720404540001c83c416c72656164794f70657261746f720000048c546865206163636f756e7420697320616c726561647920616e206f70657261746f722e28426f6e64546f6f4c6f7700010470546865207374616b6520616d6f756e7420697320746f6f206c6f772e344e6f74416e4f70657261746f720002047c546865206163636f756e74206973206e6f7420616e206f70657261746f722e2843616e6e6f744578697400030460546865206163636f756e742063616e6e6f7420657869742e38416c72656164794c656176696e6700040480546865206f70657261746f7220697320616c7265616479206c656176696e672e484e6f744c656176696e674f70657261746f72000504a8546865206163636f756e74206973206e6f74206c656176696e6720617320616e206f70657261746f722e3c4e6f744c656176696e67526f756e64000604cc54686520726f756e6420646f6573206e6f74206d6174636820746865207363686564756c6564206c6561766520726f756e642e584c656176696e67526f756e644e6f7452656163686564000704644c656176696e6720726f756e64206e6f7420726561636865644c4e6f5363686564756c6564426f6e644c657373000804985468657265206973206e6f207363686564756c656420756e7374616b6520726571756573742e6c426f6e644c657373526571756573744e6f745361746973666965640009049454686520756e7374616b652072657175657374206973206e6f74207361746973666965642e444e6f744163746976654f70657261746f72000a046c546865206f70657261746f72206973206e6f74206163746976652e484e6f744f66666c696e654f70657261746f72000b0470546865206f70657261746f72206973206e6f74206f66666c696e652e40416c726561647944656c656761746f72000c048c546865206163636f756e7420697320616c726561647920612064656c656761746f722e304e6f7444656c656761746f72000d047c546865206163636f756e74206973206e6f7420612064656c656761746f722e70576974686472617752657175657374416c7265616479457869737473000e048841207769746864726177207265717565737420616c7265616479206578697374732e4c496e73756666696369656e7442616c616e6365000f0494546865206163636f756e742068617320696e73756666696369656e742062616c616e63652e444e6f576974686472617752657175657374001004745468657265206973206e6f20776974686472617720726571756573742e444e6f426f6e644c65737352657175657374001104705468657265206973206e6f20756e7374616b6520726571756573742e40426f6e644c6573734e6f7452656164790012048454686520756e7374616b652072657175657374206973206e6f742072656164792e70426f6e644c65737352657175657374416c7265616479457869737473001304844120756e7374616b65207265717565737420616c7265616479206578697374732e6041637469766553657276696365735573696e674173736574001404a854686572652061726520616374697665207365727669636573207573696e67207468652061737365742e484e6f41637469766544656c65676174696f6e001504785468657265206973206e6f74206163746976652064656c65676174696f6e4c41737365744e6f7457686974656c697374656400160470546865206173736574206973206e6f742077686974656c6973746564344e6f74417574686f72697a6564001704cc546865206f726967696e206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e544d6178426c75657072696e74734578636565646564001804944d6178696d756d206e756d626572206f6620626c75657072696e74732065786365656465643441737365744e6f74466f756e6400190464546865206173736574204944206973206e6f7420666f756e646c426c75657072696e74416c726561647957686974656c6973746564001a049c54686520626c75657072696e7420494420697320616c72656164792077686974656c6973746564484e6f77697468647261775265717565737473001b04684e6f20776974686472617720726571756573747320666f756e64644e6f4d61746368696e67776974686472617752657175657374001c04884e6f206d61746368696e67207769746864726177207265716573747320666f756e644c4173736574416c7265616479496e5661756c74001d0498417373657420616c72656164792065786973747320696e206120726577617264207661756c743c41737365744e6f74496e5661756c74001e047c4173736574206e6f7420666f756e6420696e20726577617264207661756c74345661756c744e6f74466f756e64001f047c54686520726577617264207661756c7420646f6573206e6f74206578697374504475706c6963617465426c75657072696e74496400200415014572726f722072657475726e6564207768656e20747279696e6720746f20616464206120626c75657072696e74204944207468617420616c7265616479206578697374732e4c426c75657072696e7449644e6f74466f756e640021041d014572726f722072657475726e6564207768656e20747279696e6720746f2072656d6f7665206120626c75657072696e74204944207468617420646f65736e27742065786973742e384e6f74496e46697865644d6f64650022043d014572726f722072657475726e6564207768656e20747279696e6720746f206164642f72656d6f766520626c75657072696e7420494473207768696c65206e6f7420696e204669786564206d6f64652e584d617844656c65676174696f6e73457863656564656400230409014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662064656c65676174696f6e732069732065786365656465642e684d6178556e7374616b65526571756573747345786365656465640024041d014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f6620756e7374616b652072657175657374732069732065786365656465642e6c4d617857697468647261775265717565737473457863656564656400250421014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662077697468647261772072657175657374732069732065786365656465642e3c4465706f7369744f766572666c6f770026045c4465706f73697420616d6f756e74206f766572666c6f7754556e7374616b65416d6f756e74546f6f4c6172676500270444556e7374616b6520756e646572666c6f77345374616b654f766572666c6f770028046c4f766572666c6f77207768696c6520616464696e67207374616b6568496e73756666696369656e745374616b6552656d61696e696e6700290478556e646572666c6f77207768696c65207265647563696e67207374616b6544415059457863656564734d6178696d756d002a04b04150592065786365656473206d6178696d756d20616c6c6f776564206279207468652065787472696e7369633c43617043616e6e6f7442655a65726f002b04484361702063616e6e6f74206265207a65726f5443617045786365656473546f74616c537570706c79002c0484436170206578636565647320746f74616c20737570706c79206f662061737365746c50656e64696e67556e7374616b6552657175657374457869737473002d0494416e20756e7374616b65207265717565737420697320616c72656164792070656e64696e6750426c75657072696e744e6f7453656c6563746564002e047454686520626c75657072696e74206973206e6f742073656c65637465644c45524332305472616e736665724661696c6564002f04544572633230207472616e73666572206661696c65643045564d416269456e636f64650030044045564d20656e636f6465206572726f723045564d4162694465636f64650031044045564d206465636f6465206572726f7204744572726f727320656d6974746564206279207468652070616c6c65742e190b00000408001d06001d0b00000408300000210b0c4474616e676c655f7072696d69746976657320736572766963657338536572766963655265717565737410044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273250b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e000118617373657473290b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d626572000110617267732d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0001746f70657261746f72735f776974685f617070726f76616c5f7374617465310b010501426f756e6465645665633c284163636f756e7449642c20417070726f76616c5374617465292c20433a3a4d61784f70657261746f7273506572536572766963653e0000250b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401000453000004003d0201185665633c543e0000290b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540118045300000400410201185665633c543e00002d0b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540111020453000004000d0201185665633c543e0000310b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401350b0453000004003d0b01185665633c543e0000350b0000040800390b00390b0c4474616e676c655f7072696d69746976657320736572766963657334417070726f76616c537461746500010c1c50656e64696e6700000020417070726f76656404014472657374616b696e675f70657263656e74f501011c50657263656e740001002052656a6563746564000200003d0b000002350b00410b0c4474616e676c655f7072696d6974697665732073657276696365731c5365727669636510044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0108696430010c753634000124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273250b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e0001246f70657261746f7273450b01ec426f756e6465645665633c284163636f756e7449642c2050657263656e74292c20433a3a4d61784f70657261746f7273506572536572766963653e000118617373657473290b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d6265720000450b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401490b0453000004004d0b01185665633c543e0000490b0000040800f501004d0b000002490b00510b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400550b012c42547265655365743c543e0000550b0420425472656553657404045401300004001506000000590b0c4474616e676c655f7072696d6974697665732073657276696365731c4a6f6243616c6c08044300244163636f756e7449640100000c0128736572766963655f696430010c75363400010c6a6f620801087538000110617267732d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e00005d0b0c4474616e676c655f7072696d697469766573207365727669636573344a6f6243616c6c526573756c7408044300244163636f756e7449640100000c0128736572766963655f696430010c75363400011c63616c6c5f696430010c753634000118726573756c742d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0000610b0c3c70616c6c65745f736572766963657314747970657338556e6170706c696564536c61736808244163636f756e74496401001c42616c616e6365011800180128736572766963655f696430010c7536340001206f70657261746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f72746572733d0201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000650b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019101045300000400c90501185665633c543e0000690b0c4474616e676c655f7072696d6974697665732073657276696365733c4f70657261746f7250726f66696c65040443000008012073657276696365736d0b01bc426f756e64656442547265655365743c7536342c20433a3a4d617853657276696365735065724f70657261746f723e000128626c75657072696e7473710b01c4426f756e64656442547265655365743c7536342c20433a3a4d6178426c75657072696e74735065724f70657261746f723e00006d0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400550b012c42547265655365743c543e0000710b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400550b012c42547265655365743c543e0000750b0c4474616e676c655f7072696d6974697665732073657276696365735453746167696e67536572766963655061796d656e740c244163636f756e74496401001c4173736574496401181c42616c616e6365011800100128726571756573745f696430010c753634000124726566756e645f746f790b01484163636f756e743c4163636f756e7449643e0001146173736574f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e63650000790b0c4474616e676c655f7072696d6974697665731474797065731c4163636f756e7404244163636f756e7449640100010808496404000001244163636f756e7449640000001c4164647265737304009101013473705f636f72653a3a48313630000100007d0b0c3c70616c6c65745f7365727669636573186d6f64756c65144572726f720404540001ac44426c75657072696e744e6f74466f756e6400000490546865207365727669636520626c75657072696e7420776173206e6f7420666f756e642e70426c75657072696e744372656174696f6e496e74657272757074656400010488426c75657072696e74206372656174696f6e20697320696e7465727275707465642e44416c726561647952656769737465726564000204bc5468652063616c6c657220697320616c726561647920726567697374657265642061732061206f70657261746f722e60496e76616c6964526567697374726174696f6e496e707574000304ec5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2062652061206f70657261746f722e584e6f74416c6c6f776564546f556e7265676973746572000404a8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f20756e72656769737465722e784e6f74416c6c6f776564546f557064617465507269636554617267657473000504e8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f2075706461746520746865697220707269636520746172676574732e4c496e76616c696452657175657374496e707574000604fc5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2072657175657374206120736572766963652e4c496e76616c69644a6f6243616c6c496e707574000704e05468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2063616c6c2061206a6f622e40496e76616c69644a6f62526573756c74000804a85468652063616c6c65722070726f766964656420616e20696e76616c6964206a6f6220726573756c742e344e6f7452656769737465726564000904ac5468652063616c6c6572206973206e6f7420726567697374657265642061732061206f70657261746f722e4c417070726f76616c496e746572727570746564000a0480417070726f76616c2050726f6365737320697320696e7465727275707465642e5052656a656374696f6e496e746572727570746564000b048452656a656374696f6e2050726f6365737320697320696e7465727275707465642e5853657276696365526571756573744e6f74466f756e64000c04885468652073657276696365207265717565737420776173206e6f7420666f756e642e8053657276696365496e697469616c697a6174696f6e496e746572727570746564000d048c5365727669636520496e697469616c697a6174696f6e20696e7465727275707465642e3c536572766963654e6f74466f756e64000e0468546865207365727669636520776173206e6f7420666f756e642e585465726d696e6174696f6e496e746572727570746564000f04bc546865207465726d696e6174696f6e206f662074686520736572766963652077617320696e7465727275707465642e2454797065436865636b0400810b013854797065436865636b4572726f72001004fc416e206572726f72206f63637572726564207768696c65207479706520636865636b696e67207468652070726f766964656420696e70757420696e7075742e6c4d61785065726d697474656443616c6c65727345786365656465640011041901546865206d6178696d756d206e756d626572206f66207065726d69747465642063616c6c65727320706572207365727669636520686173206265656e2065786365656465642e6c4d61785365727669636550726f7669646572734578636565646564001204f8546865206d6178696d756d206e756d626572206f66206f70657261746f727320706572207365727669636520686173206265656e2065786365656465642e684d61785365727669636573506572557365724578636565646564001304e8546865206d6178696d756d206e756d626572206f6620736572766963657320706572207573657220686173206265656e2065786365656465642e444d61784669656c64734578636565646564001404ec546865206d6178696d756d206e756d626572206f66206669656c647320706572207265717565737420686173206265656e2065786365656465642e50417070726f76616c4e6f74526571756573746564001504f054686520617070726f76616c206973206e6f742072657175657374656420666f7220746865206f70657261746f7220287468652063616c6c6572292e544a6f62446566696e6974696f6e4e6f74466f756e6400160cb054686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f742065786973742e590154686973206572726f722069732072657475726e6564207768656e2074686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f7420657869737420696e20746865207365727669636528626c75657072696e742e60536572766963654f724a6f6243616c6c4e6f74466f756e64001704c4456974686572207468652073657276696365206f7220746865206a6f622063616c6c20776173206e6f7420666f756e642e544a6f6243616c6c526573756c744e6f74466f756e64001804a454686520726573756c74206f6620746865206a6f622063616c6c20776173206e6f7420666f756e642e3045564d416269456e636f6465001904b4416e206572726f72206f63637572726564207768696c6520656e636f64696e67207468652045564d204142492e3045564d4162694465636f6465001a04b4416e206572726f72206f63637572726564207768696c65206465636f64696e67207468652045564d204142492e5c4f70657261746f7250726f66696c654e6f74466f756e64001b046c4f70657261746f722070726f66696c65206e6f7420666f756e642e784d6178536572766963657350657250726f76696465724578636565646564001c04c04d6178696d756d206e756d626572206f66207365727669636573207065722050726f766964657220726561636865642e444f70657261746f724e6f74416374697665001d045901546865206f70657261746f72206973206e6f74206163746976652c20656e73757265206f70657261746f72207374617475732069732041435449564520696e206d756c74692d61737365742d64656c65676174696f6e404e6f41737365747350726f7669646564001e040d014e6f206173736574732070726f766964656420666f722074686520736572766963652c206174206c65617374206f6e652061737365742069732072657175697265642e6c4d6178417373657473506572536572766963654578636565646564001f04ec546865206d6178696d756d206e756d626572206f662061737365747320706572207365727669636520686173206265656e2065786365656465642e4c4f6666656e6465724e6f744f70657261746f72002004984f6666656e646572206973206e6f7420612072656769737465726564206f70657261746f722e644f6666656e6465724e6f744163746976654f70657261746f720021048c4f6666656e646572206973206e6f7420616e20616374697665206f70657261746f722e404e6f536c617368696e674f726967696e0022042101546865205365727669636520426c75657072696e7420646964206e6f742072657475726e206120736c617368696e67206f726967696e20666f72207468697320736572766963652e3c4e6f446973707574654f726967696e0023041d01546865205365727669636520426c75657072696e7420646964206e6f742072657475726e20612064697370757465206f726967696e20666f72207468697320736572766963652e58556e6170706c696564536c6173684e6f74466f756e640024048854686520556e6170706c69656420536c61736820617265206e6f7420666f756e642eb44d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64002504110154686520537570706c696564204d617374657220426c75657072696e742053657276696365204d616e61676572205265766973696f6e206973206e6f7420666f756e642ec04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e73457863656564656400260415014d6178696d756d206e756d626572206f66204d617374657220426c75657072696e742053657276696365204d616e61676572207265766973696f6e7320726561636865642e4c45524332305472616e736665724661696c656400270468546865204552433230207472616e73666572206661696c65642e404d697373696e6745564d4f726967696e002804a44d697373696e672045564d204f726967696e20666f72207468652045564d20657865637574696f6e2e48457870656374656445564d41646472657373002904a8457870656374656420746865206163636f756e7420746f20626520616e2045564d20616464726573732e4445787065637465644163636f756e744964002a04a4457870656374656420746865206163636f756e7420746f20626520616e206163636f756e742049442e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e810b0c4474616e676c655f7072696d6974697665732073657276696365733854797065436865636b4572726f7200010c50417267756d656e74547970654d69736d617463680c0114696e64657808010875380001206578706563746564410601244669656c645479706500011861637475616c410601244669656c6454797065000000484e6f74456e6f756768417267756d656e74730801206578706563746564080108753800011861637475616c080108753800010048526573756c74547970654d69736d617463680c0114696e64657808010875380001206578706563746564410601244669656c645479706500011861637475616c410601244669656c645479706500020000850b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c3c426f6e646564506f6f6c496e6e65720404540000100128636f6d6d697373696f6e890b0134436f6d6d697373696f6e3c543e000114726f6c6573910b015c506f6f6c526f6c65733c543a3a4163636f756e7449643e000114737461746549020124506f6f6c53746174650001206d65746164617461950b013c506f6f6c4d657461646174613c543e0000890b104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e28436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61784909013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f726174658d0b01bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d7d0401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e510201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e00008d0b04184f7074696f6e040454014d020108104e6f6e6500000010536f6d6504004d020000010000910b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e0000950b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c30506f6f6c4d6574616461746104045400000801106e616d65f10601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6ef90601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e0000990b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e74657291070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e00009d0b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7320537562506f6f6c7304045400000801186e6f5f657261a10b0134556e626f6e64506f6f6c3c543e000120776974685f657261a50b010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e0000a10b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e0000a50b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601a10b045300000400a90b013842547265654d61703c4b2c20563e0000a90b042042547265654d617008044b0110045601a10b000400ad0b000000ad0b000002b10b00b10b0000040810a10b00b50b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000b90b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7328506f6f6c4d656d6265720404540000040138756e626f6e64696e675f65726173bd0b010901426f756e64656442547265654d61703c457261496e6465782c2028506f6f6c49642c2042616c616e63654f663c543e292c20543a3a4d6178556e626f6e64696e673e0000bd0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b01100456013d09045300000400c10b013842547265654d61703c4b2c20563e0000c10b042042547265654d617008044b01100456013d09000400c50b000000c50b000002c90b00c90b00000408103d0900cd0b0c4470616c6c65745f74616e676c655f6c73741474797065733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000d10b0c4470616c6c65745f74616e676c655f6c73741870616c6c6574144572726f7204045400018430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e3846756c6c79556e626f6e64696e670004083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740005040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790006044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000714290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0008042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e670009085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000a04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000b043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000c047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000d04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000e049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e67655374617465000f048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001004b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001104ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e736976650400d50b0138446566656e736976654572726f720012083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001304bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640014041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001504ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001604e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400170409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640018040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001904a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001a048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001b0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001c049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001d04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001e04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e5c506f6f6c546f6b656e4372656174696f6e4661696c6564001f046c506f6f6c20746f6b656e206372656174696f6e206661696c65642e444e6f42616c616e6365546f556e626f6e64002004544e6f2062616c616e636520746f20756e626f6e642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed50b0c4470616c6c65745f74616e676c655f6c73741870616c6c657438446566656e736976654572726f72000114684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c7900040000d90b0c4466705f73656c665f636f6e7461696e65644c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c1021043616c6c01b902245369676e617475726501610514457874726101dd0b0004000d0c01250173705f72756e74696d653a3a67656e657269633a3a556e636865636b656445787472696e7369633c416464726573732c2043616c6c2c205369676e61747572652c2045787472610a3e0000dd0b00000424e10be50be90bed0bf10bf90bfd0b010c050c00e10b10306672616d655f73797374656d28657874656e73696f6e7354636865636b5f6e6f6e5f7a65726f5f73656e64657248436865636b4e6f6e5a65726f53656e64657204045400000000e50b10306672616d655f73797374656d28657874656e73696f6e7348636865636b5f737065635f76657273696f6e40436865636b5370656356657273696f6e04045400000000e90b10306672616d655f73797374656d28657874656e73696f6e7340636865636b5f74785f76657273696f6e38436865636b547856657273696f6e04045400000000ed0b10306672616d655f73797374656d28657874656e73696f6e7334636865636b5f67656e6573697330436865636b47656e6573697304045400000000f10b10306672616d655f73797374656d28657874656e73696f6e733c636865636b5f6d6f7274616c69747938436865636b4d6f7274616c69747904045400000400f50b010c4572610000f50b102873705f72756e74696d651c67656e657269630c6572610c4572610001010420496d6d6f7274616c0000001c4d6f7274616c31040008000001001c4d6f7274616c32040008000002001c4d6f7274616c33040008000003001c4d6f7274616c34040008000004001c4d6f7274616c35040008000005001c4d6f7274616c36040008000006001c4d6f7274616c37040008000007001c4d6f7274616c38040008000008001c4d6f7274616c3904000800000900204d6f7274616c313004000800000a00204d6f7274616c313104000800000b00204d6f7274616c313204000800000c00204d6f7274616c313304000800000d00204d6f7274616c313404000800000e00204d6f7274616c313504000800000f00204d6f7274616c313604000800001000204d6f7274616c313704000800001100204d6f7274616c313804000800001200204d6f7274616c313904000800001300204d6f7274616c323004000800001400204d6f7274616c323104000800001500204d6f7274616c323204000800001600204d6f7274616c323304000800001700204d6f7274616c323404000800001800204d6f7274616c323504000800001900204d6f7274616c323604000800001a00204d6f7274616c323704000800001b00204d6f7274616c323804000800001c00204d6f7274616c323904000800001d00204d6f7274616c333004000800001e00204d6f7274616c333104000800001f00204d6f7274616c333204000800002000204d6f7274616c333304000800002100204d6f7274616c333404000800002200204d6f7274616c333504000800002300204d6f7274616c333604000800002400204d6f7274616c333704000800002500204d6f7274616c333804000800002600204d6f7274616c333904000800002700204d6f7274616c343004000800002800204d6f7274616c343104000800002900204d6f7274616c343204000800002a00204d6f7274616c343304000800002b00204d6f7274616c343404000800002c00204d6f7274616c343504000800002d00204d6f7274616c343604000800002e00204d6f7274616c343704000800002f00204d6f7274616c343804000800003000204d6f7274616c343904000800003100204d6f7274616c353004000800003200204d6f7274616c353104000800003300204d6f7274616c353204000800003400204d6f7274616c353304000800003500204d6f7274616c353404000800003600204d6f7274616c353504000800003700204d6f7274616c353604000800003800204d6f7274616c353704000800003900204d6f7274616c353804000800003a00204d6f7274616c353904000800003b00204d6f7274616c363004000800003c00204d6f7274616c363104000800003d00204d6f7274616c363204000800003e00204d6f7274616c363304000800003f00204d6f7274616c363404000800004000204d6f7274616c363504000800004100204d6f7274616c363604000800004200204d6f7274616c363704000800004300204d6f7274616c363804000800004400204d6f7274616c363904000800004500204d6f7274616c373004000800004600204d6f7274616c373104000800004700204d6f7274616c373204000800004800204d6f7274616c373304000800004900204d6f7274616c373404000800004a00204d6f7274616c373504000800004b00204d6f7274616c373604000800004c00204d6f7274616c373704000800004d00204d6f7274616c373804000800004e00204d6f7274616c373904000800004f00204d6f7274616c383004000800005000204d6f7274616c383104000800005100204d6f7274616c383204000800005200204d6f7274616c383304000800005300204d6f7274616c383404000800005400204d6f7274616c383504000800005500204d6f7274616c383604000800005600204d6f7274616c383704000800005700204d6f7274616c383804000800005800204d6f7274616c383904000800005900204d6f7274616c393004000800005a00204d6f7274616c393104000800005b00204d6f7274616c393204000800005c00204d6f7274616c393304000800005d00204d6f7274616c393404000800005e00204d6f7274616c393504000800005f00204d6f7274616c393604000800006000204d6f7274616c393704000800006100204d6f7274616c393804000800006200204d6f7274616c393904000800006300244d6f7274616c31303004000800006400244d6f7274616c31303104000800006500244d6f7274616c31303204000800006600244d6f7274616c31303304000800006700244d6f7274616c31303404000800006800244d6f7274616c31303504000800006900244d6f7274616c31303604000800006a00244d6f7274616c31303704000800006b00244d6f7274616c31303804000800006c00244d6f7274616c31303904000800006d00244d6f7274616c31313004000800006e00244d6f7274616c31313104000800006f00244d6f7274616c31313204000800007000244d6f7274616c31313304000800007100244d6f7274616c31313404000800007200244d6f7274616c31313504000800007300244d6f7274616c31313604000800007400244d6f7274616c31313704000800007500244d6f7274616c31313804000800007600244d6f7274616c31313904000800007700244d6f7274616c31323004000800007800244d6f7274616c31323104000800007900244d6f7274616c31323204000800007a00244d6f7274616c31323304000800007b00244d6f7274616c31323404000800007c00244d6f7274616c31323504000800007d00244d6f7274616c31323604000800007e00244d6f7274616c31323704000800007f00244d6f7274616c31323804000800008000244d6f7274616c31323904000800008100244d6f7274616c31333004000800008200244d6f7274616c31333104000800008300244d6f7274616c31333204000800008400244d6f7274616c31333304000800008500244d6f7274616c31333404000800008600244d6f7274616c31333504000800008700244d6f7274616c31333604000800008800244d6f7274616c31333704000800008900244d6f7274616c31333804000800008a00244d6f7274616c31333904000800008b00244d6f7274616c31343004000800008c00244d6f7274616c31343104000800008d00244d6f7274616c31343204000800008e00244d6f7274616c31343304000800008f00244d6f7274616c31343404000800009000244d6f7274616c31343504000800009100244d6f7274616c31343604000800009200244d6f7274616c31343704000800009300244d6f7274616c31343804000800009400244d6f7274616c31343904000800009500244d6f7274616c31353004000800009600244d6f7274616c31353104000800009700244d6f7274616c31353204000800009800244d6f7274616c31353304000800009900244d6f7274616c31353404000800009a00244d6f7274616c31353504000800009b00244d6f7274616c31353604000800009c00244d6f7274616c31353704000800009d00244d6f7274616c31353804000800009e00244d6f7274616c31353904000800009f00244d6f7274616c3136300400080000a000244d6f7274616c3136310400080000a100244d6f7274616c3136320400080000a200244d6f7274616c3136330400080000a300244d6f7274616c3136340400080000a400244d6f7274616c3136350400080000a500244d6f7274616c3136360400080000a600244d6f7274616c3136370400080000a700244d6f7274616c3136380400080000a800244d6f7274616c3136390400080000a900244d6f7274616c3137300400080000aa00244d6f7274616c3137310400080000ab00244d6f7274616c3137320400080000ac00244d6f7274616c3137330400080000ad00244d6f7274616c3137340400080000ae00244d6f7274616c3137350400080000af00244d6f7274616c3137360400080000b000244d6f7274616c3137370400080000b100244d6f7274616c3137380400080000b200244d6f7274616c3137390400080000b300244d6f7274616c3138300400080000b400244d6f7274616c3138310400080000b500244d6f7274616c3138320400080000b600244d6f7274616c3138330400080000b700244d6f7274616c3138340400080000b800244d6f7274616c3138350400080000b900244d6f7274616c3138360400080000ba00244d6f7274616c3138370400080000bb00244d6f7274616c3138380400080000bc00244d6f7274616c3138390400080000bd00244d6f7274616c3139300400080000be00244d6f7274616c3139310400080000bf00244d6f7274616c3139320400080000c000244d6f7274616c3139330400080000c100244d6f7274616c3139340400080000c200244d6f7274616c3139350400080000c300244d6f7274616c3139360400080000c400244d6f7274616c3139370400080000c500244d6f7274616c3139380400080000c600244d6f7274616c3139390400080000c700244d6f7274616c3230300400080000c800244d6f7274616c3230310400080000c900244d6f7274616c3230320400080000ca00244d6f7274616c3230330400080000cb00244d6f7274616c3230340400080000cc00244d6f7274616c3230350400080000cd00244d6f7274616c3230360400080000ce00244d6f7274616c3230370400080000cf00244d6f7274616c3230380400080000d000244d6f7274616c3230390400080000d100244d6f7274616c3231300400080000d200244d6f7274616c3231310400080000d300244d6f7274616c3231320400080000d400244d6f7274616c3231330400080000d500244d6f7274616c3231340400080000d600244d6f7274616c3231350400080000d700244d6f7274616c3231360400080000d800244d6f7274616c3231370400080000d900244d6f7274616c3231380400080000da00244d6f7274616c3231390400080000db00244d6f7274616c3232300400080000dc00244d6f7274616c3232310400080000dd00244d6f7274616c3232320400080000de00244d6f7274616c3232330400080000df00244d6f7274616c3232340400080000e000244d6f7274616c3232350400080000e100244d6f7274616c3232360400080000e200244d6f7274616c3232370400080000e300244d6f7274616c3232380400080000e400244d6f7274616c3232390400080000e500244d6f7274616c3233300400080000e600244d6f7274616c3233310400080000e700244d6f7274616c3233320400080000e800244d6f7274616c3233330400080000e900244d6f7274616c3233340400080000ea00244d6f7274616c3233350400080000eb00244d6f7274616c3233360400080000ec00244d6f7274616c3233370400080000ed00244d6f7274616c3233380400080000ee00244d6f7274616c3233390400080000ef00244d6f7274616c3234300400080000f000244d6f7274616c3234310400080000f100244d6f7274616c3234320400080000f200244d6f7274616c3234330400080000f300244d6f7274616c3234340400080000f400244d6f7274616c3234350400080000f500244d6f7274616c3234360400080000f600244d6f7274616c3234370400080000f700244d6f7274616c3234380400080000f800244d6f7274616c3234390400080000f900244d6f7274616c3235300400080000fa00244d6f7274616c3235310400080000fb00244d6f7274616c3235320400080000fc00244d6f7274616c3235330400080000fd00244d6f7274616c3235340400080000fe00244d6f7274616c3235350400080000ff0000f90b10306672616d655f73797374656d28657874656e73696f6e732c636865636b5f6e6f6e636528436865636b4e6f6e63650404540000040065020120543a3a4e6f6e63650000fd0b10306672616d655f73797374656d28657874656e73696f6e7330636865636b5f7765696768742c436865636b57656967687404045400000000010c086870616c6c65745f7472616e73616374696f6e5f7061796d656e74604368617267655472616e73616374696f6e5061796d656e74040454000004006d01013042616c616e63654f663c543e0000050c08746672616d655f6d657461646174615f686173685f657874656e73696f6e44436865636b4d657461646174614861736804045400000401106d6f6465090c01104d6f64650000090c08746672616d655f6d657461646174615f686173685f657874656e73696f6e104d6f64650001082044697361626c65640000001c456e61626c6564000100000d0c102873705f72756e74696d651c67656e657269634c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c1021043616c6c01b902245369676e617475726501610514457874726101dd0b00040038000000110c085874616e676c655f746573746e65745f72756e74696d651c52756e74696d6500000000ac1853797374656d011853797374656d481c4163636f756e7401010402000c4101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008004e8205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e3845787472696e736963436f756e74000010040004b820546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e40496e686572656e74734170706c696564010020040004a4205768657468657220616c6c20696e686572656e74732068617665206265656e206170706c6965642e2c426c6f636b576569676874010024180000000000000488205468652063757272656e742077656967687420666f722074686520626c6f636b2e40416c6c45787472696e736963734c656e000010040004410120546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e24426c6f636b486173680101040530348000000000000000000000000000000000000000000000000000000000000000000498204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e3445787472696e736963446174610101040510380400043d012045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e184e756d626572010030200000000000000000040901205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e28506172656e744861736801003480000000000000000000000000000000000000000000000000000000000000000004702048617368206f66207468652070726576696f757320626c6f636b2e1844696765737401003c040004f020446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e184576656e747301004c04001ca0204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e001d01204e4f54453a20546865206974656d20697320756e626f756e6420616e642073686f756c64207468657265666f7265206e657665722062652072656164206f6e20636861696e2ed020497420636f756c64206f746865727769736520696e666c6174652074686520506f562073697a65206f66206120626c6f636b2e002d01204576656e747320686176652061206c6172676520696e2d6d656d6f72792073697a652e20426f7820746865206576656e747320746f206e6f7420676f206f75742d6f662d6d656d6f7279fc206a75737420696e206361736520736f6d656f6e65207374696c6c207265616473207468656d2066726f6d2077697468696e207468652072756e74696d652e284576656e74436f756e74010010100000000004b820546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e2c4576656e74546f7069637301010402345d020400282501204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e646578657394206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e00510120416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e2054686973450120616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e64e420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e005901205468652076616c756520686173207468652074797065206028426c6f636b4e756d626572466f723c543e2c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573744d012074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b0101206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e484c61737452756e74696d65557067726164650000610204000455012053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e545570677261646564546f553332526566436f756e740100200400044d012054727565206966207765206861766520757067726164656420736f207468617420607479706520526566436f756e74602069732060753332602e2046616c7365202864656661756c7429206966206e6f742e605570677261646564546f547269706c65526566436f756e740100200400085d012054727565206966207765206861766520757067726164656420736f2074686174204163636f756e74496e666f20636f6e7461696e73207468726565207479706573206f662060526566436f756e74602e2046616c736548202864656661756c7429206966206e6f742e38457865637574696f6e506861736500005902040004882054686520657865637574696f6e207068617365206f662074686520626c6f636b2e44417574686f72697a65645570677261646500006902040004b82060536f6d6560206966206120636f6465207570677261646520686173206265656e20617574686f72697a65642e016d0201581830426c6f636b576569676874737d02f901624d186c000b00204aa9d10113ffffffffffffffff4247871900010b30f6a7a72e011366666666666666a6010b0098f73e5d0113ffffffffffffffbf0100004247871900010b307efa11a3011366666666666666e6010b00204aa9d10113ffffffffffffffff01070088526a74130000000000000040424787190000000004d020426c6f636b20262065787472696e7369637320776569676874733a20626173652076616c75657320616e64206c696d6974732e2c426c6f636b4c656e6774688d023000003c00000050000000500004a820546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e38426c6f636b48617368436f756e7430200001000000000000045501204d6178696d756d206e756d626572206f6620626c6f636b206e756d62657220746f20626c6f636b2068617368206d617070696e677320746f206b65657020286f6c64657374207072756e6564206669727374292e20446257656967687495024040787d010000000000e1f505000000000409012054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e1c56657273696f6e9902c1033874616e676c652d746573746e65743874616e676c652d746573746e657401000000b40400000100000040df6acb689907609b0500000037e397fc7c91f5e40200000040fe3ad401f8959a060000009bbaa777b4c15fc401000000582211f65bb14b8905000000e65b00e46cedd0aa02000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000cbca25e39f14238702000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000ed99c5acb25eedf503000000bd78255d4feeea1f06000000a33d43f58731ad8402000000fbc577b9d747efd60100000001000000000484204765742074686520636861696e277320696e2d636f64652076657273696f6e2e2853533538507265666978e901082a0014a8205468652064657369676e61746564205353353820707265666978206f66207468697320636861696e2e0039012054686973207265706c6163657320746865202273733538466f726d6174222070726f7065727479206465636c6172656420696e2074686520636861696e20737065632e20526561736f6e20697331012074686174207468652072756e74696d652073686f756c64206b6e6f772061626f7574207468652070726566697820696e206f7264657220746f206d616b6520757365206f662069742061737020616e206964656e746966696572206f662074686520636861696e2e01ad02012454696d657374616d70012454696d657374616d70080c4e6f7701003020000000000000000004a0205468652063757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e24446964557064617465010020040010d82057686574686572207468652074696d657374616d7020686173206265656e207570646174656420696e207468697320626c6f636b2e00550120546869732076616c7565206973207570646174656420746f206074727565602075706f6e207375636365737366756c207375626d697373696f6e206f6620612074696d657374616d702062792061206e6f64652e4501204974206973207468656e20636865636b65642061742074686520656e64206f66206561636820626c6f636b20657865637574696f6e20696e2074686520606f6e5f66696e616c697a656020686f6f6b2e01b1020004344d696e696d756d506572696f643020b80b000000000000188c20546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e004d012042652061776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e4901206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f61012064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20466f72206578616d706c652c20696e2074686520417572612070616c6c65742069742077696c6c20626520646f75626c6520746869737020706572696f64206f6e2064656661756c742073657474696e67732e0002105375646f01105375646f040c4b6579000000040004842054686520604163636f756e74496460206f6620746865207375646f206b65792e01b502017c00011107036052616e646f6d6e657373436f6c6c656374697665466c6970016052616e646f6d6e657373436f6c6c656374697665466c6970043852616e646f6d4d6174657269616c0100150704000c610120536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e2054686973610120697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f664420746865206f6c6465737420686173682e00000000041841737365747301184173736574731414417373657400010402181907040004542044657461696c73206f6620616e2061737365742e1c4163636f756e74000108020221072507040004e42054686520686f6c64696e6773206f662061207370656369666963206163636f756e7420666f7220612073706563696669632061737365742e24417070726f76616c7300010c0202023107350704000c590120417070726f7665642062616c616e6365207472616e73666572732e2046697273742062616c616e63652069732074686520616d6f756e7420617070726f76656420666f72207472616e736665722e205365636f6e64e82069732074686520616d6f756e74206f662060543a3a43757272656e63796020726573657276656420666f722073746f72696e6720746869732e4901204669727374206b6579206973207468652061737365742049442c207365636f6e64206b657920697320746865206f776e657220616e64207468697264206b6579206973207468652064656c65676174652e204d65746164617461010104021839075000000000000000000000000000000000000000000458204d65746164617461206f6620616e2061737365742e2c4e657874417373657449640000180400246d012054686520617373657420494420656e666f7263656420666f7220746865206e657874206173736574206372656174696f6e2c20696620616e792070726573656e742e204f74686572776973652c20746869732073746f7261676550206974656d20686173206e6f206566666563742e00650120546869732063616e2062652075736566756c20666f722073657474696e6720757020636f6e73747261696e747320666f7220494473206f6620746865206e6577206173736574732e20466f72206578616d706c652c20627969012070726f766964696e6720616e20696e697469616c205b604e65787441737365744964605d20616e64207573696e6720746865205b6063726174653a3a4175746f496e6341737365744964605d2063616c6c6261636b2c20616ee8206175746f2d696e6372656d656e74206d6f64656c2063616e206265206170706c69656420746f20616c6c206e6577206173736574204944732e0021012054686520696e697469616c206e6578742061737365742049442063616e20626520736574207573696e6720746865205b6047656e65736973436f6e666967605d206f72207468652101205b5365744e657874417373657449645d28606d6967726174696f6e3a3a6e6578745f61737365745f69643a3a5365744e657874417373657449646029206d6967726174696f6e2e01bd02018c1c4052656d6f76654974656d734c696d69741010e80300000c5101204d6178206e756d626572206f66206974656d7320746f2064657374726f7920706572206064657374726f795f6163636f756e74736020616e64206064657374726f795f617070726f76616c73602063616c6c2e003901204d75737420626520636f6e6669677572656420746f20726573756c7420696e2061207765696768742074686174206d616b657320656163682063616c6c2066697420696e206120626c6f636b2e3041737365744465706f73697418400000e8890423c78a000000000000000004f82054686520626173696320616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f7220616e2061737365742e4c41737365744163636f756e744465706f73697418400000e8890423c78a00000000000000000845012054686520616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f722061206e6f6e2d70726f7669646572206173736574206163636f756e7420746f20626530206d61696e7461696e65642e4c4d657461646174614465706f736974426173651840000054129336377505000000000000000451012054686520626173696320616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e20616464696e67206d6574616461746120746f20796f75722061737365742e584d657461646174614465706f7369745065724279746518400000c16ff2862300000000000000000008550120546865206164646974696f6e616c2066756e64732074686174206d75737420626520726573657276656420666f7220746865206e756d626572206f6620627974657320796f752073746f726520696e20796f757228206d657461646174612e3c417070726f76616c4465706f736974184000e40b540200000000000000000000000421012054686520616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e206372656174696e672061206e657720617070726f76616c2e2c537472696e674c696d697410103200000004e020546865206d6178696d756d206c656e677468206f662061206e616d65206f722073796d626f6c2073746f726564206f6e2d636861696e2e014107052042616c616e636573012042616c616e6365731c34546f74616c49737375616e6365010018400000000000000000000000000000000004982054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e40496e61637469766549737375616e636501001840000000000000000000000000000000000409012054686520746f74616c20756e697473206f66206f75747374616e64696e672064656163746976617465642062616c616e636520696e207468652073797374656d2e1c4163636f756e74010104020014010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080600901205468652042616c616e6365732070616c6c6574206578616d706c65206f662073746f72696e67207468652062616c616e6365206f6620616e206163636f756e742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b19022020202074797065204163636f756e7453746f7265203d2053746f726167654d61705368696d3c53656c663a3a4163636f756e743c52756e74696d653e2c206672616d655f73797374656d3a3a50726f76696465723c52756e74696d653e2c204163636f756e7449642c2053656c663a3a4163636f756e74446174613c42616c616e63653e3e0c20207d102060606000150120596f752063616e20616c736f2073746f7265207468652062616c616e6365206f6620616e206163636f756e7420696e20746865206053797374656d602070616c6c65742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b7420202074797065204163636f756e7453746f7265203d2053797374656d0c20207d102060606000510120427574207468697320636f6d657320776974682074726164656f6666732c2073746f72696e67206163636f756e742062616c616e63657320696e207468652073797374656d2070616c6c65742073746f7265736d0120606672616d655f73797374656d60206461746120616c6f6e677369646520746865206163636f756e74206461746120636f6e747261727920746f2073746f72696e67206163636f756e742062616c616e63657320696e207468652901206042616c616e636573602070616c6c65742c20776869636820757365732061206053746f726167654d61706020746f2073746f72652062616c616e6365732064617461206f6e6c792e4101204e4f54453a2054686973206973206f6e6c79207573656420696e207468652063617365207468617420746869732070616c6c6574206973207573656420746f2073746f72652062616c616e6365732e144c6f636b7301010402004507040010b820416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2501204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602052657365727665730101040200550704000ca4204e616d6564207265736572766573206f6e20736f6d65206163636f756e742062616c616e6365732e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f6014486f6c6473010104020061070400046c20486f6c6473206f6e206163636f756e742062616c616e6365732e1c467265657a6573010104020075070400048820467265657a65206c6f636b73206f6e206163636f756e742062616c616e6365732e01c502019010484578697374656e7469616c4465706f736974184000e40b5402000000000000000000000020410120546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e204d5553542042452047524541544552205448414e205a45524f2100590120496620796f75202a7265616c6c792a206e65656420697420746f206265207a65726f2c20796f752063616e20656e61626c652074686520666561747572652060696e7365637572655f7a65726f5f65646020666f72610120746869732070616c6c65742e20486f77657665722c20796f7520646f20736f20617420796f7572206f776e207269736b3a20746869732077696c6c206f70656e2075702061206d616a6f7220446f5320766563746f722e590120496e206361736520796f752068617665206d756c7469706c6520736f7572636573206f662070726f7669646572207265666572656e6365732c20796f75206d617920616c736f2067657420756e65787065637465648c206265686176696f757220696620796f7520736574207468697320746f207a65726f2e00f020426f74746f6d206c696e653a20446f20796f757273656c662061206661766f757220616e64206d616b65206974206174206c65617374206f6e6521204d61784c6f636b7310103200000010f420546865206d6178696d756d206e756d626572206f66206c6f636b7320746861742073686f756c64206578697374206f6e20616e206163636f756e742edc204e6f74207374726963746c7920656e666f726365642c20627574207573656420666f722077656967687420657374696d6174696f6e2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602c4d617852657365727665731010320000000c0d0120546865206d6178696d756d206e756d626572206f66206e616d656420726573657276657320746861742063616e206578697374206f6e20616e206163636f756e742e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f60284d6178467265657a657310103200000004610120546865206d6178696d756d206e756d626572206f6620696e646976696475616c20667265657a65206c6f636b7320746861742063616e206578697374206f6e20616e206163636f756e7420617420616e792074696d652e018d0706485472616e73616374696f6e5061796d656e7401485472616e73616374696f6e5061796d656e7408444e6578744665654d756c7469706c6965720100910740000064a7b3b6e00d0000000000000000003853746f7261676556657273696f6e0100950704000000019804604f7065726174696f6e616c4665654d756c7469706c696572080405545901204120666565206d756c7469706c69657220666f7220604f7065726174696f6e616c602065787472696e7369637320746f20636f6d7075746520227669727475616c207469702220746f20626f6f73742074686569722c20607072696f726974796000510120546869732076616c7565206973206d756c7469706c69656420627920746865206066696e616c5f6665656020746f206f627461696e206120227669727475616c20746970222074686174206973206c61746572f420616464656420746f20612074697020636f6d706f6e656e7420696e20726567756c617220607072696f72697479602063616c63756c6174696f6e732e4d01204974206d65616e732074686174206120604e6f726d616c60207472616e73616374696f6e2063616e2066726f6e742d72756e20612073696d696c61726c792d73697a656420604f7065726174696f6e616c6041012065787472696e736963202877697468206e6f20746970292c20627920696e636c7564696e672061207469702076616c75652067726561746572207468616e20746865207669727475616c207469702e003c20606060727573742c69676e6f726540202f2f20466f7220604e6f726d616c608c206c6574207072696f72697479203d207072696f726974795f63616c6328746970293b0054202f2f20466f7220604f7065726174696f6e616c601101206c6574207669727475616c5f746970203d2028696e636c7573696f6e5f666565202b2074697029202a204f7065726174696f6e616c4665654d756c7469706c6965723bc4206c6574207072696f72697479203d207072696f726974795f63616c6328746970202b207669727475616c5f746970293b1020606060005101204e6f746520746861742073696e636520776520757365206066696e616c5f6665656020746865206d756c7469706c696572206170706c69657320616c736f20746f2074686520726567756c61722060746970605d012073656e74207769746820746865207472616e73616374696f6e2e20536f2c206e6f74206f6e6c7920646f657320746865207472616e73616374696f6e206765742061207072696f726974792062756d702062617365646101206f6e207468652060696e636c7573696f6e5f666565602c2062757420776520616c736f20616d706c6966792074686520696d70616374206f662074697073206170706c69656420746f20604f7065726174696f6e616c6038207472616e73616374696f6e732e000728417574686f72736869700128417574686f72736869700418417574686f720000000400046420417574686f72206f662063757272656e7420626c6f636b2e00000000081042616265011042616265442845706f6368496e64657801003020000000000000000004542043757272656e742065706f636820696e6465782e2c417574686f726974696573010099070400046c2043757272656e742065706f636820617574686f7269746965732e2c47656e65736973536c6f740100dd0220000000000000000008f82054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e205468697320697320309020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2c43757272656e74536c6f740100dd0220000000000000000004542043757272656e7420736c6f74206e756d6265722e2852616e646f6d6e65737301000480000000000000000000000000000000000000000000000000000000000000000028b8205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e002c20232053656375726974790005012054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061f8206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e7915012063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d6265727320746861742074686973150120286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e206265050120757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e0d01206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e6050656e64696e6745706f6368436f6e6669674368616e67650000e50204000461012050656e64696e672065706f636820636f6e66696775726174696f6e206368616e676520746861742077696c6c206265206170706c696564207768656e20746865206e6578742065706f636820697320656e61637465642e384e65787452616e646f6d6e657373010004800000000000000000000000000000000000000000000000000000000000000000045c204e6578742065706f63682072616e646f6d6e6573732e3c4e657874417574686f7269746965730100990704000460204e6578742065706f636820617574686f7269746965732e305365676d656e74496e6465780100101000000000247c2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e00f8205765206d616b6520612074726164652d6f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e01012057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f942060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e00ec204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e090120576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572791c2065706f63682e44556e646572436f6e737472756374696f6e0101040510a50704000415012054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2c496e697469616c697a65640000ad0704000801012054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d65601d01206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e4c417574686f7256726652616e646f6d6e65737301003d0104001015012054686973206669656c642073686f756c6420616c7761797320626520706f70756c6174656420647572696e6720626c6f636b2070726f63657373696e6720756e6c6573731901207365636f6e6461727920706c61696e20736c6f74732061726520656e61626c65642028776869636820646f6e277420636f6e7461696e206120565246206f7574707574292e0049012049742069732073657420696e20606f6e5f66696e616c697a65602c206265666f72652069742077696c6c20636f6e7461696e207468652076616c75652066726f6d20746865206c61737420626c6f636b2e2845706f636853746172740100e9024000000000000000000000000000000000145d012054686520626c6f636b206e756d62657273207768656e20746865206c61737420616e642063757272656e742065706f6368206861766520737461727465642c20726573706563746976656c7920604e2d316020616e641420604e602e4901204e4f54453a20576520747261636b207468697320697320696e206f7264657220746f20616e6e6f746174652074686520626c6f636b206e756d626572207768656e206120676976656e20706f6f6c206f66590120656e74726f7079207761732066697865642028692e652e20697420776173206b6e6f776e20746f20636861696e206f6273657276657273292e2053696e63652065706f6368732061726520646566696e656420696e590120736c6f74732c207768696368206d617920626520736b69707065642c2074686520626c6f636b206e756d62657273206d6179206e6f74206c696e6520757020776974682074686520736c6f74206e756d626572732e204c6174656e65737301003020000000000000000014d820486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e001501205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e65642075701101206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636bb020657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2c45706f6368436f6e6669670000c50704000861012054686520636f6e66696775726174696f6e20666f72207468652063757272656e742065706f63682e2053686f756c64206e6576657220626520604e6f6e656020617320697420697320696e697469616c697a656420696e242067656e657369732e3c4e65787445706f6368436f6e6669670000c5070400082d012054686520636f6e66696775726174696f6e20666f7220746865206e6578742065706f63682c20604e6f6e65602069662074686520636f6e6669672077696c6c206e6f74206368616e6765e82028796f752063616e2066616c6c6261636b20746f206045706f6368436f6e6669676020696e737465616420696e20746861742063617365292e34536b697070656445706f6368730100c90704002029012041206c697374206f6620746865206c6173742031303020736b69707065642065706f63687320616e642074686520636f72726573706f6e64696e672073657373696f6e20696e64657870207768656e207468652065706f63682077617320736b69707065642e0031012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f663501206d75737420636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e656564206139012077617920746f2074696520746f6765746865722073657373696f6e7320616e642065706f636820696e64696365732c20692e652e207765206e65656420746f2076616c69646174652074686174290120612076616c696461746f722077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e64207768617420746865b0206163746976652065706f636820696e6465782077617320647572696e6720746861742073657373696f6e2e01cd0200103445706f63684475726174696f6e3020b0040000000000000cec2054686520616d6f756e74206f662074696d652c20696e20736c6f74732c207468617420656163682065706f63682073686f756c64206c6173742e1901204e4f54453a2043757272656e746c79206974206973206e6f7420706f737369626c6520746f206368616e6765207468652065706f6368206475726174696f6e20616674657221012074686520636861696e2068617320737461727465642e20417474656d7074696e6720746f20646f20736f2077696c6c20627269636b20626c6f636b2070726f64756374696f6e2e444578706563746564426c6f636b54696d653020701700000000000014050120546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e67110120626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f75740501207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f740901206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473a0207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e384d6178417574686f7269746965731010e80300000488204d6178206e756d626572206f6620617574686f72697469657320616c6c6f776564344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e01cd07091c4772616e647061011c4772616e6470611c1453746174650100d10704000490205374617465206f66207468652063757272656e7420617574686f72697479207365742e3450656e64696e674368616e67650000d507040004c42050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e284e657874466f72636564000030040004bc206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e1c5374616c6c65640000e9020400049020607472756560206966207765206172652063757272656e746c79207374616c6c65642e3043757272656e745365744964010030200000000000000000085d0120546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c697469657329c420696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e30536574496453657373696f6e00010405301004002859012041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f722077686963682069747368206d656d62657273207765726520726573706f6e7369626c652e0045012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f66206d7573744d0120636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e65656420612077617920746f20746965450120746f6765746865722073657373696f6e7320616e64204752414e44504120736574206964732c20692e652e207765206e65656420746f2076616c6964617465207468617420612076616c696461746f7241012077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e642077686174207468652061637469766520736574204944207761735420647572696e6720746861742073657373696f6e2e00b82054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e2c417574686f7269746965730100d90704000484205468652063757272656e74206c697374206f6620617574686f7269746965732e01f102019c0c384d6178417574686f7269746965731010e8030000045c204d617820417574686f72697469657320696e20757365344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e584d6178536574496453657373696f6e456e74726965733020000000000000000018390120546865206d6178696d756d206e756d626572206f6620656e747269657320746f206b65657020696e207468652073657420696420746f2073657373696f6e20696e646578206d617070696e672e0031012053696e6365207468652060536574496453657373696f6e60206d6170206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e73207468697329012076616c75652073686f756c642072656c61746520746f2074686520626f6e64696e67206475726174696f6e206f66207768617465766572207374616b696e672073797374656d2069733501206265696e6720757365642028696620616e79292e2049662065717569766f636174696f6e2068616e646c696e67206973206e6f7420656e61626c6564207468656e20746869732076616c7565342063616e206265207a65726f2e01dd070a1c496e6469636573011c496e646963657304204163636f756e74730001040210e1070400048820546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e01210301ac041c4465706f7369741840000064a7b3b6e00d000000000000000004ac20546865206465706f736974206e656564656420666f7220726573657276696e6720616e20696e6465782e01e5070b2444656d6f6372616379012444656d6f6372616379303c5075626c696350726f70436f756e74010010100000000004f420546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e2c5075626c696350726f70730100e907040004050120546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c2e244465706f7369744f660001040510f50704000c842054686f73652077686f2068617665206c6f636b65642061206465706f7369742e00d82054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e3c5265666572656e64756d436f756e74010010100000000004310120546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e344c6f77657374556e62616b6564010010100000000008250120546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746fdc20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e405265666572656e64756d496e666f4f660001040510f90704000cb420496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e0009012054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20566f74696e674f6601010405000508e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105d0120416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077655d012068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e00e82054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e544c6173745461626c656457617345787465726e616c0100200400085901205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c6963282070726f706f73616c2e304e65787445787465726e616c00001d08040010590120546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e550120546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743aa4202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f7268202d20605075626c696350726f70736020697320656d7074792e24426c61636b6c6973740001040634210804000851012041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d626572e82028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e3443616e63656c6c6174696f6e730101040634200400042901205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e284d657461646174614f6600010402c034040018ec2047656e6572616c20696e666f726d6174696f6e20636f6e6365726e696e6720616e792070726f706f73616c206f72207265666572656e64756d2e490120546865206048617368602072656665727320746f2074686520707265696d616765206f66207468652060507265696d61676573602070726f76696465722077686963682063616e2062652061204a534f4e882064756d70206f7220495046532068617368206f662061204a534f4e2066696c652e00750120436f6e73696465722061206761726261676520636f6c6c656374696f6e20666f722061206d65746164617461206f662066696e6973686564207265666572656e64756d7320746f2060756e7265717565737460202872656d6f76652944206c6172676520707265696d616765732e01250301b0303c456e6163746d656e74506572696f643020c0a800000000000014e82054686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e0031012049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e737572652074686174510120766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365b4207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e304c61756e6368506572696f643020201c00000000000004e420486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e30566f74696e67506572696f643020c08901000000000004b820486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e44566f74654c6f636b696e67506572696f643020c0a8000000000000109020546865206d696e696d756d20706572696f64206f6620766f7465206c6f636b696e672e0065012049742073686f756c64206265206e6f2073686f72746572207468616e20656e6163746d656e7420706572696f6420746f20656e73757265207468617420696e207468652063617365206f6620616e20617070726f76616c2c49012074686f7365207375636365737366756c20766f7465727320617265206c6f636b656420696e746f2074686520636f6e73657175656e636573207468617420746865697220766f74657320656e7461696c2e384d696e696d756d4465706f73697418400000a0dec5adc935360000000000000004350120546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e38496e7374616e74416c6c6f7765642004010c550120496e64696361746f7220666f72207768657468657220616e20656d657267656e6379206f726967696e206973206576656e20616c6c6f77656420746f2068617070656e2e20536f6d6520636861696e73206d617961012077616e7420746f207365742074686973207065726d616e656e746c7920746f206066616c7365602c206f7468657273206d61792077616e7420746f20636f6e646974696f6e206974206f6e207468696e67732073756368a020617320616e207570677261646520686176696e672068617070656e656420726563656e746c792e5446617374547261636b566f74696e67506572696f643020807000000000000004ec204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f72206120666173742d747261636b207265666572656e64756d2e34436f6f6c6f6666506572696f643020c0a800000000000004610120506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d6178566f74657310106400000010b020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e00d420416c736f207573656420746f20636f6d70757465207765696768742c20616e206f7665726c79206269672076616c75652063616e1501206c65616420746f2065787472696e7369632077697468207665727920626967207765696768743a20736565206064656c65676174656020666f7220696e7374616e63652e304d617850726f706f73616c73101064000000040d0120546865206d6178696d756d206e756d626572206f66207075626c69632070726f706f73616c7320746861742063616e20657869737420617420616e792074696d652e2c4d61784465706f73697473101064000000041d0120546865206d6178696d756d206e756d626572206f66206465706f736974732061207075626c69632070726f706f73616c206d6179206861766520617420616e792074696d652e384d6178426c61636b6c697374656410106400000004d820546865206d6178696d756d206e756d626572206f66206974656d732077686963682063616e20626520626c61636b6c69737465642e0125080c1c436f756e63696c011c436f756e63696c182450726f706f73616c7301002908040004902054686520686173686573206f6620746865206163746976652070726f706f73616c732e2850726f706f73616c4f660001040634b902040004cc2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e18566f74696e6700010406342d08040004b420566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e3450726f706f73616c436f756e74010010100000000004482050726f706f73616c7320736f206661722e1c4d656d6265727301003d020400043901205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e145072696d65000000040004610120546865207072696d65206d656d62657220746861742068656c70732064657465726d696e65207468652064656661756c7420766f7465206265686176696f7220696e2063617365206f662061627374656e74696f6e732e01410301c404444d617850726f706f73616c576569676874283c070010a5d4e813ffffffffffffff7f04250120546865206d6178696d756d20776569676874206f6620612064697370617463682063616c6c20746861742063616e2062652070726f706f73656420616e642065786563757465642e0131080d1c56657374696e67011c56657374696e67081c56657374696e6700010402003508040004d820496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e3853746f7261676556657273696f6e01003d0804000c7c2053746f726167652076657273696f6e206f66207468652070616c6c65742e003101204e6577206e6574776f726b732073746172742077697468206c61746573742076657273696f6e2c2061732064657465726d696e6564206279207468652067656e65736973206275696c642e01450301c808444d696e5665737465645472616e736665721840000010632d5ec76b050000000000000004e820546865206d696e696d756d20616d6f756e74207472616e7366657272656420746f2063616c6c20607665737465645f7472616e73666572602e4c4d617856657374696e675363686564756c657310101c000000000141080e24456c656374696f6e730124456c656374696f6e73141c4d656d626572730100450804000c74205468652063757272656e7420656c6563746564206d656d626572732e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e2452756e6e65727355700100450804001084205468652063757272656e742072657365727665642072756e6e6572732d75702e00590120496e76617269616e743a20416c7761797320736f72746564206261736564206f6e2072616e6b2028776f72736520746f2062657374292e2055706f6e2072656d6f76616c206f662061206d656d6265722c20746865bc206c6173742028692e652e205f626573745f292072756e6e65722d75702077696c6c206265207265706c616365642e2843616e646964617465730100d00400185901205468652070726573656e742063616e646964617465206c6973742e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f72d020616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e007c205365636f6e6420656c656d656e7420697320746865206465706f7369742e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e38456c656374696f6e526f756e647301001010000000000441012054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e18566f74696e6701010405004d08840000000000000000000000000000000000000000000000000000000000000000000cb820566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e00c42054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682e014d0301cc282050616c6c65744964a90220706872656c65637404d0204964656e74696669657220666f722074686520656c656374696f6e732d70687261676d656e2070616c6c65742773206c6f636b3443616e646964616379426f6e6418400000a0dec5adc935360000000000000004050120486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e38566f74696e67426f6e6442617365184000005053c91aa974050000000000000010942042617365206465706f736974206173736f636961746564207769746820766f74696e672e00550120546869732073686f756c642062652073656e7369626c79206869676820746f2065636f6e6f6d6963616c6c7920656e73757265207468652070616c6c65742063616e6e6f742062652061747461636b656420627994206372656174696e67206120676967616e746963206e756d626572206f6620766f7465732e40566f74696e67426f6e64466163746f721840000020f84dde700400000000000000000411012054686520616d6f756e74206f6620626f6e642074686174206e65656420746f206265206c6f636b656420666f72206561636820766f746520283332206279746573292e38446573697265644d656d626572731010050000000470204e756d626572206f66206d656d6265727320746f20656c6563742e404465736972656452756e6e65727355701010030000000478204e756d626572206f662072756e6e6572735f757020746f206b6565702e305465726d4475726174696f6e3020c0890100000000000c510120486f77206c6f6e6720656163682073656174206973206b6570742e205468697320646566696e657320746865206e65787420626c6f636b206e756d62657220617420776869636820616e20656c656374696f6e5d0120726f756e642077696c6c2068617070656e2e2049662073657420746f207a65726f2c206e6f20656c656374696f6e732061726520657665722074726967676572656420616e6420746865206d6f64756c652077696c6c5020626520696e2070617373697665206d6f64652e344d617843616e6469646174657310104000000018e420546865206d6178696d756d206e756d626572206f662063616e6469646174657320696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e003101205768656e2074686973206c696d69742069732072656163686564206e6f206d6f72652063616e646964617465732061726520616363657074656420696e2074686520656c656374696f6e2e244d6178566f7465727310100002000018f820546865206d6178696d756d206e756d626572206f6620766f7465727320746f20616c6c6f7720696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e00d8205768656e20746865206c696d6974206973207265616368656420746865206e657720766f74657273206172652069676e6f7265642e404d6178566f746573506572566f7465721010640000001090204d6178696d756d206e756d62657273206f6620766f7465732070657220766f7465722e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e0151080f68456c656374696f6e50726f76696465724d756c746950686173650168456c656374696f6e50726f76696465724d756c746950686173652814526f756e64010010100100000018ac20496e7465726e616c20636f756e74657220666f7220746865206e756d626572206f6620726f756e64732e00550120546869732069732075736566756c20666f722064652d6475706c69636174696f6e206f66207472616e73616374696f6e73207375626d697474656420746f2074686520706f6f6c2c20616e642067656e6572616c6c20646961676e6f7374696373206f66207468652070616c6c65742e004d012054686973206973206d6572656c7920696e6372656d656e746564206f6e6365207065722065766572792074696d65207468617420616e20757073747265616d2060656c656374602069732063616c6c65642e3043757272656e7450686173650100e40400043c2043757272656e742070686173652e38517565756564536f6c7574696f6e0000550804000c3d012043757272656e74206265737420736f6c7574696f6e2c207369676e6564206f7220756e7369676e65642c2071756575656420746f2062652072657475726e65642075706f6e2060656c656374602e006020416c7761797320736f727465642062792073636f72652e20536e617073686f7400005d080400107020536e617073686f742064617461206f662074686520726f756e642e005d01205468697320697320637265617465642061742074686520626567696e6e696e67206f6620746865207369676e656420706861736520616e6420636c65617265642075706f6e2063616c6c696e672060656c656374602e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e384465736972656454617267657473000010040010cc2044657369726564206e756d626572206f66207461726765747320746f20656c65637420666f72207468697320726f756e642e00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e40536e617073686f744d65746164617461000029040400109820546865206d65746164617461206f6620746865205b60526f756e64536e617073686f74605d00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e645369676e65645375626d697373696f6e4e657874496e646578010010100000000024010120546865206e65787420696e64657820746f2062652061737369676e656420746f20616e20696e636f6d696e67207369676e6564207375626d697373696f6e2e007501204576657279206163636570746564207375626d697373696f6e2069732061737369676e6564206120756e6971756520696e6465783b207468617420696e64657820697320626f756e6420746f207468617420706172746963756c61726501207375626d697373696f6e20666f7220746865206475726174696f6e206f662074686520656c656374696f6e2e204f6e20656c656374696f6e2066696e616c697a6174696f6e2c20746865206e65787420696e6465782069733020726573657420746f20302e0069012057652063616e2774206a7573742075736520605369676e65645375626d697373696f6e496e64696365732e6c656e2829602c206265636175736520746861742773206120626f756e646564207365743b20706173742069747359012063617061636974792c2069742077696c6c2073696d706c792073617475726174652e2057652063616e2774206a7573742069746572617465206f76657220605369676e65645375626d697373696f6e734d6170602cf4206265636175736520697465726174696f6e20697320736c6f772e20496e73746561642c2077652073746f7265207468652076616c756520686572652e5c5369676e65645375626d697373696f6e496e646963657301006d080400186d01204120736f727465642c20626f756e64656420766563746f72206f6620602873636f72652c20626c6f636b5f6e756d6265722c20696e64657829602c20776865726520656163682060696e6465786020706f696e747320746f2061782076616c756520696e20605369676e65645375626d697373696f6e73602e007101205765206e65766572206e65656420746f2070726f63657373206d6f7265207468616e20612073696e676c65207369676e6564207375626d697373696f6e20617420612074696d652e205369676e6564207375626d697373696f6e7375012063616e206265207175697465206c617267652c20736f2077652772652077696c6c696e6720746f207061792074686520636f7374206f66206d756c7469706c6520646174616261736520616363657373657320746f206163636573732101207468656d206f6e6520617420612074696d6520696e7374656164206f662072656164696e6720616e64206465636f64696e6720616c6c206f66207468656d206174206f6e63652e505369676e65645375626d697373696f6e734d61700001040510790804001c7420556e636865636b65642c207369676e656420736f6c7574696f6e732e00690120546f676574686572207769746820605375626d697373696f6e496e6469636573602c20746869732073746f726573206120626f756e64656420736574206f6620605369676e65645375626d697373696f6e7360207768696c65ec20616c6c6f77696e6720757320746f206b656570206f6e6c7920612073696e676c65206f6e6520696e206d656d6f727920617420612074696d652e0069012054776f78206e6f74653a20746865206b6579206f6620746865206d617020697320616e206175746f2d696e6372656d656e74696e6720696e6465782077686963682075736572732063616e6e6f7420696e7370656374206f72f4206166666563743b2077652073686f756c646e2774206e65656420612063727970746f67726170686963616c6c7920736563757265206861736865722e544d696e696d756d556e7472757374656453636f72650000e00400105d0120546865206d696e696d756d2073636f7265207468617420656163682027756e747275737465642720736f6c7574696f6e206d7573742061747461696e20696e206f7264657220746f20626520636f6e7369646572656428206665617369626c652e00b82043616e206265207365742076696120607365745f6d696e696d756d5f756e747275737465645f73636f7265602e01550301d838544265747465725369676e65645468726573686f6c64f41000000000084d0120546865206d696e696d756d20616d6f756e74206f6620696d70726f76656d656e7420746f2074686520736f6c7574696f6e2073636f7265207468617420646566696e6573206120736f6c7574696f6e2061737820226265747465722220696e20746865205369676e65642070686173652e384f6666636861696e5265706561743020050000000000000010b42054686520726570656174207468726573686f6c64206f6620746865206f6666636861696e20776f726b65722e00610120466f72206578616d706c652c20696620697420697320352c2074686174206d65616e732074686174206174206c65617374203520626c6f636b732077696c6c20656c61707365206265747765656e20617474656d7074738420746f207375626d69742074686520776f726b6572277320736f6c7574696f6e2e3c4d696e657254785072696f726974793020feffffffffffff7f04250120546865207072696f72697479206f662074686520756e7369676e6564207472616e73616374696f6e207375626d697474656420696e2074686520756e7369676e65642d7068617365505369676e65644d61785375626d697373696f6e7310100a0000001ce4204d6178696d756d206e756d626572206f66207369676e6564207375626d697373696f6e7320746861742063616e206265207175657565642e005501204974206973206265737420746f2061766f69642061646a757374696e67207468697320647572696e6720616e20656c656374696f6e2c20617320697420696d706163747320646f776e73747265616d2064617461650120737472756374757265732e20496e20706172746963756c61722c20605369676e65645375626d697373696f6e496e64696365733c543e6020697320626f756e646564206f6e20746869732076616c75652e20496620796f75f42075706461746520746869732076616c756520647572696e6720616e20656c656374696f6e2c20796f75205f6d7573745f20656e7375726520746861744d0120605369676e65645375626d697373696f6e496e64696365732e6c656e282960206973206c657373207468616e206f7220657175616c20746f20746865206e65772076616c75652e204f74686572776973652cf020617474656d70747320746f207375626d6974206e657720736f6c7574696f6e73206d617920636175736520612072756e74696d652070616e69632e3c5369676e65644d617857656967687428400bd8e2a18c2e011366666666666666a61494204d6178696d756d20776569676874206f662061207369676e656420736f6c7574696f6e2e005d01204966205b60436f6e6669673a3a4d696e6572436f6e666967605d206973206265696e6720696d706c656d656e74656420746f207375626d6974207369676e656420736f6c7574696f6e7320286f757473696465206f663d0120746869732070616c6c6574292c207468656e205b604d696e6572436f6e6669673a3a736f6c7574696f6e5f776569676874605d206973207573656420746f20636f6d7061726520616761696e73743020746869732076616c75652e405369676e65644d6178526566756e647310100300000004190120546865206d6178696d756d20616d6f756e74206f6620756e636865636b656420736f6c7574696f6e7320746f20726566756e64207468652063616c6c2066656520666f722e405369676e6564526577617264426173651840000064a7b3b6e00d0000000000000000048820426173652072657761726420666f722061207369676e656420736f6c7574696f6e445369676e65644465706f73697442797465184000008a5d78456301000000000000000004a0205065722d62797465206465706f73697420666f722061207369676e656420736f6c7574696f6e2e4c5369676e65644465706f73697457656967687418400000000000000000000000000000000004a8205065722d776569676874206465706f73697420666f722061207369676e656420736f6c7574696f6e2e284d617857696e6e6572731010e803000010350120546865206d6178696d756d206e756d626572206f662077696e6e65727320746861742063616e20626520656c656374656420627920746869732060456c656374696f6e50726f7669646572604020696d706c656d656e746174696f6e2e005101204e6f74653a2054686973206d75737420616c776179732062652067726561746572206f7220657175616c20746f2060543a3a4461746150726f76696465723a3a646573697265645f746172676574732829602e384d696e65724d61784c656e67746810100000360000384d696e65724d617857656967687428400bd8e2a18c2e011366666666666666a600544d696e65724d6178566f746573506572566f746572101010000000003c4d696e65724d617857696e6e6572731010e803000000017d08101c5374616b696e67011c5374616b696e67ac3856616c696461746f72436f756e740100101000000000049c2054686520696465616c206e756d626572206f66206163746976652076616c696461746f72732e544d696e696d756d56616c696461746f72436f756e740100101000000000044101204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e34496e76756c6e657261626c657301003d0204000c590120416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e636520746865792772654d01206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f7572ac20696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e18426f6e64656400010405000004000c0101204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e404d696e4e6f6d696e61746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f662061206e6f6d696e61746f722e404d696e56616c696461746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f6620612076616c696461746f722e484d696e696d756d4163746976655374616b65010018400000000000000000000000000000000004110120546865206d696e696d756d20616374697665206e6f6d696e61746f72207374616b65206f6620746865206c617374207375636365737366756c20656c656374696f6e2e344d696e436f6d6d697373696f6e0100f410000000000ce820546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e20746861742076616c696461746f72732063616e207365742e00802049662073657420746f206030602c206e6f206c696d6974206578697374732e184c6564676572000104020081080400104501204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e007501204e6f74653a20416c6c2074686520726561647320616e64206d75746174696f6e7320746f20746869732073746f72616765202a4d5553542a20626520646f6e65207468726f75676820746865206d6574686f6473206578706f736564e8206279205b605374616b696e674c6564676572605d20746f20656e73757265206461746120616e64206c6f636b20636f6e73697374656e63792e1450617965650001040500f004000ce42057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e2856616c696461746f72730101040500f80800000c450120546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f7256616c696461746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d617856616c696461746f7273436f756e7400001004000c310120546865206d6178696d756d2076616c696461746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e284e6f6d696e61746f72730001040500890804004c750120546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f207468656972206e6f6d696e6174696f6e20707265666572656e6365732c206e616d656c79207468652076616c696461746f72732074686174582074686579207769736820746f20737570706f72742e003901204e6f7465207468617420746865206b657973206f6620746869732073746f72616765206d6170206d69676874206265636f6d65206e6f6e2d6465636f6461626c6520696e2063617365207468652d01206163636f756e742773205b604e6f6d696e6174696f6e7351756f74613a3a4d61784e6f6d696e6174696f6e73605d20636f6e66696775726174696f6e206973206465637265617365642e9020496e2074686973207261726520636173652c207468657365206e6f6d696e61746f7273650120617265207374696c6c206578697374656e7420696e2073746f726167652c207468656972206b657920697320636f727265637420616e64207265747269657661626c652028692e652e2060636f6e7461696e735f6b657960710120696e6469636174657320746861742074686579206578697374292c206275742074686569722076616c75652063616e6e6f74206265206465636f6465642e205468657265666f72652c20746865206e6f6e2d6465636f6461626c656d01206e6f6d696e61746f72732077696c6c206566666563746976656c79206e6f742d65786973742c20756e74696c20746865792072652d7375626d697420746865697220707265666572656e6365732073756368207468617420697401012069732077697468696e2074686520626f756e6473206f6620746865206e65776c79207365742060436f6e6669673a3a4d61784e6f6d696e6174696f6e73602e006101205468697320696d706c696573207468617420603a3a697465725f6b65797328292e636f756e7428296020616e6420603a3a6974657228292e636f756e74282960206d696768742072657475726e20646966666572656e746d012076616c75657320666f722074686973206d61702e204d6f72656f7665722c20746865206d61696e20603a3a636f756e7428296020697320616c69676e656420776974682074686520666f726d65722c206e616d656c79207468656c206e756d626572206f66206b65797320746861742065786973742e006d01204c6173746c792c20696620616e79206f6620746865206e6f6d696e61746f7273206265636f6d65206e6f6e2d6465636f6461626c652c20746865792063616e206265206368696c6c656420696d6d6564696174656c7920766961b8205b6043616c6c3a3a6368696c6c5f6f74686572605d20646973706174636861626c6520627920616e796f6e652e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f724e6f6d696e61746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170385669727475616c5374616b657273000104050084040018c8205374616b6572732077686f73652066756e647320617265206d616e61676564206279206f746865722070616c6c6574732e00750120546869732070616c6c657420646f6573206e6f74206170706c7920616e79206c6f636b73206f6e207468656d2c207468657265666f7265207468657920617265206f6e6c79207669727475616c6c7920626f6e6465642e20546865796d012061726520657870656374656420746f206265206b65796c657373206163636f756e747320616e642068656e63652073686f756c64206e6f7420626520616c6c6f77656420746f206d7574617465207468656972206c65646765727101206469726563746c792076696120746869732070616c6c65742e20496e73746561642c207468657365206163636f756e747320617265206d616e61676564206279206f746865722070616c6c65747320616e64206163636573736564290120766961206c6f77206c6576656c20617069732e205765206b65657020747261636b206f66207468656d20746f20646f206d696e696d616c20696e7465677269747920636865636b732e60436f756e746572466f725669727475616c5374616b657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d61784e6f6d696e61746f7273436f756e7400001004000c310120546865206d6178696d756d206e6f6d696e61746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e2843757272656e744572610000100400105c205468652063757272656e742065726120696e6465782e006501205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f7280207365742c206974206d6967687420626520616374697665206f72206e6f742e2441637469766545726100008d08040010d820546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e0059012054686520616374697665206572612069732074686520657261206265696e672063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d757374206265ac20657175616c20746f205b6053657373696f6e496e746572666163653a3a76616c696461746f7273605d2e5445726173537461727453657373696f6e496e6465780001040510100400105501205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e006101204e6f74653a205468697320747261636b7320746865207374617274696e672073657373696f6e2028692e652e2073657373696f6e20696e646578207768656e20657261207374617274206265696e672061637469766529f020666f7220746865206572617320696e20605b43757272656e74457261202d20484953544f52595f44455054482c2043757272656e744572615d602e2c457261735374616b6572730101080505910869010c0000002078204578706f73757265206f662076616c696461746f72206174206572612e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e4c457261735374616b6572734f76657276696577000108050591089508040030b82053756d6d617279206f662076616c696461746f72206578706f73757265206174206120676976656e206572612e007101205468697320636f6e7461696e732074686520746f74616c207374616b6520696e20737570706f7274206f66207468652076616c696461746f7220616e64207468656972206f776e207374616b652e20496e206164646974696f6e2c75012069742063616e20616c736f206265207573656420746f2067657420746865206e756d626572206f66206e6f6d696e61746f7273206261636b696e6720746869732076616c696461746f7220616e6420746865206e756d626572206f666901206578706f73757265207061676573207468657920617265206469766964656420696e746f2e20546865207061676520636f756e742069732075736566756c20746f2064657465726d696e6520746865206e756d626572206f66ac207061676573206f6620726577617264732074686174206e6565647320746f20626520636c61696d65642e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742eac2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206f766572766965772069732072657475726e65642e48457261735374616b657273436c69707065640101080505910869010c000000409820436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e006501204e6f74653a205468697320697320646570726563617465642c2073686f756c64206265207573656420617320726561642d6f6e6c7920616e642077696c6c2062652072656d6f76656420696e20746865206675747572652e3101204e657720604578706f737572656073206172652073746f72656420696e2061207061676564206d616e6e657220696e2060457261735374616b65727350616765646020696e73746561642e00590120546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f20746865a82060543a3a4d61784578706f737572655061676553697a65602062696767657374207374616b6572732e1d0120284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292ef42054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e005d012054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e40457261735374616b657273506167656400010c05050599089d08040018c020506167696e61746564206578706f73757265206f6620612076616c696461746f7220617420676976656e206572612e0071012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e2c207468656e207374617368206163636f756e7420616e642066696e616c6c79d42074686520706167652e2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00d4205468697320697320636c6561726564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e38436c61696d656452657761726473010108050591084504040018dc20486973746f7279206f6620636c61696d656420706167656420726577617264732062792065726120616e642076616c696461746f722e0069012054686973206973206b657965642062792065726120616e642076616c696461746f72207374617368207768696368206d61707320746f2074686520736574206f66207061676520696e6465786573207768696368206861766538206265656e20636c61696d65642e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e484572617356616c696461746f72507265667301010805059108f80800001411012053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4c4572617356616c696461746f7252657761726400010405101804000c2d012054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e0021012045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e4045726173526577617264506f696e74730101040510a10814000000000008d0205265776172647320666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e250120496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e3845726173546f74616c5374616b6501010405101840000000000000000000000000000000000811012054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e1d0120496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e20466f7263654572610100010104000454204d6f6465206f662065726120666f7263696e672e404d61785374616b6564526577617264730000f50104000c1901204d6178696d756d207374616b656420726577617264732c20692e652e207468652070657263656e74616765206f66207468652065726120696e666c6174696f6e20746861746c206973207573656420666f72207374616b6520726577617264732eac20536565205b457261207061796f75745d282e2f696e6465782e68746d6c236572612d7061796f7574292e4c536c6173685265776172644672616374696f6e0100f410000000000cf8205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e00e4205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e4c43616e63656c6564536c6173685061796f757401001840000000000000000000000000000000000815012054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e7420776869636820776173ec2063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e40556e6170706c696564536c61736865730101040510b108040004c420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e28426f6e646564457261730100b90804001025012041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e00c8204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653abc20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d604c56616c696461746f72536c617368496e45726100010805059108c108040008450120416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e7020616e6420736c6173682076616c7565206f6620746865206572612e4c4e6f6d696e61746f72536c617368496e4572610001080505910818040004610120416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e34536c617368696e675370616e730001040500c5080400048c20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e245370616e536c61736801010405ad08c908800000000000000000000000000000000000000000000000000000000000000000083d01205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2cb82061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e5443757272656e74506c616e6e656453657373696f6e01001010000000000ce820546865206c61737420706c616e6e65642073657373696f6e207363686564756c6564206279207468652073657373696f6e2070616c6c65742e0071012054686973206973206261736963616c6c7920696e2073796e632077697468207468652063616c6c20746f205b6070616c6c65745f73657373696f6e3a3a53657373696f6e4d616e616765723a3a6e65775f73657373696f6e605d2e4844697361626c656456616c696461746f72730100450404001c750120496e6469636573206f662076616c696461746f727320746861742068617665206f6666656e64656420696e2074686520616374697665206572612e20546865206f6666656e64657273206172652064697361626c656420666f72206169012077686f6c65206572612e20466f72207468697320726561736f6e207468657920617265206b6570742068657265202d206f6e6c79207374616b696e672070616c6c6574206b6e6f77732061626f757420657261732e20546865550120696d706c656d656e746f72206f66205b6044697361626c696e675374726174656779605d20646566696e657320696620612076616c696461746f722073686f756c642062652064697361626c65642077686963686d0120696d706c696369746c79206d65616e7320746861742074686520696d706c656d656e746f7220616c736f20636f6e74726f6c7320746865206d6178206e756d626572206f662064697361626c65642076616c696461746f72732e006d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f72206861732070726576696f75736c7978206f6666656e646564207573696e672062696e617279207365617263682e384368696c6c5468726573686f6c640000f50104000c510120546865207468726573686f6c6420666f72207768656e2075736572732063616e2073746172742063616c6c696e6720606368696c6c5f6f746865726020666f72206f746865722076616c696461746f7273202f5901206e6f6d696e61746f72732e20546865207468726573686f6c6420697320636f6d706172656420746f207468652061637475616c206e756d626572206f662076616c696461746f7273202f206e6f6d696e61746f72732901202860436f756e74466f722a602920696e207468652073797374656d20636f6d706172656420746f2074686520636f6e66696775726564206d61782028604d61782a436f756e7460292e013d0401ec1830486973746f72794465707468101050000000508c204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e00e820466f6c6c6f77696e6720696e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d090120486973746f727944657074682c2063757272656e745f6572615d603a2060457261735374616b657273602c2060457261735374616b657273436c6970706564602c050120604572617356616c696461746f725072656673602c20604572617356616c696461746f72526577617264602c206045726173526577617264506f696e7473602c4501206045726173546f74616c5374616b65602c206045726173537461727453657373696f6e496e646578602c2060436c61696d656452657761726473602c2060457261735374616b6572735061676564602c5c2060457261735374616b6572734f76657276696577602e00e4204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e2ef820492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203ec42063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e001101204966206d6967726174696e6720616e206578697374696e672070616c6c65742066726f6d2073746f726167652076616c756520746f20636f6e6669672076616c75652cec20746869732073686f756c642062652073657420746f2073616d652076616c7565206f72206772656174657220617320696e2073746f726167652e001501204e6f74653a2060486973746f727944657074686020697320757365642061732074686520757070657220626f756e6420666f72207468652060426f756e646564566563602d01206974656d20605374616b696e674c65646765722e6c65676163795f636c61696d65645f72657761726473602e2053657474696e6720746869732076616c7565206c6f776572207468616ed820746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865150120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e2061206d6967726174696f6e2ef020546865207465737420607265647563696e675f686973746f72795f64657074685f616272757074602073686f77732074686973206566666563742e3853657373696f6e735065724572611010030000000470204e756d626572206f662073657373696f6e7320706572206572612e3c426f6e64696e674475726174696f6e10100e00000004e4204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e48536c61736844656665724475726174696f6e10100a000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e4c4d61784578706f737572655061676553697a651010400000002cb020546865206d6178696d756d2073697a65206f6620656163682060543a3a4578706f7375726550616765602e00290120416e20604578706f737572655061676560206973207765616b6c7920626f756e64656420746f2061206d6178696d756d206f6620604d61784578706f737572655061676553697a656030206e6f6d696e61746f72732e00210120466f72206f6c646572206e6f6e2d7061676564206578706f737572652c206120726577617264207061796f757420776173207265737472696374656420746f2074686520746f70210120604d61784578706f737572655061676553697a6560206e6f6d696e61746f72732e205468697320697320746f206c696d69742074686520692f6f20636f737420666f722074686548206e6f6d696e61746f72207061796f75742e005901204e6f74653a20604d61784578706f737572655061676553697a6560206973207573656420746f20626f756e642060436c61696d6564526577617264736020616e6420697320756e7361666520746f207265647563659020776974686f75742068616e646c696e6720697420696e2061206d6967726174696f6e2e484d6178556e6c6f636b696e674368756e6b7310102000000028050120546865206d6178696d756d206e756d626572206f662060756e6c6f636b696e6760206368756e6b732061205b605374616b696e674c6564676572605d2063616e090120686176652e204566666563746976656c792064657465726d696e657320686f77206d616e7920756e6971756520657261732061207374616b6572206d61792062653820756e626f6e64696e6720696e2e00f8204e6f74653a20604d6178556e6c6f636b696e674368756e6b736020697320757365642061732074686520757070657220626f756e6420666f722074686501012060426f756e64656456656360206974656d20605374616b696e674c65646765722e756e6c6f636b696e67602e2053657474696e6720746869732076616c75650501206c6f776572207468616e20746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865090120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e20612072756e74696d650501206d6967726174696f6e2e20546865207465737420607265647563696e675f6d61785f756e6c6f636b696e675f6368756e6b735f616272757074602073686f7773342074686973206566666563742e01cd08111c53657373696f6e011c53657373696f6e1c2856616c696461746f727301003d020400047c205468652063757272656e7420736574206f662076616c696461746f72732e3043757272656e74496e646578010010100000000004782043757272656e7420696e646578206f66207468652073657373696f6e2e345175657565644368616e676564010020040008390120547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f7273a420686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e285175657565644b6579730100d1080400083d012054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b657973e02077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e4844697361626c656456616c696461746f7273010045040400148020496e6469636573206f662064697361626c65642076616c696461746f72732e003d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f722069733d012064697361626c6564207573696e672062696e617279207365617263682e204974206765747320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e73642061206e657720736574206f66206964656e7469746965732e204e6578744b657973000104050075040400049c20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e204b65794f776e657200010405d90800040004090120546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e0171040105010001e1081228486973746f726963616c0128486973746f726963616c0848486973746f726963616c53657373696f6e730001040510e5080400045d01204d617070696e672066726f6d20686973746f726963616c2073657373696f6e20696e646963657320746f2073657373696f6e2d6461746120726f6f74206861736820616e642076616c696461746f7220636f756e742e2c53746f72656452616e67650000bd08040004e4205468652072616e6765206f6620686973746f726963616c2073657373696f6e732077652073746f72652e205b66697273742c206c61737429000000001320547265617375727901205472656173757279183450726f706f73616c436f756e74010010100000000004a4204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e2450726f706f73616c730001040510e9080400047c2050726f706f73616c7320746861742068617665206265656e206d6164652e2c4465616374697661746564010018400000000000000000000000000000000004f02054686520616d6f756e7420776869636820686173206265656e207265706f7274656420617320696e61637469766520746f2043757272656e63792e24417070726f76616c730100ed08040004f82050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e285370656e64436f756e74010010100000000004a42054686520636f756e74206f66207370656e647320746861742068617665206265656e206d6164652e185370656e64730001040510f108040004d0205370656e647320746861742068617665206265656e20617070726f76656420616e64206265696e672070726f6365737365642e017904010901142c5370656e64506572696f6430204038000000000000048820506572696f64206265747765656e2073756363657373697665207370656e64732e104275726ed10110000000000411012050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e2050616c6c65744964f9082070792f74727372790419012054686520747265617375727927732070616c6c65742069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e304d6178417070726f76616c731010640000000c150120546865206d6178696d756d206e756d626572206f6620617070726f76616c7320746861742063616e207761697420696e20746865207370656e64696e672071756575652e004d01204e4f54453a205468697320706172616d6574657220697320616c736f20757365642077697468696e2074686520426f756e746965732050616c6c657420657874656e73696f6e20696620656e61626c65642e305061796f7574506572696f6430200a000000000000000419012054686520706572696f6420647572696e6720776869636820616e20617070726f766564207472656173757279207370656e642068617320746f20626520636c61696d65642e01fd081420426f756e746965730120426f756e74696573102c426f756e7479436f756e74010010100000000004c0204e756d626572206f6620626f756e74792070726f706f73616c7320746861742068617665206265656e206d6164652e20426f756e74696573000104051001090400047820426f756e7469657320746861742068617665206265656e206d6164652e48426f756e74794465736372697074696f6e73000104051009090400048020546865206465736372697074696f6e206f66206561636820626f756e74792e3c426f756e7479417070726f76616c730100ed08040004ec20426f756e747920696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f74207965742066756e6465642e018104010d012444426f756e74794465706f736974426173651840000064a7b3b6e00d000000000000000004e82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120626f756e74792070726f706f73616c2e60426f756e74794465706f7369745061796f757444656c617930204038000000000000045901205468652064656c617920706572696f6420666f72207768696368206120626f756e74792062656e6566696369617279206e65656420746f2077616974206265666f726520636c61696d20746865207061796f75742e48426f756e7479557064617465506572696f6430208013030000000000046c20426f756e7479206475726174696f6e20696e20626c6f636b732e6043757261746f724465706f7369744d756c7469706c696572d1011020a10700101901205468652063757261746f72206465706f7369742069732063616c63756c6174656420617320612070657263656e74616765206f66207468652063757261746f72206665652e0039012054686973206465706f73697420686173206f7074696f6e616c20757070657220616e64206c6f77657220626f756e64732077697468206043757261746f724465706f7369744d61786020616e6454206043757261746f724465706f7369744d696e602e4443757261746f724465706f7369744d61785d044401000010632d5ec76b0500000000000000044901204d6178696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e4443757261746f724465706f7369744d696e5d044401000064a7b3b6e00d0000000000000000044901204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e48426f756e747956616c75654d696e696d756d18400000f4448291634500000000000000000470204d696e696d756d2076616c756520666f72206120626f756e74792e48446174614465706f73697450657242797465184000008a5d7845630100000000000000000461012054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e206f7220626f756e7479206465736372697074696f6e2e4c4d6178696d756d526561736f6e4c656e67746810102c0100000c88204d6178696d756d2061636365707461626c6520726561736f6e206c656e6774682e0065012042656e63686d61726b7320646570656e64206f6e20746869732076616c75652c206265207375726520746f2075706461746520776569676874732066696c65207768656e206368616e67696e6720746869732076616c7565010d0915344368696c64426f756e7469657301344368696c64426f756e7469657314404368696c64426f756e7479436f756e7401001010000000000480204e756d626572206f6620746f74616c206368696c6420626f756e746965732e4c506172656e744368696c64426f756e74696573010104051010100000000008b0204e756d626572206f66206368696c6420626f756e746965732070657220706172656e7420626f756e74792ee0204d6170206f6620706172656e7420626f756e747920696e64657820746f206e756d626572206f66206368696c6420626f756e746965732e344368696c64426f756e746965730001080505bd08110904000494204368696c6420626f756e7469657320746861742068617665206265656e2061646465642e5c4368696c64426f756e74794465736372697074696f6e73000104051009090400049820546865206465736372697074696f6e206f662065616368206368696c642d626f756e74792e4c4368696c6472656e43757261746f72466565730101040510184000000000000000000000000000000000040101205468652063756d756c6174697665206368696c642d626f756e74792063757261746f722066656520666f72206561636820706172656e7420626f756e74792e01850401110108644d61784163746976654368696c64426f756e7479436f756e74101005000000041d01204d6178696d756d206e756d626572206f66206368696c6420626f756e7469657320746861742063616e20626520616464656420746f206120706172656e7420626f756e74792e5c4368696c64426f756e747956616c75654d696e696d756d1840000064a7b3b6e00d00000000000000000488204d696e696d756d2076616c756520666f722061206368696c642d626f756e74792e0119091620426167734c6973740120426167734c6973740c244c6973744e6f64657300010405001d0904000c8020412073696e676c65206e6f64652c2077697468696e20736f6d65206261672e000501204e6f6465732073746f7265206c696e6b7320666f727761726420616e64206261636b2077697468696e207468656972207265737065637469766520626167732e4c436f756e746572466f724c6973744e6f646573010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204c697374426167730001040530210904000c642041206261672073746f72656420696e2073746f726167652e0019012053746f7265732061206042616760207374727563742c2077686963682073746f726573206865616420616e64207461696c20706f696e7465727320746f20697473656c662e01890401150104344261675468726573686f6c647315060919210300407a10f35a00006a70ccd4a96000009ef3397fbc660000a907ccd5306d00003d9a67fb0c740000a9bfa275577b0000a6fdf73217830000034f5d91538b0000132445651494000078081001629d00000302f63c45a70000392e6f7fc7b10000f59c23c6f2bc00004ae76aafd1c80000598a64846fd50000129fb243d8e200003f22e1ac18f1000033a4844c3e000100e2e51b895710010076a2c0b0732101006789b407a3330100793ed8d7f646010078131b81815b01000c1cf38a567101004437eeb68a8801009eb56d1434a10100335e9f156abb010067c3c7a545d701003218f340e1f40100de0b230d59140200699c11f5ca350200ad50a2c4565902009ae41c471e7f0200d0244e6745a70200f984ad51f2d10200ace7a7984dff0200a118325b822f0300ffa4c76dbe620300580bfd8532990300a9afce6812d30300109ad81b95100400d9caa519f551040038df488970970400bee1727949e10400cc73401fc62f0500b304f91831830500828bffb4d9db05001235383d143a0600a5b42a473a9e060036662d09ab080700f73aeab4cb790700b87e93d707f20700ffec23c0d1710800b84b0beca2f90800c9dcae7afc89090091752ba867230a0064f1cd4f76c60a003609be76c3730b0078655fdff32b0c00a407f5a5b6ef0c0052f61be7c5bf0d00da71bb70e79c0e000de9127eed870f001477987fb7811000ebee65ef328b11001269fe325ca5120033f8428b3fd113008ba57a13fa0f15001b2b60d0ba6216000d1d37d0c3ca17006c64fa5c6b4919002622c7411de01a00045bb9245c901c00233d83f6c25b1e00c8771c79064420003013fddef64a2200aa8b6e848172240082c096c4b2bc260016a3faebb72b29008296524ae1c12b00a636a865a4812e00d0e2d4509e6d31009c0a9a2796883400e4faafb27fd53700e6e64d367e573b000e4bd66de7113f0088b17db746084300b07def72603e470034de249635b84b00d48bd57b077a5000d0bd20ef5b885500b8f0467801e85a0010f88aee139e60003892925301b066009c95e4fc8e236d00b4126d10dffe730028b43e5976487b00a08a1c7a42078300b09ab083a0428b002846b2f463029400c861a42ade4e9d0050d23d4ae630a700805101a7e1b1b10038e501b2ccdbbc002016527844b9c800388924ba9055d50070ca35a4aebce200805fb1355cfbf0008035685d241f0001a0c3dcd96b361001d07862e87e50210160e852d09f7d330190662c5816cf460110274c3340575b01804be277a22971013082b92dfc5a880180d276075a01a101b0f511592b34bb014031745f580cd701802f6cee59a4f40140ff799b521814026075607d2986350260fde999a60d590200e5e71c91d07e02c0df2575cff2a602a07fd975899ad102a067009d4cf0fe0220dc29a1321f2f0320ff526b0a5562038088caa383c29803e05683fb5c9bd203401dd75d9516100400317e39a06e5104c0b071129de1960480b48c9192b1e00480e8124aad242f05c007ca7082858205007c13c45623db0540836fe869523906c0700f81466c9d0640f09c5017d00707c0e624b301e37807c0332ac78510f10780074ca1e4ca700800d5a9eb8c8bf80800a849588ed3880900804254142c220a80a25170e826c50a00e8d5fafc5e720b801df64e00792a0c80d4fe64f923ee0c006dd038ee19be0d001e90a494209b0e0010bf570e0a860f00da6a9db0b57f1000bf64afd810891100bb5b60cd17a31200f963f3aed6ce1300d5f004766a0d1500e099770202601600103d663bdfc71700de3e2d4158461900ecdbadb2d8dc1a0045c70007e38c1c00b8bde0fc11581e00ba5c2a211a402000407de46dcb462200dea55b03136e2400aaf1f3fcfcb7260014226f63b62629006492803e8fbc2b008486a6c7fc7b2e002cf05fc09b673100da63f7ed32823400f0b13fbdb5ce3700f291c41047503b00422a1a3c3c0a3f002c24212f20004300ac9342d4b6354700cc6ed7a400af4b00c4d022773e70500020017d89f57d5500f86387cef3dc5a008c4c7f7e54926000206207f284a36600cc1e05cb49166d00b42a7a70c4f07300d43a90e278397b0038f461ec53f78200a07264b9b1318b0048c9b3d464f09300007fe998bd3b9d0010058f17921ca70000dfaf7f469cb100e80c880bd6c4bc0058bdcb7ddca0c80038d18d37a03bd50030d55bf01ca1e200704ac01a0fdef0ffffffffffffffffacd020546865206c697374206f66207468726573686f6c64732073657061726174696e672074686520766172696f757320626167732e00490120496473206172652073657061726174656420696e746f20756e736f727465642062616773206163636f7264696e6720746f2074686569722073636f72652e205468697320737065636966696573207468656101207468726573686f6c64732073657061726174696e672074686520626167732e20416e20696427732062616720697320746865206c6172676573742062616720666f722077686963682074686520696427732073636f7265b8206973206c657373207468616e206f7220657175616c20746f20697473207570706572207468726573686f6c642e006501205768656e20696473206172652069746572617465642c2068696768657220626167732061726520697465726174656420636f6d706c6574656c79206265666f7265206c6f77657220626167732e2054686973206d65616e735901207468617420697465726174696f6e206973205f73656d692d736f727465645f3a20696473206f66206869676865722073636f72652074656e6420746f20636f6d65206265666f726520696473206f66206c6f7765722d012073636f72652c206275742070656572206964732077697468696e206120706172746963756c6172206261672061726520736f7274656420696e20696e73657274696f6e206f726465722e006820232045787072657373696e672074686520636f6e7374616e74004d01205468697320636f6e7374616e74206d75737420626520736f7274656420696e207374726963746c7920696e6372656173696e67206f726465722e204475706c6963617465206974656d7320617265206e6f742c207065726d69747465642e00410120546865726520697320616e20696d706c696564207570706572206c696d6974206f66206053636f72653a3a4d4158603b20746861742076616c756520646f6573206e6f74206e65656420746f2062652101207370656369666965642077697468696e20746865206261672e20466f7220616e792074776f207468726573686f6c64206c697374732c206966206f6e6520656e647320776974683101206053636f72653a3a4d4158602c20746865206f74686572206f6e6520646f6573206e6f742c20616e64207468657920617265206f746865727769736520657175616c2c207468652074776f7c206c697374732077696c6c20626568617665206964656e746963616c6c792e003820232043616c63756c6174696f6e005501204974206973207265636f6d6d656e64656420746f2067656e65726174652074686520736574206f66207468726573686f6c647320696e20612067656f6d6574726963207365726965732c2073756368207468617441012074686572652065786973747320736f6d6520636f6e7374616e7420726174696f2073756368207468617420607468726573686f6c645b6b202b20315d203d3d20287468726573686f6c645b6b5d202ad020636f6e7374616e745f726174696f292e6d6178287468726573686f6c645b6b5d202b2031296020666f7220616c6c20606b602e005901205468652068656c7065727320696e2074686520602f7574696c732f6672616d652f67656e65726174652d6261677360206d6f64756c652063616e2073696d706c69667920746869732063616c63756c6174696f6e2e002c2023204578616d706c6573005101202d20496620604261675468726573686f6c64733a3a67657428292e69735f656d7074792829602c207468656e20616c6c20696473206172652070757420696e746f207468652073616d65206261672c20616e64b0202020697465726174696f6e206973207374726963746c7920696e20696e73657274696f6e206f726465722e6101202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d203634602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f11012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320657175616c20746f20322e6501202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d20323030602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f59012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320617070726f78696d6174656c7920657175616c20746f20312e3234382e6101202d20496620746865207468726573686f6c64206c69737420626567696e7320605b312c20322c20332c202e2e2e5d602c207468656e20616e20696420776974682073636f72652030206f7220312077696c6c2066616c6cf0202020696e746f2062616720302c20616e20696420776974682073636f726520322077696c6c2066616c6c20696e746f2062616720312c206574632e00302023204d6967726174696f6e00610120496e20746865206576656e7420746861742074686973206c6973742065766572206368616e6765732c206120636f7079206f6620746865206f6c642062616773206c697374206d7573742062652072657461696e65642e5d012057697468207468617420604c6973743a3a6d696772617465602063616e2062652063616c6c65642c2077686963682077696c6c20706572666f726d2074686520617070726f707269617465206d6967726174696f6e2e012509173c4e6f6d696e6174696f6e506f6f6c73013c4e6f6d696e6174696f6e506f6f6c735440546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e384d6178506f6f6c4d656d626572730000100400084901204d6178696d756d206e756d626572206f66206d656d6265727320746861742063616e20657869737420696e207468652073797374656d2e20496620604e6f6e65602c207468656e2074686520636f756e74b8206d656d6265727320617265206e6f7420626f756e64206f6e20612073797374656d20776964652062617369732e544d6178506f6f6c4d656d62657273506572506f6f6c0000100400084101204d6178696d756d206e756d626572206f66206d656d626572732074686174206d61792062656c6f6e6720746f20706f6f6c2e20496620604e6f6e65602c207468656e2074686520636f756e74206f66a8206d656d62657273206973206e6f7420626f756e64206f6e20612070657220706f6f6c2062617369732e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c506f6f6c4d656d6265727300010405002d0904000c4020416374697665206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e54436f756e746572466f72506f6f6c4d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c426f6e646564506f6f6c7300010405104109040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510550904000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f7574206f66207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f726167650001040510590904000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d65746164617461010104051055010400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e4c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0075012054686973206973206f6e6c79207573656420666f7220736c617368696e6720616e64206f6e206175746f6d61746963207769746864726177207570646174652e20496e20616c6c206f7468657220696e7374616e6365732c20746865250120706f6f6c20696420697320757365642c20616e6420746865206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500a5040402040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e018d040119010c2050616c6c65744964f9082070792f6e6f706c73048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101008000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e01710918245363686564756c657201245363686564756c6572103c496e636f6d706c65746553696e6365000030040000184167656e6461010104053079090400044d01204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e1c526574726965730001040239018909040004210120526574727920636f6e66696775726174696f6e7320666f72206974656d7320746f2062652065786563757465642c20696e6465786564206279207461736b20616464726573732e184c6f6f6b757000010405043901040010f8204c6f6f6b75702066726f6d2061206e616d6520746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e00590120466f72207633202d3e207634207468652070726576696f75736c7920756e626f756e646564206964656e7469746965732061726520426c616b65322d3235362068617368656420746f20666f726d2074686520763430206964656e7469746965732e01a90401350108344d6178696d756d57656967687428400b00806e87740113cccccccccccccccc04290120546865206d6178696d756d207765696768742074686174206d6179206265207363686564756c65642070657220626c6f636b20666f7220616e7920646973706174636861626c65732e504d61785363686564756c6564506572426c6f636b101000020000141d0120546865206d6178696d756d206e756d626572206f66207363686564756c65642063616c6c7320696e2074686520717565756520666f7220612073696e676c6520626c6f636b2e0018204e4f54453a5101202b20446570656e64656e742070616c6c657473272062656e63686d61726b73206d696768742072657175697265206120686967686572206c696d697420666f72207468652073657474696e672e205365742061c420686967686572206c696d697420756e646572206072756e74696d652d62656e63686d61726b736020666561747572652e018d091920507265696d6167650120507265696d6167650c24537461747573466f72000104063491090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e4052657175657374537461747573466f72000104063499090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e2c507265696d616765466f7200010406e508a50904000001b1040141010001a9091a204f6666656e63657301204f6666656e636573081c5265706f7274730001040534ad09040004490120546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e58436f6e63757272656e745265706f727473496e6465780101080505b109c1010400042901204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e0001450100001b1c54785061757365011c54785061757365042c50617573656443616c6c7300010402510184040004b42054686520736574206f662063616c6c73207468617420617265206578706c696369746c79207061757365642e01b504014d0104284d61784e616d654c656e1010000100000c2501204d6178696d756d206c656e67746820666f722070616c6c6574206e616d6520616e642063616c6c206e616d65205343414c4520656e636f64656420737472696e67206e616d65732e00a820544f4f204c4f4e47204e414d45532057494c4c2042452054524541544544204153205041555345442e01b5091c20496d4f6e6c696e650120496d4f6e6c696e65103848656172746265617441667465720100302000000000000000002c1d012054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e207468652063757272656e74242073657373696f6e2e0025012041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c350120726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f721901207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f207468617420746865a820686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00390120546869732076616c75652077696c6c206f6e6c79206265207573656420617320612066616c6c6261636b206966207765206661696c20746f2067657420612070726f7065722073657373696f6e2d012070726f677265737320657374696d6174652066726f6d20604e65787453657373696f6e526f746174696f6e602c2061732074686f736520657374696d617465732073686f756c642062650101206d6f7265206163637572617465207468656e207468652076616c75652077652063616c63756c61746520666f7220604865617274626561744166746572602e104b6579730100b909040004d0205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e485265636569766564486561727462656174730001080505bd0820040004350120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206053657373696f6e496e6465786020616e64206041757468496e646578602e38417574686f726564426c6f636b730101080505910810100000000008150120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206056616c696461746f7249643c543e6020746f20746865c8206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e01b9040159010440556e7369676e65645072696f726974793020ffffffffffffffff10f0204120636f6e66696775726174696f6e20666f722062617365207072696f72697479206f6620756e7369676e6564207472616e73616374696f6e732e0015012054686973206973206578706f73656420736f20746861742069742063616e2062652074756e656420666f7220706172746963756c61722072756e74696d652c207768656eb4206d756c7469706c652070616c6c6574732073656e6420756e7369676e6564207472616e73616374696f6e732e01c1091d204964656e7469747901204964656e746974791c284964656e746974794f660001040500c509040010690120496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e204669727374206974656d20697320746865e020726567697374726174696f6e2c207365636f6e6420697320746865206163636f756e742773207072696d61727920757365726e616d652e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e1c53757065724f66000104020055050400086101205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e2074686174510120636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e18537562734f660101040500dd0944000000000000000000000000000000000014b820416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e001d0120546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e28526567697374726172730100e5090400104d012054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061a8207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e0029012054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e4c557365726e616d65417574686f7269746965730001040500f509040004f42041206d6170206f6620746865206163636f756e74732077686f2061726520617574686f72697a656420746f206772616e7420757365726e616d65732e444163636f756e744f66557365726e616d65000104027d01000400146d012052657665727365206c6f6f6b75702066726f6d2060757365726e616d656020746f2074686520604163636f756e7449646020746861742068617320726567697374657265642069742e205468652076616c75652073686f756c6465012062652061206b657920696e2074686520604964656e746974794f6660206d61702c20627574206974206d6179206e6f742069662074686520757365722068617320636c6561726564207468656972206964656e746974792e006901204d756c7469706c6520757365726e616d6573206d6179206d617020746f207468652073616d6520604163636f756e744964602c2062757420604964656e746974794f66602077696c6c206f6e6c79206d617020746f206f6e6548207072696d61727920757365726e616d652e4050656e64696e67557365726e616d6573000104027d01fd090400186d0120557365726e616d6573207468617420616e20617574686f7269747920686173206772616e7465642c20627574207468617420746865206163636f756e7420636f6e74726f6c6c657220686173206e6f7420636f6e6669726d65647101207468617420746865792077616e742069742e2055736564207072696d6172696c7920696e2063617365732077686572652074686520604163636f756e744964602063616e6e6f742070726f766964652061207369676e61747572655d012062656361757365207468657920617265206120707572652070726f78792c206d756c74697369672c206574632e20496e206f7264657220746f20636f6e6669726d2069742c20746865792073686f756c642063616c6c6c205b6043616c6c3a3a6163636570745f757365726e616d65605d2e001d01204669727374207475706c65206974656d20697320746865206163636f756e7420616e64207365636f6e642069732074686520616363657074616e636520646561646c696e652e01c504017901203042617369634465706f7369741840000064a7b3b6e00d000000000000000004d82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e2c427974654465706f7369741840000064a7b3b6e00d0000000000000000041d012054686520616d6f756e742068656c64206f6e206465706f7369742070657220656e636f646564206279746520666f7220612072656769737465726564206964656e746974792e445375624163636f756e744465706f73697418400000d1d21fe5ea6b05000000000000000c65012054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f7220746865206661637465012074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c350120626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e384d61785375624163636f756e7473101064000000040d0120546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e344d617852656769737472617273101014000000084d01204d6178696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c65786974797c206f662c20652e672e2c207570646174696e67206a756467656d656e74732e6450656e64696e67557365726e616d6545787069726174696f6e3020c08901000000000004150120546865206e756d626572206f6620626c6f636b732077697468696e207768696368206120757365726e616d65206772616e74206d7573742062652061636365707465642e3c4d61785375666669784c656e677468101007000000048020546865206d6178696d756d206c656e677468206f662061207375666669782e444d6178557365726e616d654c656e67746810102000000004610120546865206d6178696d756d206c656e677468206f66206120757365726e616d652c20696e636c7564696e67206974732073756666697820616e6420616e792073797374656d2d61646465642064656c696d69746572732e01010a1e1c5574696c69747900016505018101044c626174636865645f63616c6c735f6c696d69741010aa2a000004a820546865206c696d6974206f6e20746865206e756d626572206f6620626174636865642063616c6c732e01050a1f204d756c746973696701204d756c746973696704244d756c7469736967730001080502090a0d0a040004942054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e017d050185010c2c4465706f736974426173651840000068cd83c1fd77050000000000000018590120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e672061206d756c746973696720657865637574696f6e206f7220746f842073746f726520612064697370617463682063616c6c20666f72206c617465722e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069733101206034202b2073697a656f662828426c6f636b4e756d6265722c2042616c616e63652c204163636f756e74496429296020627974657320616e642077686f7365206b65792073697a652069738020603332202b2073697a656f66284163636f756e74496429602062797465732e344465706f736974466163746f721840000020f84dde700400000000000000000c55012054686520616d6f756e74206f662063757272656e6379206e65656465642070657220756e6974207468726573686f6c64207768656e206372656174696e672061206d756c746973696720657865637574696f6e2e00250120546869732069732068656c6420666f7220616464696e67203332206279746573206d6f726520696e746f2061207072652d6578697374696e672073746f726167652076616c75652e384d61785369676e61746f7269657310106400000004ec20546865206d6178696d756d20616d6f756e74206f66207369676e61746f7269657320616c6c6f77656420696e20746865206d756c74697369672e01110a2020457468657265756d0120457468657265756d141c50656e64696e670100150a040004d02043757272656e74206275696c64696e6720626c6f636b2773207472616e73616374696f6e7320616e642072656365697074732e3043757272656e74426c6f636b0000350a04000470205468652063757272656e7420457468657265756d20626c6f636b2e3c43757272656e7452656365697074730000490a0400047c205468652063757272656e7420457468657265756d2072656365697074732e6843757272656e745472616e73616374696f6e537461747573657300004d0a04000488205468652063757272656e74207472616e73616374696f6e2073746174757365732e24426c6f636b4861736801010405c9013480000000000000000000000000000000000000000000000000000000000000000000018505018d010001510a210c45564d010c45564d10304163636f756e74436f64657301010402910138040000504163636f756e74436f6465734d65746164617461000104029101550a0400003c4163636f756e7453746f72616765730101080202590a34800000000000000000000000000000000000000000000000000000000000000000002053756963696465640001040291018404000001ad0501b90100015d0a222845564d436861696e4964012845564d436861696e4964041c436861696e49640100302000000000000000000448205468652045564d20636861696e2049442e00000000232844796e616d6963466565012844796e616d6963466565082c4d696e47617350726963650100c90180000000000000000000000000000000000000000000000000000000000000000000445461726765744d696e47617350726963650000c90104000001bd05000000241c42617365466565011c426173654665650834426173654665655065724761730100c9018040420f00000000000000000000000000000000000000000000000000000000000028456c61737469636974790100d1011048e801000001c10501c50100002544486f7466697853756666696369656e74730001c505000001610a2618436c61696d730118436c61696d731418436c61696d7300010406d9011804000014546f74616c01001840000000000000000000000000000000000030457870697279436f6e6669670000650a040004c82045787069727920626c6f636b20616e64206163636f756e7420746f206465706f73697420657870697265642066756e64731c56657374696e6700010406d901e505040010782056657374696e67207363686564756c6520666f72206120636c61696d2e0d012046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672ee4205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2ecc2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e1c5369676e696e6700010406d901f505040004c0205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e01cd0501d5010418507265666978386c68436c61696d20544e547320746f20746865206163636f756e743a0001690a271450726f7879011450726f7879081c50726f7869657301010405006d0a4400000000000000000000000000000000000845012054686520736574206f66206163636f756e742070726f786965732e204d61707320746865206163636f756e74207768696368206861732064656c65676174656420746f20746865206163636f756e7473210120776869636820617265206265696e672064656c65676174656420746f2c20746f67657468657220776974682074686520616d6f756e742068656c64206f6e206465706f7369742e34416e6e6f756e63656d656e747301010405007d0a44000000000000000000000000000000000004ac2054686520616e6e6f756e63656d656e7473206d616465206279207468652070726f787920286b6579292e01f90501e101184050726f78794465706f736974426173651840000018e1c095e36c050000000000000010110120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720612070726f78792e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069732501206073697a656f662842616c616e6365296020627974657320616e642077686f7365206b65792073697a65206973206073697a656f66284163636f756e74496429602062797465732e4850726f78794465706f736974466163746f7218400000e16740659404000000000000000014bc2054686520616d6f756e74206f662063757272656e6379206e6565646564207065722070726f78792061646465642e00350120546869732069732068656c6420666f7220616464696e6720333220627974657320706c757320616e20696e7374616e6365206f66206050726f78795479706560206d6f726520696e746f20616101207072652d6578697374696e672073746f726167652076616c75652e20546875732c207768656e20636f6e6669677572696e67206050726f78794465706f736974466163746f7260206f6e652073686f756c642074616b65f420696e746f206163636f756e7420603332202b2070726f78795f747970652e656e636f646528292e6c656e282960206279746573206f6620646174612e284d617850726f7869657310102000000004f020546865206d6178696d756d20616d6f756e74206f662070726f7869657320616c6c6f77656420666f7220612073696e676c65206163636f756e742e284d617850656e64696e6710102000000004450120546865206d6178696d756d20616d6f756e74206f662074696d652d64656c6179656420616e6e6f756e63656d656e747320746861742061726520616c6c6f77656420746f2062652070656e64696e672e5c416e6e6f756e63656d656e744465706f736974426173651840000018e1c095e36c050000000000000010310120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720616e20616e6e6f756e63656d656e742e00490120546869732069732068656c64207768656e2061206e65772073746f72616765206974656d20686f6c64696e672061206042616c616e636560206973206372656174656420287479706963616c6c7920313620206279746573292e64416e6e6f756e63656d656e744465706f736974466163746f7218400000c2cf80ca2809000000000000000010d42054686520616d6f756e74206f662063757272656e6379206e65656465642070657220616e6e6f756e63656d656e74206d6164652e00590120546869732069732068656c6420666f7220616464696e6720616e20604163636f756e744964602c2060486173686020616e642060426c6f636b4e756d6265726020287479706963616c6c79203638206279746573298c20696e746f2061207072652d6578697374696e672073746f726167652076616c75652e018d0a2c504d756c7469417373657444656c65676174696f6e01504d756c7469417373657444656c65676174696f6e1c244f70657261746f72730001040200910a040004882053746f7261676520666f72206f70657261746f7220696e666f726d6174696f6e2e3043757272656e74526f756e640100101000000000047c2053746f7261676520666f72207468652063757272656e7420726f756e642e1c41745374616b6500010802029108b90a040004050120536e617073686f74206f6620636f6c6c61746f722064656c65676174696f6e207374616b6520617420746865207374617274206f662074686520726f756e642e2844656c656761746f72730001040200bd0a0400048c2053746f7261676520666f722064656c656761746f7220696e666f726d6174696f6e2e305265776172645661756c74730001040218fd0a040004782053746f7261676520666f722074686520726577617264207661756c74735c41737365744c6f6f6b75705265776172645661756c747300010402f10118040004782053746f7261676520666f722074686520726577617264207661756c74734c526577617264436f6e66696753746f726167650000010b04000869012053746f7261676520666f72207468652072657761726420636f6e66696775726174696f6e2c20776869636820696e636c75646573204150592c2063617020666f72206173736574732c20616e642077686974656c69737465643020626c75657072696e74732e01010601ed0130584d617844656c656761746f72426c75657072696e747310103200000004150120546865206d6178696d756d206e756d626572206f6620626c75657072696e747320612064656c656761746f722063616e206861766520696e204669786564206d6f64652e544d61784f70657261746f72426c75657072696e747310103200000004e820546865206d6178696d756d206e756d626572206f6620626c75657072696e747320616e206f70657261746f722063616e20737570706f72742e4c4d61785769746864726177526571756573747310100500000004f820546865206d6178696d756d206e756d626572206f6620776974686472617720726571756573747320612064656c656761746f722063616e20686176652e384d617844656c65676174696f6e7310103200000004e020546865206d6178696d756d206e756d626572206f662064656c65676174696f6e7320612064656c656761746f722063616e20686176652e484d6178556e7374616b65526571756573747310100500000004f420546865206d6178696d756d206e756d626572206f6620756e7374616b6520726571756573747320612064656c656761746f722063616e20686176652e544d696e4f70657261746f72426f6e64416d6f756e7418401027000000000000000000000000000004d820546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220616e206f70657261746f722e444d696e44656c6567617465416d6f756e741840e803000000000000000000000000000004d420546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220612064656c65676174652e30426f6e644475726174696f6e10100a00000004b020546865206475726174696f6e20666f7220776869636820746865207374616b65206973206c6f636b65642e4c4c656176654f70657261746f727344656c617910100a000000045501204e756d626572206f6620726f756e64732074686174206f70657261746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e544f70657261746f72426f6e644c65737344656c6179101001000000045901204e756d626572206f6620726f756e6473206f70657261746f7220726571756573747320746f2064656372656173652073656c662d7374616b65206d757374207761697420746f2062652065786563757461626c652e504c6561766544656c656761746f727344656c6179101001000000045901204e756d626572206f6620726f756e647320746861742064656c656761746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e5c44656c65676174696f6e426f6e644c65737344656c6179101005000000045501204e756d626572206f6620726f756e647320746861742064656c65676174696f6e20756e7374616b65207265717565737473206d7573742077616974206265666f7265206265696e672065786563757461626c652e01150b2d20536572766963657301205365727669636573403c4e657874426c75657072696e74496401003020000000000000000004a820546865206e657874206672656520494420666f722061207365727669636520626c75657072696e742e504e6578745365727669636552657175657374496401003020000000000000000004a020546865206e657874206672656520494420666f722061207365727669636520726571756573742e384e657874496e7374616e6365496401003020000000000000000004a420546865206e657874206672656520494420666f722061207365727669636520496e7374616e63652e344e6578744a6f6243616c6c4964010030200000000000000000049420546865206e657874206672656520494420666f72206120736572766963652063616c6c2e5c4e657874556e6170706c696564536c617368496e646578010010100000000004a020546865206e657874206672656520494420666f72206120756e6170706c69656420736c6173682e28426c75657072696e74730001040630190b08010004bc20546865207365727669636520626c75657072696e747320616c6f6e672077697468207468656972206f776e65722e244f70657261746f727300010806061d0b010208010908c020546865206f70657261746f727320666f722061207370656369666963207365727669636520626c75657072696e742ec420426c75657072696e74204944202d3e204f70657261746f72202d3e204f70657261746f7220507265666572656e6365733c5365727669636552657175657374730001040630210b08010c08b420546865207365727669636520726571756573747320616c6f6e672077697468207468656972206f776e65722e782052657175657374204944202d3e2053657276696365205265717565737424496e7374616e6365730001040630410b08010e085c2054686520536572766963657320496e7374616e636573582053657276696365204944202d3e2053657276696365305573657253657276696365730101040600510b0400085c2055736572205365727669636520496e7374616e636573782055736572204163636f756e74204944202d3e2053657276696365204944204a6f6243616c6c730001080606e902590b0801170858205468652053657276696365204a6f622043616c6c73882053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c284a6f62526573756c74730001080606e9025d0b0801170874205468652053657276696365204a6f622043616c6c20526573756c7473a42053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c20526573756c7440556e6170706c696564536c61736865730001080606bd08610b0801240cc420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e009020457261496e646578202d3e20496e646578202d3e20556e6170706c696564536c617368984d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e730100650b04000cd420416c6c20746865204d617374657220426c75657072696e742053657276696365204d616e6167657273207265766973696f6e732e00a02057686572652074686520696e64657820697320746865207265766973696f6e206e756d6265722e404f70657261746f727350726f66696c650001040600690b08011b005853746167696e67536572766963655061796d656e74730001040630750b040014f420486f6c6473207468652073657276696365207061796d656e7420696e666f726d6174696f6e20666f722061207365727669636520726571756573742e3d01204f6e636520746865207365727669636520697320696e697469617465642c20746865207061796d656e74206973207472616e7366657272656420746f20746865204d42534d20616e6420746869736020696e666f726d6174696f6e2069732072656d6f7665642e0094205365727669636520526571757374204944202d3e2053657276696365205061796d656e7401190601fd015c4050616c6c657445564d4164647265737391015011111111111111111111111111111111111111110458206050616c6c6574602045564d20416464726573732e244d61784669656c647310100001000004a0204d6178696d756d206e756d626572206f66206669656c647320696e2061206a6f622063616c6c2e344d61784669656c647353697a65101000040000049c204d6178696d756d2073697a65206f662061206669656c6420696e2061206a6f622063616c6c2e444d61784d657461646174614c656e67746810100004000004a8204d6178696d756d206c656e677468206f66206d6574616461746120737472696e67206c656e6774682e444d61784a6f6273506572536572766963651010000400000490204d6178696d756d206e756d626572206f66206a6f62732070657220736572766963652e584d61784f70657261746f72735065725365727669636510100004000004a4204d6178696d756d206e756d626572206f66204f70657261746f72732070657220736572766963652e4c4d61785065726d697474656443616c6c65727310100001000004c4204d6178696d756d206e756d626572206f66207065726d69747465642063616c6c6572732070657220736572766963652e584d617853657276696365735065724f70657261746f7210100004000004a4204d6178696d756d206e756d626572206f6620736572766963657320706572206f70657261746f722e604d6178426c75657072696e74735065724f70657261746f7210100004000004ac204d6178696d756d206e756d626572206f6620626c75657072696e747320706572206f70657261746f722e484d61785365727669636573506572557365721010000400000494204d6178696d756d206e756d626572206f662073657276696365732070657220757365722e504d617842696e6172696573506572476164676574101040000000049c204d6178696d756d206e756d626572206f662062696e617269657320706572206761646765742e4c4d6178536f75726365735065724761646765741010400000000498204d6178696d756d206e756d626572206f6620736f757263657320706572206761646765742e444d61784769744f776e65724c656e677468101000040000046820476974206f776e6572206d6178696d756d206c656e6774682e404d61784769745265706f4c656e677468101000040000047c20476974207265706f7369746f7279206d6178696d756d206c656e6774682e3c4d61784769745461674c656e67746810100004000004602047697420746167206d6178696d756d206c656e6774682e4c4d617842696e6172794e616d654c656e67746810100004000004702062696e617279206e616d65206d6178696d756d206c656e6774682e444d617849706673486173684c656e67746810102e000000046820495046532068617368206d6178696d756d206c656e6774682e684d6178436f6e7461696e657252656769737472794c656e677468101000040000048c20436f6e7461696e6572207265676973747279206d6178696d756d206c656e6774682e6c4d6178436f6e7461696e6572496d6167654e616d654c656e677468101000040000049420436f6e7461696e657220696d616765206e616d65206d6178696d756d206c656e6774682e684d6178436f6e7461696e6572496d6167655461674c656e677468101000040000049020436f6e7461696e657220696d61676520746167206d6178696d756d206c656e6774682e4c4d6178417373657473506572536572766963651010400000000498204d6178696d756d206e756d626572206f66206173736574732070657220736572766963652ea04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e731010ffffffff042101204d6178696d756d206e756d626572206f662076657273696f6e73206f66204d617374657220426c75657072696e742053657276696365204d616e6167657220616c6c6f7765642e48536c61736844656665724475726174696f6e101007000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e017d0b330c4c7374010c4c73744c40546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c426f6e646564506f6f6c730001040510850b040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510990b04000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f757420666f207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f7261676500010405109d0b04000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d657461646174610101040510b50b0400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e40556e626f6e64696e674d656d626572730001040500b90b04000c4c20556e626f6e64696e67206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e68436f756e746572466f72556e626f6e64696e674d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61704c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0055012054686973206973206f6e6c79207573656420666f7220736c617368696e672e20496e20616c6c206f7468657220696e7374616e6365732c2074686520706f6f6c20696420697320757365642c20616e6420746865c0206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500cd0b0400040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e01e906014502142050616c6c65744964f9082070792f746e6c7374048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101020000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e344d61784e616d654c656e677468101032000000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c206e616d652e344d617849636f6e4c656e6774681010f4010000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c2069636f6e2e01d10b34d90b042448436865636b4e6f6e5a65726f53656e646572e10b8440436865636b5370656356657273696f6ee50b1038436865636b547856657273696f6ee90b1030436865636b47656e65736973ed0b3438436865636b4d6f7274616c697479f10b3428436865636b4e6f6e6365f90b842c436865636b576569676874fd0b84604368617267655472616e73616374696f6e5061796d656e74010c8444436865636b4d6574616461746148617368050c3d01110c","id":"1"} \ No newline at end of file +{"jsonrpc":"2.0","result":"0x6d6574610e350c000c1c73705f636f72651863727970746f2c4163636f756e7449643332000004000401205b75383b2033325d0000040000032000000008000800000503000c08306672616d655f73797374656d2c4163636f756e74496e666f08144e6f6e636501102c4163636f756e74446174610114001401146e6f6e63651001144e6f6e6365000124636f6e73756d657273100120526566436f756e7400012470726f766964657273100120526566436f756e7400012c73756666696369656e7473100120526566436f756e740001106461746114012c4163636f756e74446174610000100000050500140c3c70616c6c65745f62616c616e6365731474797065732c4163636f756e7444617461041c42616c616e63650118001001106672656518011c42616c616e6365000120726573657276656418011c42616c616e636500011866726f7a656e18011c42616c616e6365000114666c6167731c01284578747261466c61677300001800000507001c0c3c70616c6c65745f62616c616e636573147479706573284578747261466c61677300000400180110753132380000200000050000240c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540128000c01186e6f726d616c2801045400012c6f7065726174696f6e616c280104540001246d616e6461746f7279280104540000280c2873705f77656967687473247765696768745f76321857656967687400000801207265665f74696d652c010c75363400012870726f6f665f73697a652c010c75363400002c000006300030000005060034083c7072696d69746976655f74797065731048323536000004000401205b75383b2033325d00003800000208003c102873705f72756e74696d651c67656e65726963186469676573741844696765737400000401106c6f677340013c5665633c4469676573744974656d3e000040000002440044102873705f72756e74696d651c67656e6572696318646967657374284469676573744974656d0001142850726552756e74696d650800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e00060024436f6e73656e7375730800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000400105365616c0800480144436f6e73656e737573456e67696e654964000038011c5665633c75383e000500144f74686572040038011c5665633c75383e0000006452756e74696d65456e7669726f6e6d656e745570646174656400080000480000030400000008004c00000250005008306672616d655f73797374656d2c4576656e745265636f7264080445015404540134000c011470686173655d02011450686173650001146576656e7454010445000118746f70696373c10101185665633c543e000054085874616e676c655f746573746e65745f72756e74696d653052756e74696d654576656e740001901853797374656d04005801706672616d655f73797374656d3a3a4576656e743c52756e74696d653e000100105375646f04007c016c70616c6c65745f7375646f3a3a4576656e743c52756e74696d653e0003001841737365747304008c017470616c6c65745f6173736574733a3a4576656e743c52756e74696d653e0005002042616c616e636573040090017c70616c6c65745f62616c616e6365733a3a4576656e743c52756e74696d653e000600485472616e73616374696f6e5061796d656e7404009801a870616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4576656e743c52756e74696d653e0007001c4772616e64706104009c015470616c6c65745f6772616e6470613a3a4576656e74000a001c496e64696365730400ac017870616c6c65745f696e64696365733a3a4576656e743c52756e74696d653e000b002444656d6f63726163790400b0018070616c6c65745f64656d6f63726163793a3a4576656e743c52756e74696d653e000c001c436f756e63696c0400c401fc70616c6c65745f636f6c6c6563746976653a3a4576656e743c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d001c56657374696e670400c8017870616c6c65745f76657374696e673a3a4576656e743c52756e74696d653e000e0024456c656374696f6e730400cc01a470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4576656e743c52756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400d801d070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653a3a4576656e743c52756e74696d653e0010001c5374616b696e670400ec017870616c6c65745f7374616b696e673a3a4576656e743c52756e74696d653e0011001c53657373696f6e04000501015470616c6c65745f73657373696f6e3a3a4576656e7400120020547265617375727904000901017c70616c6c65745f74726561737572793a3a4576656e743c52756e74696d653e00140020426f756e7469657304000d01017c70616c6c65745f626f756e746965733a3a4576656e743c52756e74696d653e001500344368696c64426f756e7469657304001101019470616c6c65745f6368696c645f626f756e746965733a3a4576656e743c52756e74696d653e00160020426167734c69737404001501018070616c6c65745f626167735f6c6973743a3a4576656e743c52756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c7304001901019c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a4576656e743c52756e74696d653e001800245363686564756c657204003501018070616c6c65745f7363686564756c65723a3a4576656e743c52756e74696d653e00190020507265696d61676504004101017c70616c6c65745f707265696d6167653a3a4576656e743c52756e74696d653e001a00204f6666656e63657304004501015870616c6c65745f6f6666656e6365733a3a4576656e74001b001c5478506175736504004d01017c70616c6c65745f74785f70617573653a3a4576656e743c52756e74696d653e001c0020496d4f6e6c696e6504005901018070616c6c65745f696d5f6f6e6c696e653a3a4576656e743c52756e74696d653e001d00204964656e7469747904007901017c70616c6c65745f6964656e746974793a3a4576656e743c52756e74696d653e001e001c5574696c69747904008101015470616c6c65745f7574696c6974793a3a4576656e74001f00204d756c746973696704008501017c70616c6c65745f6d756c74697369673a3a4576656e743c52756e74696d653e00200020457468657265756d04008d01015870616c6c65745f657468657265756d3a3a4576656e740021000c45564d0400b901016870616c6c65745f65766d3a3a4576656e743c52756e74696d653e0022001c426173654665650400c501015870616c6c65745f626173655f6665653a3a4576656e7400250018436c61696d730400d501019470616c6c65745f61697264726f705f636c61696d733a3a4576656e743c52756e74696d653e0027001450726f78790400e101017070616c6c65745f70726f78793a3a4576656e743c52756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400ed0101b470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e3a3a4576656e743c52756e74696d653e002d002053657276696365730400f501017c70616c6c65745f73657276696365733a3a4576656e743c52756e74696d653e0033000c4c737404003d02018470616c6c65745f74616e676c655f6c73743a3a4576656e743c52756e74696d653e0034001c5265776172647304005102017870616c6c65745f726577617264733a3a4576656e743c52756e74696d653e00350000580c306672616d655f73797374656d1870616c6c6574144576656e7404045400011c4045787472696e7369635375636365737304013464697370617463685f696e666f5c01304469737061746368496e666f00000490416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e3c45787472696e7369634661696c656408013864697370617463685f6572726f7268013444697370617463684572726f7200013464697370617463685f696e666f5c01304469737061746368496e666f00010450416e2065787472696e736963206661696c65642e2c436f64655570646174656400020450603a636f6465602077617320757064617465642e284e65774163636f756e7404011c6163636f756e74000130543a3a4163636f756e7449640003046841206e6577206163636f756e742077617320637265617465642e344b696c6c65644163636f756e7404011c6163636f756e74000130543a3a4163636f756e74496400040458416e206163636f756e7420776173207265617065642e2052656d61726b656408011873656e646572000130543a3a4163636f756e7449640001106861736834011c543a3a48617368000504704f6e206f6e2d636861696e2072656d61726b2068617070656e65642e4455706772616465417574686f72697a6564080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c00060468416e20757067726164652077617320617574686f72697a65642e04704576656e7420666f72207468652053797374656d2070616c6c65742e5c0c346672616d655f737570706f7274206469737061746368304469737061746368496e666f00000c0118776569676874280118576569676874000114636c6173736001344469737061746368436c617373000120706179735f666565640110506179730000600c346672616d655f737570706f7274206469737061746368344469737061746368436c61737300010c184e6f726d616c0000002c4f7065726174696f6e616c000100244d616e6461746f727900020000640c346672616d655f737570706f727420646973706174636810506179730001080c596573000000084e6f0001000068082873705f72756e74696d653444697370617463684572726f72000138144f746865720000003043616e6e6f744c6f6f6b7570000100244261644f726967696e000200184d6f64756c6504006c012c4d6f64756c654572726f7200030044436f6e73756d657252656d61696e696e670004002c4e6f50726f76696465727300050040546f6f4d616e79436f6e73756d65727300060014546f6b656e0400700128546f6b656e4572726f720007002841726974686d65746963040074013c41726974686d657469634572726f72000800345472616e73616374696f6e616c04007801485472616e73616374696f6e616c4572726f7200090024457868617573746564000a0028436f7272757074696f6e000b002c556e617661696c61626c65000c0038526f6f744e6f74416c6c6f776564000d00006c082873705f72756e74696d652c4d6f64756c654572726f720000080114696e64657808010875380001146572726f7248018c5b75383b204d41585f4d4f44554c455f4552524f525f454e434f4445445f53495a455d000070082873705f72756e74696d6528546f6b656e4572726f720001284046756e6473556e617661696c61626c65000000304f6e6c7950726f76696465720001003042656c6f774d696e696d756d0002003043616e6e6f7443726561746500030030556e6b6e6f776e41737365740004001846726f7a656e0005002c556e737570706f727465640006004043616e6e6f74437265617465486f6c64000700344e6f74457870656e6461626c650008001c426c6f636b65640009000074083473705f61726974686d657469633c41726974686d657469634572726f7200010c24556e646572666c6f77000000204f766572666c6f77000100384469766973696f6e42795a65726f0002000078082873705f72756e74696d65485472616e73616374696f6e616c4572726f72000108304c696d6974526561636865640000001c4e6f4c61796572000100007c0c2c70616c6c65745f7375646f1870616c6c6574144576656e7404045400011014537564696404012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e00047041207375646f2063616c6c206a75737420746f6f6b20706c6163652e284b65794368616e67656408010c6f6c648801504f7074696f6e3c543a3a4163636f756e7449643e04b4546865206f6c64207375646f206b657920286966206f6e65207761732070726576696f75736c7920736574292e010c6e6577000130543a3a4163636f756e7449640488546865206e6577207375646f206b657920286966206f6e652077617320736574292e010478546865207375646f206b657920686173206265656e20757064617465642e284b657952656d6f76656400020480546865206b657920776173207065726d616e656e746c792072656d6f7665642e285375646f4173446f6e6504012c7375646f5f726573756c748001384469737061746368526573756c7404b454686520726573756c74206f66207468652063616c6c206d61646520627920746865207375646f20757365722e0304c841205b7375646f5f61735d2850616c6c65743a3a7375646f5f6173292063616c6c206a75737420746f6f6b20706c6163652e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574800418526573756c740804540184044501680108084f6b040084000000000c45727204006800000100008400000400008804184f7074696f6e04045401000108104e6f6e6500000010536f6d6504000000000100008c0c3470616c6c65745f6173736574731870616c6c6574144576656e740804540004490001681c437265617465640c012061737365745f6964180128543a3a4173736574496400011c63726561746f72000130543a3a4163636f756e7449640001146f776e6572000130543a3a4163636f756e74496400000474536f6d6520617373657420636c6173732077617320637265617465642e184973737565640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500010460536f6d65206173736574732077657265206973737565642e2c5472616e7366657272656410012061737365745f6964180128543a3a4173736574496400011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500020474536f6d65206173736574732077657265207472616e736665727265642e184275726e65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400011c62616c616e6365180128543a3a42616c616e63650003046c536f6d652061737365747320776572652064657374726f7965642e2c5465616d4368616e67656410012061737365745f6964180128543a3a41737365744964000118697373756572000130543a3a4163636f756e74496400011461646d696e000130543a3a4163636f756e74496400011c667265657a6572000130543a3a4163636f756e74496400040470546865206d616e6167656d656e74207465616d206368616e6765642e304f776e65724368616e67656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400050448546865206f776e6572206368616e6765642e1846726f7a656e08012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400060478536f6d65206163636f756e74206077686f60207761732066726f7a656e2e1854686177656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e74496400070478536f6d65206163636f756e74206077686f6020776173207468617765642e2c417373657446726f7a656e04012061737365745f6964180128543a3a4173736574496400080484536f6d65206173736574206061737365745f696460207761732066726f7a656e2e2c417373657454686177656404012061737365745f6964180128543a3a4173736574496400090484536f6d65206173736574206061737365745f69646020776173207468617765642e444163636f756e747344657374726f7965640c012061737365745f6964180128543a3a417373657449640001486163636f756e74735f64657374726f79656410010c7533320001486163636f756e74735f72656d61696e696e6710010c753332000a04a04163636f756e747320776572652064657374726f79656420666f7220676976656e2061737365742e48417070726f76616c7344657374726f7965640c012061737365745f6964180128543a3a4173736574496400014c617070726f76616c735f64657374726f79656410010c75333200014c617070726f76616c735f72656d61696e696e6710010c753332000b04a4417070726f76616c7320776572652064657374726f79656420666f7220676976656e2061737365742e484465737472756374696f6e5374617274656404012061737365745f6964180128543a3a41737365744964000c04d0416e20617373657420636c61737320697320696e207468652070726f63657373206f66206265696e672064657374726f7965642e2444657374726f79656404012061737365745f6964180128543a3a41737365744964000d0474416e20617373657420636c617373207761732064657374726f7965642e30466f7263654372656174656408012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e744964000e048c536f6d6520617373657420636c6173732077617320666f7263652d637265617465642e2c4d6574616461746153657414012061737365745f6964180128543a3a417373657449640001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000f049c4e6577206d6574616461746120686173206265656e2073657420666f7220616e2061737365742e3c4d65746164617461436c656172656404012061737365745f6964180128543a3a417373657449640010049c4d6574616461746120686173206265656e20636c656172656420666f7220616e2061737365742e40417070726f7665645472616e7366657210012061737365745f6964180128543a3a41737365744964000118736f75726365000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650011043101284164646974696f6e616c292066756e64732068617665206265656e20617070726f76656420666f72207472616e7366657220746f20612064657374696e6174696f6e206163636f756e742e44417070726f76616c43616e63656c6c65640c012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e744964001204f0416e20617070726f76616c20666f72206163636f756e74206064656c656761746560207761732063616e63656c6c656420627920606f776e6572602e4c5472616e73666572726564417070726f76656414012061737365745f6964180128543a3a417373657449640001146f776e6572000130543a3a4163636f756e74496400012064656c6567617465000130543a3a4163636f756e74496400012c64657374696e6174696f6e000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650013083101416e2060616d6f756e746020776173207472616e7366657272656420696e2069747320656e7469726574792066726f6d20606f776e65726020746f206064657374696e6174696f6e602062796074686520617070726f766564206064656c6567617465602e4841737365745374617475734368616e67656404012061737365745f6964180128543a3a41737365744964001404f8416e2061737365742068617320686164206974732061747472696275746573206368616e676564206279207468652060466f72636560206f726967696e2e5841737365744d696e42616c616e63654368616e67656408012061737365745f6964180128543a3a4173736574496400013c6e65775f6d696e5f62616c616e6365180128543a3a42616c616e63650015040101546865206d696e5f62616c616e6365206f6620616e20617373657420686173206265656e207570646174656420627920746865206173736574206f776e65722e1c546f75636865640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640001246465706f7369746f72000130543a3a4163636f756e744964001604fc536f6d65206163636f756e74206077686f6020776173206372656174656420776974682061206465706f7369742066726f6d20606465706f7369746f72602e1c426c6f636b656408012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e7449640017047c536f6d65206163636f756e74206077686f602077617320626c6f636b65642e244465706f73697465640c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365001804dc536f6d65206173736574732077657265206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e2457697468647261776e0c012061737365745f6964180128543a3a4173736574496400010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650019042101536f6d652061737365747320776572652077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574900c3c70616c6c65745f62616c616e6365731870616c6c6574144576656e740804540004490001581c456e646f77656408011c6163636f756e74000130543a3a4163636f756e744964000130667265655f62616c616e6365180128543a3a42616c616e6365000004b8416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e20447573744c6f737408011c6163636f756e74000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650001083d01416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c78726573756c74696e6720696e20616e206f75747269676874206c6f73732e205472616e736665720c011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650002044c5472616e73666572207375636365656465642e2842616c616e636553657408010c77686f000130543a3a4163636f756e74496400011066726565180128543a3a42616c616e636500030468412062616c616e6365207761732073657420627920726f6f742e20526573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000404e0536f6d652062616c616e63652077617320726573657276656420286d6f7665642066726f6d206672656520746f207265736572766564292e28556e726573657276656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000504e8536f6d652062616c616e63652077617320756e726573657276656420286d6f7665642066726f6d20726573657276656420746f2066726565292e4852657365727665526570617472696174656410011066726f6d000130543a3a4163636f756e744964000108746f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500014864657374696e6174696f6e5f7374617475739401185374617475730006084d01536f6d652062616c616e636520776173206d6f7665642066726f6d207468652072657365727665206f6620746865206669727374206163636f756e7420746f20746865207365636f6e64206163636f756e742ed846696e616c20617267756d656e7420696e64696361746573207468652064657374696e6174696f6e2062616c616e636520747970652e1c4465706f73697408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000704d8536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20576974686472617708010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650008041d01536f6d6520616d6f756e74207761732077697468647261776e2066726f6d20746865206163636f756e742028652e672e20666f72207472616e73616374696f6e2066656573292e1c536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e63650009040101536f6d6520616d6f756e74207761732072656d6f7665642066726f6d20746865206163636f756e742028652e672e20666f72206d69736265686176696f72292e184d696e74656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000a049c536f6d6520616d6f756e7420776173206d696e74656420696e746f20616e206163636f756e742e184275726e656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000b049c536f6d6520616d6f756e7420776173206275726e65642066726f6d20616e206163636f756e742e2453757370656e64656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000c041501536f6d6520616d6f756e74207761732073757370656e6465642066726f6d20616e206163636f756e74202869742063616e20626520726573746f726564206c61746572292e20526573746f72656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e6365000d04a4536f6d6520616d6f756e742077617320726573746f72656420696e746f20616e206163636f756e742e20557067726164656404010c77686f000130543a3a4163636f756e744964000e0460416e206163636f756e74207761732075706772616465642e18497373756564040118616d6f756e74180128543a3a42616c616e6365000f042d01546f74616c2069737375616e63652077617320696e637265617365642062792060616d6f756e74602c206372656174696e6720612063726564697420746f2062652062616c616e6365642e2452657363696e646564040118616d6f756e74180128543a3a42616c616e63650010042501546f74616c2069737375616e636520776173206465637265617365642062792060616d6f756e74602c206372656174696e672061206465627420746f2062652062616c616e6365642e184c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500110460536f6d652062616c616e636520776173206c6f636b65642e20556e6c6f636b656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500120468536f6d652062616c616e63652077617320756e6c6f636b65642e1846726f7a656e08010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500130460536f6d652062616c616e6365207761732066726f7a656e2e1854686177656408010c77686f000130543a3a4163636f756e744964000118616d6f756e74180128543a3a42616c616e636500140460536f6d652062616c616e636520776173207468617765642e4c546f74616c49737375616e6365466f7263656408010c6f6c64180128543a3a42616c616e636500010c6e6577180128543a3a42616c616e6365001504ac5468652060546f74616c49737375616e6365602077617320666f72636566756c6c79206368616e6765642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749414346672616d655f737570706f72741874726169747318746f6b656e73106d6973633442616c616e6365537461747573000108104672656500000020526573657276656400010000980c6870616c6c65745f7472616e73616374696f6e5f7061796d656e741870616c6c6574144576656e74040454000104485472616e73616374696f6e466565506169640c010c77686f000130543a3a4163636f756e74496400012861637475616c5f66656518013042616c616e63654f663c543e00010c74697018013042616c616e63654f663c543e000008590141207472616e73616374696f6e20666565206061637475616c5f666565602c206f662077686963682060746970602077617320616464656420746f20746865206d696e696d756d20696e636c7573696f6e206665652c5c686173206265656e2070616964206279206077686f602e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749c0c3870616c6c65745f6772616e6470611870616c6c6574144576656e7400010c384e6577417574686f726974696573040134617574686f726974795f736574a00134417574686f726974794c6973740000048c4e657720617574686f726974792073657420686173206265656e206170706c6965642e185061757365640001049843757272656e7420617574686f726974792073657420686173206265656e207061757365642e1c526573756d65640002049c43757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574a0000002a400a400000408a83000a80c5073705f636f6e73656e7375735f6772616e6470610c617070185075626c69630000040004013c656432353531393a3a5075626c69630000ac0c3870616c6c65745f696e64696365731870616c6c6574144576656e7404045400010c34496e64657841737369676e656408010c77686f000130543a3a4163636f756e744964000114696e64657810013c543a3a4163636f756e74496e6465780000047441206163636f756e7420696e646578207761732061737369676e65642e28496e6465784672656564040114696e64657810013c543a3a4163636f756e74496e646578000104bc41206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e2c496e64657846726f7a656e080114696e64657810013c543a3a4163636f756e74496e64657800010c77686f000130543a3a4163636f756e744964000204e841206163636f756e7420696e64657820686173206265656e2066726f7a656e20746f206974732063757272656e74206163636f756e742049442e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b00c4070616c6c65745f64656d6f63726163791870616c6c6574144576656e740404540001442050726f706f73656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000004bc41206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e185461626c656408013870726f706f73616c5f696e64657810012450726f70496e64657800011c6465706f73697418013042616c616e63654f663c543e000104d841207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e3845787465726e616c5461626c656400020494416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e1c537461727465640801247265665f696e64657810013c5265666572656e64756d496e6465780001247468726573686f6c64b40134566f74655468726573686f6c640003045c41207265666572656e64756d2068617320626567756e2e185061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000404ac412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e244e6f745061737365640401247265665f696e64657810013c5265666572656e64756d496e646578000504ac412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e2443616e63656c6c65640401247265665f696e64657810013c5265666572656e64756d496e6465780006048041207265666572656e64756d20686173206265656e2063616e63656c6c65642e2444656c65676174656408010c77686f000130543a3a4163636f756e744964000118746172676574000130543a3a4163636f756e744964000704dc416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e2c556e64656c65676174656404011c6163636f756e74000130543a3a4163636f756e744964000804e4416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e185665746f65640c010c77686f000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114756e74696c300144426c6f636b4e756d626572466f723c543e00090494416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e2c426c61636b6c697374656404013470726f706f73616c5f6861736834011c543a3a48617368000a04c4412070726f706f73616c5f6861736820686173206265656e20626c61636b6c6973746564207065726d616e656e746c792e14566f7465640c0114766f746572000130543a3a4163636f756e7449640001247265665f696e64657810013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e000b0490416e206163636f756e742068617320766f74656420696e2061207265666572656e64756d205365636f6e6465640801207365636f6e646572000130543a3a4163636f756e74496400012870726f705f696e64657810012450726f70496e646578000c0488416e206163636f756e7420686173207365636f6e64656420612070726f706f73616c4050726f706f73616c43616e63656c656404012870726f705f696e64657810012450726f70496e646578000d0460412070726f706f73616c20676f742063616e63656c65642e2c4d657461646174615365740801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0e04d44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e207365742e3c4d65746164617461436c65617265640801146f776e6572c001344d657461646174614f776e6572043c4d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e0f04e44d6574616461746120666f7220612070726f706f73616c206f722061207265666572656e64756d20686173206265656e20636c65617265642e4c4d657461646174615472616e736665727265640c0128707265765f6f776e6572c001344d657461646174614f776e6572046050726576696f7573206d65746164617461206f776e65722e01146f776e6572c001344d657461646174614f776e6572044c4e6577206d65746164617461206f776e65722e01106861736834011c543a3a486173680438507265696d61676520686173682e1004ac4d6574616461746120686173206265656e207472616e7366657272656420746f206e6577206f776e65722e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574b40c4070616c6c65745f64656d6f637261637938766f74655f7468726573686f6c6434566f74655468726573686f6c6400010c5053757065724d616a6f72697479417070726f76650000005053757065724d616a6f72697479416761696e73740001003853696d706c654d616a6f7269747900020000b80c4070616c6c65745f64656d6f637261637910766f74652c4163636f756e74566f7465041c42616c616e636501180108205374616e64617264080110766f7465bc0110566f746500011c62616c616e636518011c42616c616e63650000001453706c697408010c61796518011c42616c616e636500010c6e617918011c42616c616e636500010000bc0c4070616c6c65745f64656d6f637261637910766f746510566f74650000040008000000c00c4070616c6c65745f64656d6f6372616379147479706573344d657461646174614f776e657200010c2045787465726e616c0000002050726f706f73616c040010012450726f70496e646578000100285265666572656e64756d040010013c5265666572656e64756d496e64657800020000c40c4470616c6c65745f636f6c6c6563746976651870616c6c6574144576656e7408045400044900011c2050726f706f73656410011c6163636f756e74000130543a3a4163636f756e74496400013870726f706f73616c5f696e64657810013450726f706f73616c496e64657800013470726f706f73616c5f6861736834011c543a3a486173680001247468726573686f6c6410012c4d656d626572436f756e74000008490141206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e3c604d656d626572436f756e7460292e14566f74656414011c6163636f756e74000130543a3a4163636f756e74496400013470726f706f73616c5f6861736834011c543a3a48617368000114766f746564200110626f6f6c00010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e74000108050141206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e671501612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e20417070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000204c041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2c446973617070726f76656404013470726f706f73616c5f6861736834011c543a3a48617368000304d041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e20457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c74000404210141206d6f74696f6e207761732065786563757465643b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e384d656d626572457865637574656408013470726f706f73616c5f6861736834011c543a3a48617368000118726573756c748001384469737061746368526573756c740005044901412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b20726573756c742077696c6c20626520604f6b602069662069742072657475726e656420776974686f7574206572726f722e18436c6f7365640c013470726f706f73616c5f6861736834011c543a3a4861736800010c79657310012c4d656d626572436f756e740001086e6f10012c4d656d626572436f756e740006045501412070726f706f73616c2077617320636c6f736564206265636175736520697473207468726573686f6c64207761732072656163686564206f7220616674657220697473206475726174696f6e207761732075702e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c80c3870616c6c65745f76657374696e671870616c6c6574144576656e740404540001083856657374696e675570646174656408011c6163636f756e74000130543a3a4163636f756e744964000120756e76657374656418013042616c616e63654f663c543e000008510154686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e6469636174652061206368616e676520696e2066756e647320617661696c61626c652e25015468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e4056657374696e67436f6d706c6574656404011c6163636f756e74000130543a3a4163636f756e7449640001049c416e205c5b6163636f756e745c5d20686173206265636f6d652066756c6c79207665737465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574cc0c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144576656e7404045400011c1c4e65775465726d04012c6e65775f6d656d62657273d001ec5665633c283c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e7449642c2042616c616e63654f663c543e293e000014450141206e6577207465726d2077697468206e65775f6d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e550174686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e65644501666f72207468697320707572706f73652e204120604e65775465726d285c5b5c5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e645501736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f2c626567696e20776974682e24456d7074795465726d00010831014e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6dc8604e65775465726d285c5b5c5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e34456c656374696f6e4572726f72000204e4496e7465726e616c206572726f722068617070656e6564207768696c6520747279696e6720746f20706572666f726d20656c656374696f6e2e304d656d6265724b69636b65640401186d656d6265720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000308410141206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f723060456d7074795465726d602e2452656e6f756e63656404012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400040498536f6d656f6e65206861732072656e6f756e6365642074686569722063616e6469646163792e4043616e646964617465536c617368656408012463616e6469646174650001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0005103901412063616e6469646174652077617320736c617368656420627920616d6f756e742064756520746f206661696c696e6720746f206f627461696e20612073656174206173206d656d626572206f722872756e6e65722d75702e00e44e6f74652074686174206f6c64206d656d6265727320616e642072756e6e6572732d75702061726520616c736f2063616e646964617465732e4453656174486f6c646572536c617368656408012c736561745f686f6c6465720001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000604350141207365617420686f6c6465722077617320736c617368656420627920616d6f756e74206279206265696e6720666f72636566756c6c792072656d6f7665642066726f6d20746865207365742e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d0000002d400d400000408001800d80c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144576656e7404045400011838536f6c7574696f6e53746f7265640c011c636f6d70757465dc013c456c656374696f6e436f6d707574650001186f726967696e8801504f7074696f6e3c543a3a4163636f756e7449643e000130707265765f656a6563746564200110626f6f6c00001cb44120736f6c7574696f6e207761732073746f72656420776974682074686520676976656e20636f6d707574652e00510154686520606f726967696e6020696e6469636174657320746865206f726967696e206f662074686520736f6c7574696f6e2e20496620606f726967696e602069732060536f6d65284163636f756e74496429602c59017468652073746f72656420736f6c7574696f6e20776173207375626d697474656420696e20746865207369676e65642070686173652062792061206d696e657220776974682074686520604163636f756e744964602e25014f74686572776973652c2074686520736f6c7574696f6e207761732073746f7265642065697468657220647572696e672074686520756e7369676e6564207068617365206f722062794d0160543a3a466f7263654f726967696e602e205468652060626f6f6c6020697320607472756560207768656e20612070726576696f757320736f6c7574696f6e2077617320656a656374656420746f206d616b6548726f6f6d20666f722074686973206f6e652e44456c656374696f6e46696e616c697a656408011c636f6d70757465dc013c456c656374696f6e436f6d7075746500011473636f7265e00134456c656374696f6e53636f7265000104190154686520656c656374696f6e20686173206265656e2066696e616c697a65642c20776974682074686520676976656e20636f6d7075746174696f6e20616e642073636f72652e38456c656374696f6e4661696c656400020c4c416e20656c656374696f6e206661696c65642e0001014e6f74206d7563682063616e20626520736169642061626f757420776869636820636f6d7075746573206661696c656420696e207468652070726f636573732e20526577617264656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0003042501416e206163636f756e7420686173206265656e20726577617264656420666f72207468656972207369676e6564207375626d697373696f6e206265696e672066696e616c697a65642e1c536c617368656408011c6163636f756e740001983c54206173206672616d655f73797374656d3a3a436f6e6669673e3a3a4163636f756e74496400011476616c756518013042616c616e63654f663c543e0004042101416e206163636f756e7420686173206265656e20736c617368656420666f72207375626d697474696e6720616e20696e76616c6964207369676e6564207375626d697373696f6e2e4450686173655472616e736974696f6e65640c011066726f6de4016050686173653c426c6f636b4e756d626572466f723c543e3e000108746fe4016050686173653c426c6f636b4e756d626572466f723c543e3e000114726f756e6410010c753332000504b85468657265207761732061207068617365207472616e736974696f6e20696e206120676976656e20726f756e642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574dc089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173653c456c656374696f6e436f6d707574650001141c4f6e436861696e000000185369676e656400010020556e7369676e65640002002046616c6c6261636b00030024456d657267656e637900040000e0084473705f6e706f735f656c656374696f6e7334456c656374696f6e53636f726500000c01346d696e696d616c5f7374616b6518013c457874656e64656442616c616e636500012473756d5f7374616b6518013c457874656e64656442616c616e636500014473756d5f7374616b655f7371756172656418013c457874656e64656442616c616e63650000e4089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651450686173650408426e013001100c4f6666000000185369676e656400010020556e7369676e65640400e8012828626f6f6c2c20426e2900020024456d657267656e637900030000e800000408203000ec103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144576656e740404540001481c457261506169640c01246572615f696e646578100120457261496e64657800014076616c696461746f725f7061796f757418013042616c616e63654f663c543e00012472656d61696e64657218013042616c616e63654f663c543e000008550154686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973c07468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e2052657761726465640c01147374617368000130543a3a4163636f756e74496400011064657374f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000118616d6f756e7418013042616c616e63654f663c543e0001040d01546865206e6f6d696e61746f7220686173206265656e207265776172646564206279207468697320616d6f756e7420746f20746869732064657374696e6174696f6e2e1c536c61736865640801187374616b6572000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0002041d0141207374616b6572202876616c696461746f72206f72206e6f6d696e61746f722920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e34536c6173685265706f727465640c012476616c696461746f72000130543a3a4163636f756e7449640001206672616374696f6ef4011c50657262696c6c000124736c6173685f657261100120457261496e64657800030859014120736c61736820666f722074686520676976656e2076616c696461746f722c20666f722074686520676976656e2070657263656e74616765206f66207468656972207374616b652c2061742074686520676976656e54657261206173206265656e207265706f727465642e684f6c64536c617368696e675265706f727444697363617264656404013473657373696f6e5f696e64657810013053657373696f6e496e6465780004081901416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64446e6f742062652070726f6365737365642e385374616b657273456c65637465640005048441206e657720736574206f66207374616b6572732077617320656c65637465642e18426f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e000610d0416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e205c5b73746173682c20616d6f756e745c5d004d014e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c210169742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e20556e626f6e6465640801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00070490416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e2457697468647261776e0801147374617368000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0008085901416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365606466726f6d2074686520756e6c6f636b696e672071756575652e184b69636b65640801246e6f6d696e61746f72000130543a3a4163636f756e7449640001147374617368000130543a3a4163636f756e744964000904b441206e6f6d696e61746f7220686173206265656e206b69636b65642066726f6d20612076616c696461746f722e545374616b696e67456c656374696f6e4661696c6564000a04ac54686520656c656374696f6e206661696c65642e204e6f206e65772065726120697320706c616e6e65642e1c4368696c6c65640401147374617368000130543a3a4163636f756e744964000b042101416e206163636f756e74206861732073746f707065642070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e345061796f7574537461727465640801246572615f696e646578100120457261496e64657800013c76616c696461746f725f7374617368000130543a3a4163636f756e744964000c0498546865207374616b657273272072657761726473206172652067657474696e6720706169642e4456616c696461746f7250726566735365740801147374617368000130543a3a4163636f756e7449640001147072656673f8013856616c696461746f725072656673000d0498412076616c696461746f72206861732073657420746865697220707265666572656e6365732e68536e617073686f74566f7465727353697a65457863656564656404011073697a6510010c753332000e0468566f746572732073697a65206c696d697420726561636865642e6c536e617073686f745461726765747353697a65457863656564656404011073697a6510010c753332000f046c546172676574732073697a65206c696d697420726561636865642e20466f7263654572610401106d6f64650101011c466f7263696e670010047441206e657720666f72636520657261206d6f646520776173207365742e64436f6e74726f6c6c65724261746368446570726563617465640401206661696c7572657310010c753332001104a45265706f7274206f66206120636f6e74726f6c6c6572206261746368206465707265636174696f6e2e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574f0083870616c6c65745f7374616b696e674452657761726444657374696e6174696f6e04244163636f756e74496401000114185374616b656400000014537461736800010028436f6e74726f6c6c65720002001c4163636f756e7404000001244163636f756e744964000300104e6f6e6500040000f40c3473705f61726974686d65746963287065725f7468696e67731c50657262696c6c0000040010010c7533320000f8083870616c6c65745f7374616b696e673856616c696461746f7250726566730000080128636f6d6d697373696f6efc011c50657262696c6c00011c626c6f636b6564200110626f6f6c0000fc000006f4000101083870616c6c65745f7374616b696e671c466f7263696e67000110284e6f74466f7263696e6700000020466f7263654e657700010024466f7263654e6f6e650002002c466f726365416c776179730003000005010c3870616c6c65745f73657373696f6e1870616c6c6574144576656e74000104284e657753657373696f6e04013473657373696f6e5f696e64657810013053657373696f6e496e64657800000839014e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f74207468659c626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657409010c3c70616c6c65745f74726561737572791870616c6c6574144576656e74080454000449000130205370656e64696e670401406275646765745f72656d61696e696e6718013c42616c616e63654f663c542c20493e000004e45765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e1c417761726465640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000114617761726418013c42616c616e63654f663c542c20493e00011c6163636f756e74000130543a3a4163636f756e7449640001047c536f6d652066756e64732068617665206265656e20616c6c6f63617465642e144275726e7404012c6275726e745f66756e647318013c42616c616e63654f663c542c20493e00020488536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20526f6c6c6f766572040140726f6c6c6f7665725f62616c616e636518013c42616c616e63654f663c542c20493e0003042d015370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e1c4465706f73697404011476616c756518013c42616c616e63654f663c542c20493e0004047c536f6d652066756e64732068617665206265656e206465706f73697465642e345370656e64417070726f7665640c013870726f706f73616c5f696e64657810013450726f706f73616c496e646578000118616d6f756e7418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640005049c41206e6577207370656e642070726f706f73616c20686173206265656e20617070726f7665642e3c55706461746564496e61637469766508012c726561637469766174656418013c42616c616e63654f663c542c20493e00012c646561637469766174656418013c42616c616e63654f663c542c20493e000604cc54686520696e6163746976652066756e6473206f66207468652070616c6c65742068617665206265656e20757064617465642e4841737365745370656e64417070726f766564180114696e6465781001285370656e64496e64657800012861737365745f6b696e64840130543a3a41737365744b696e64000118616d6f756e74180150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000138543a3a42656e656669636961727900012876616c69645f66726f6d300144426c6f636b4e756d626572466f723c543e0001246578706972655f6174300144426c6f636b4e756d626572466f723c543e000704b441206e6577206173736574207370656e642070726f706f73616c20686173206265656e20617070726f7665642e4041737365745370656e64566f69646564040114696e6465781001285370656e64496e64657800080474416e20617070726f766564207370656e642077617320766f696465642e1050616964080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a49640009044c41207061796d656e742068617070656e65642e345061796d656e744661696c6564080114696e6465781001285370656e64496e6465780001287061796d656e745f69648401643c543a3a5061796d6173746572206173205061793e3a3a4964000a049041207061796d656e74206661696c656420616e642063616e20626520726574726965642e385370656e6450726f636573736564040114696e6465781001285370656e64496e646578000b084d0141207370656e64207761732070726f63657373656420616e642072656d6f7665642066726f6d207468652073746f726167652e204974206d696768742068617665206265656e207375636365737366756c6c797070616964206f72206974206d6179206861766520657870697265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65740d010c3c70616c6c65745f626f756e746965731870616c6c6574144576656e7408045400044900012c38426f756e747950726f706f736564040114696e64657810012c426f756e7479496e646578000004504e657720626f756e74792070726f706f73616c2e38426f756e747952656a6563746564080114696e64657810012c426f756e7479496e646578000110626f6e6418013c42616c616e63654f663c542c20493e000104cc4120626f756e74792070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e48426f756e7479426563616d65416374697665040114696e64657810012c426f756e7479496e646578000204b84120626f756e74792070726f706f73616c2069732066756e64656420616e6420626563616d65206163746976652e34426f756e747941776172646564080114696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000304944120626f756e7479206973206177617264656420746f20612062656e65666963696172792e34426f756e7479436c61696d65640c0114696e64657810012c426f756e7479496e6465780001187061796f757418013c42616c616e63654f663c542c20493e00012c62656e6566696369617279000130543a3a4163636f756e7449640004048c4120626f756e747920697320636c61696d65642062792062656e65666963696172792e38426f756e747943616e63656c6564040114696e64657810012c426f756e7479496e646578000504584120626f756e74792069732063616e63656c6c65642e38426f756e7479457874656e646564040114696e64657810012c426f756e7479496e646578000604704120626f756e74792065787069727920697320657874656e6465642e38426f756e7479417070726f766564040114696e64657810012c426f756e7479496e646578000704544120626f756e747920697320617070726f7665642e3c43757261746f7250726f706f736564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000804744120626f756e74792063757261746f722069732070726f706f7365642e4443757261746f72556e61737369676e6564040124626f756e74795f696410012c426f756e7479496e6465780009047c4120626f756e74792063757261746f7220697320756e61737369676e65642e3c43757261746f724163636570746564080124626f756e74795f696410012c426f756e7479496e64657800011c63757261746f72000130543a3a4163636f756e744964000a04744120626f756e74792063757261746f722069732061636365707465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657411010c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144576656e74040454000110144164646564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780000046041206368696c642d626f756e74792069732061646465642e1c417761726465640c0114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e64657800012c62656e6566696369617279000130543a3a4163636f756e744964000104ac41206368696c642d626f756e7479206973206177617264656420746f20612062656e65666963696172792e1c436c61696d6564100114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780001187061796f757418013042616c616e63654f663c543e00012c62656e6566696369617279000130543a3a4163636f756e744964000204a441206368696c642d626f756e747920697320636c61696d65642062792062656e65666963696172792e2043616e63656c6564080114696e64657810012c426f756e7479496e64657800012c6368696c645f696e64657810012c426f756e7479496e6465780003047041206368696c642d626f756e74792069732063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657415010c4070616c6c65745f626167735f6c6973741870616c6c6574144576656e740804540004490001082052656261676765640c010c77686f000130543a3a4163636f756e74496400011066726f6d300120543a3a53636f7265000108746f300120543a3a53636f7265000004a44d6f76656420616e206163636f756e742066726f6d206f6e652062616720746f20616e6f746865722e3053636f72655570646174656408010c77686f000130543a3a4163636f756e7449640001246e65775f73636f7265300120543a3a53636f7265000104d855706461746564207468652073636f7265206f6620736f6d65206163636f756e7420746f2074686520676976656e20616d6f756e742e047c54686520604576656e746020656e756d206f6620746869732070616c6c657419010c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d6265722068617320626563616d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c0646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00210154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e206f66206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f73746174651d010124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104bc436c61696d6564206578636573732066726f7a656e204544206f66206166207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e1d01085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e6700020000210104184f7074696f6e0404540125010108104e6f6e6500000010536f6d65040025010000010000250100000408f400002901085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7350436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d62657200002d0104184f7074696f6e0404540131010108104e6f6e6500000010536f6d650400310100000100003101085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7364436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e7449640001000035010c4070616c6c65745f7363686564756c65721870616c6c6574144576656e74040454000124245363686564756c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c753332000004505363686564756c656420736f6d65207461736b2e2043616e63656c65640801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001044c43616e63656c656420736f6d65207461736b2e28446973706174636865640c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118726573756c748001384469737061746368526573756c74000204544469737061746368656420736f6d65207461736b2e2052657472795365741001107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000118706572696f64300144426c6f636b4e756d626572466f723c543e00011c726574726965730801087538000304a0536574206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e38526574727943616e63656c6c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000404ac43616e63656c206120726574727920636f6e66696775726174696f6e20666f7220736f6d65207461736b2e3c43616c6c556e617661696c61626c650801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e00050429015468652063616c6c20666f72207468652070726f7669646564206861736820776173206e6f7420666f756e6420736f20746865207461736b20686173206265656e2061626f727465642e38506572696f6469634661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0006043d0154686520676976656e207461736b2077617320756e61626c6520746f2062652072656e657765642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b2e2c52657472794661696c65640801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e0007085d0154686520676976656e207461736b2077617320756e61626c6520746f20626520726574726965642073696e636520746865206167656e64612069732066756c6c206174207468617420626c6f636b206f722074686572659c776173206e6f7420656e6f7567682077656967687420746f2072657363686564756c652069742e545065726d616e656e746c794f7665727765696768740801107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00010869643d0101404f7074696f6e3c5461736b4e616d653e000804f054686520676976656e207461736b2063616e206e657665722062652065786563757465642073696e6365206974206973206f7665727765696768742e04304576656e747320747970652e3901000004083010003d0104184f7074696f6e04045401040108104e6f6e6500000010536f6d65040004000001000041010c3c70616c6c65745f707265696d6167651870616c6c6574144576656e7404045400010c144e6f7465640401106861736834011c543a3a48617368000004684120707265696d61676520686173206265656e206e6f7465642e245265717565737465640401106861736834011c543a3a48617368000104784120707265696d61676520686173206265656e207265717565737465642e1c436c65617265640401106861736834011c543a3a486173680002046c4120707265696d616765206861732062656e20636c65617265642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657445010c3c70616c6c65745f6f6666656e6365731870616c6c6574144576656e740001041c4f6666656e63650801106b696e64490101104b696e6400012074696d65736c6f743801384f706171756554696d65536c6f7400000c5101546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e643501286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e4c5c5b6b696e642c2074696d65736c6f745c5d2e04304576656e747320747970652e49010000031000000008004d010c3c70616c6c65745f74785f70617573651870616c6c6574144576656e740404540001082843616c6c50617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000004b8546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f77207061757365642e3043616c6c556e70617573656404012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e000104c0546869732070616c6c65742c206f7220612073706563696669632063616c6c206973206e6f7720756e7061757365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574510100000408550155010055010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000059010c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144576656e7404045400010c444865617274626561745265636569766564040130617574686f726974795f69645d010138543a3a417574686f726974794964000004c041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f726974794964602e1c416c6c476f6f64000104d041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2c536f6d654f66666c696e6504011c6f66666c696e656101016c5665633c4964656e74696669636174696f6e5475706c653c543e3e000204290141742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e047c54686520604576656e746020656e756d206f6620746869732070616c6c65745d01104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139185075626c69630000040004013c737232353531393a3a5075626c696300006101000002650100650100000408006901006901082873705f7374616b696e67204578706f7375726508244163636f756e74496401001c42616c616e63650118000c0114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e00006d01000006180071010000027501007501082873705f7374616b696e6748496e646976696475616c4578706f7375726508244163636f756e74496401001c42616c616e636501180008010c77686f0001244163636f756e74496400011476616c75656d01011c42616c616e6365000079010c3c70616c6c65745f6964656e746974791870616c6c6574144576656e740404540001442c4964656e7469747953657404010c77686f000130543a3a4163636f756e744964000004ec41206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e3c4964656e74697479436c656172656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000104cc41206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e384964656e746974794b696c6c656408010c77686f000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000204c441206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e484a756467656d656e7452657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780003049c41206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e504a756467656d656e74556e72657175657374656408010c77686f000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780004048841206a756467656d656e74207265717565737420776173207265747261637465642e384a756467656d656e74476976656e080118746172676574000130543a3a4163636f756e74496400013c7265676973747261725f696e646578100138526567697374726172496e6465780005049441206a756467656d656e742077617320676976656e2062792061207265676973747261722e38526567697374726172416464656404013c7265676973747261725f696e646578100138526567697374726172496e646578000604584120726567697374726172207761732061646465642e405375624964656e7469747941646465640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000704f441207375622d6964656e746974792077617320616464656420746f20616e206964656e7469747920616e6420746865206465706f73697420706169642e485375624964656e7469747952656d6f7665640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000804090141207375622d6964656e74697479207761732072656d6f7665642066726f6d20616e206964656e7469747920616e6420746865206465706f7369742066726565642e485375624964656e746974795265766f6b65640c010c737562000130543a3a4163636f756e7449640001106d61696e000130543a3a4163636f756e74496400011c6465706f73697418013042616c616e63654f663c543e000908190141207375622d6964656e746974792077617320636c65617265642c20616e642074686520676976656e206465706f7369742072657061747269617465642066726f6d20746865c86d61696e206964656e74697479206163636f756e7420746f20746865207375622d6964656e74697479206163636f756e742e38417574686f726974794164646564040124617574686f72697479000130543a3a4163636f756e744964000a047c4120757365726e616d6520617574686f72697479207761732061646465642e40417574686f7269747952656d6f766564040124617574686f72697479000130543a3a4163636f756e744964000b04844120757365726e616d6520617574686f72697479207761732072656d6f7665642e2c557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000c04744120757365726e616d65207761732073657420666f72206077686f602e38557365726e616d655175657565640c010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e00012865787069726174696f6e300144426c6f636b4e756d626572466f723c543e000d0419014120757365726e616d6520776173207175657565642c20627574206077686f60206d75737420616363657074206974207072696f7220746f206065787069726174696f6e602e48507265617070726f76616c4578706972656404011477686f7365000130543a3a4163636f756e744964000e043901412071756575656420757365726e616d6520706173736564206974732065787069726174696f6e20776974686f7574206265696e6720636c61696d656420616e64207761732072656d6f7665642e485072696d617279557365726e616d6553657408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e000f0401014120757365726e616d6520776173207365742061732061207072696d61727920616e642063616e206265206c6f6f6b65642075702066726f6d206077686f602e5c44616e676c696e67557365726e616d6552656d6f76656408010c77686f000130543a3a4163636f756e744964000120757365726e616d657d01012c557365726e616d653c543e0010085d01412064616e676c696e6720757365726e616d652028617320696e2c206120757365726e616d6520636f72726573706f6e64696e6720746f20616e206163636f756e742074686174206861732072656d6f766564206974736c6964656e746974792920686173206265656e2072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65747d010c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000081010c3870616c6c65745f7574696c6974791870616c6c6574144576656e74000118404261746368496e746572727570746564080114696e64657810010c7533320001146572726f7268013444697370617463684572726f7200000855014261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061734877656c6c20617320746865206572726f722e384261746368436f6d706c65746564000104c84261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e604261746368436f6d706c65746564576974684572726f7273000204b44261746368206f66206469737061746368657320636f6d706c657465642062757420686173206572726f72732e344974656d436f6d706c657465640003041d01412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206e6f206572726f722e284974656d4661696c65640401146572726f7268013444697370617463684572726f720004041101412073696e676c65206974656d2077697468696e2061204261746368206f6620646973706174636865732068617320636f6d706c657465642077697468206572726f722e30446973706174636865644173040118726573756c748001384469737061746368526573756c7400050458412063616c6c2077617320646973706174636865642e047c54686520604576656e746020656e756d206f6620746869732070616c6c657485010c3c70616c6c65745f6d756c74697369671870616c6c6574144576656e740404540001102c4e65774d756c74697369670c0124617070726f76696e67000130543a3a4163636f756e7449640001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c486173680000048c41206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e404d756c7469736967417070726f76616c100124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000104c841206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e404d756c74697369674578656375746564140124617070726f76696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000118726573756c748001384469737061746368526573756c740002049c41206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e444d756c746973696743616e63656c6c656410012863616e63656c6c696e67000130543a3a4163636f756e74496400012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e0001206d756c7469736967000130543a3a4163636f756e74496400012463616c6c5f6861736804012043616c6c48617368000304a041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65748901083c70616c6c65745f6d756c74697369672454696d65706f696e74042c426c6f636b4e756d62657201300008011868656967687430012c426c6f636b4e756d626572000114696e64657810010c75333200008d010c3c70616c6c65745f657468657265756d1870616c6c6574144576656e7400010420457865637574656414011066726f6d9101011048313630000108746f91010110483136300001407472616e73616374696f6e5f686173683401104832353600012c657869745f726561736f6e9901012845786974526561736f6e00012865787472615f6461746138011c5665633c75383e000004c8416e20657468657265756d207472616e73616374696f6e20776173207375636365737366756c6c792065786563757465642e047c54686520604576656e746020656e756d206f6620746869732070616c6c65749101083c7072696d69746976655f7479706573104831363000000400950101205b75383b2032305d0000950100000314000000080099010c2065766d5f636f7265146572726f722845786974526561736f6e0001101c5375636365656404009d01012c4578697453756363656564000000144572726f720400a1010124457869744572726f72000100185265766572740400b10101284578697452657665727400020014466174616c0400b501012445786974466174616c000300009d010c2065766d5f636f7265146572726f722c457869745375636365656400010c1c53746f707065640000002052657475726e656400010020537569636964656400020000a1010c2065766d5f636f7265146572726f7224457869744572726f7200014038537461636b556e646572666c6f7700000034537461636b4f766572666c6f770001002c496e76616c69644a756d7000020030496e76616c696452616e67650003004444657369676e61746564496e76616c69640004002c43616c6c546f6f446565700005003c437265617465436f6c6c6973696f6e0006004c437265617465436f6e74726163744c696d69740007002c496e76616c6964436f64650400a50101184f70636f6465000f002c4f75744f664f6666736574000800204f75744f66476173000900244f75744f6646756e64000a002c5043556e646572666c6f77000b002c437265617465456d707479000c00144f746865720400a9010144436f773c277374617469632c207374723e000d00204d61784e6f6e6365000e0000a5010c2065766d5f636f7265186f70636f6465184f70636f64650000040008010875380000a901040c436f7704045401ad01000400ad01000000ad010000050200b1010c2065766d5f636f7265146572726f72284578697452657665727400010420526576657274656400000000b5010c2065766d5f636f7265146572726f722445786974466174616c000110304e6f74537570706f7274656400000048556e68616e646c6564496e746572727570740001004043616c6c4572726f724173466174616c0400a1010124457869744572726f72000200144f746865720400a9010144436f773c277374617469632c207374723e00030000b9010c2870616c6c65745f65766d1870616c6c6574144576656e740404540001140c4c6f6704010c6c6f67bd01010c4c6f670000047c457468657265756d206576656e74732066726f6d20636f6e7472616374732e1c4372656174656404011c616464726573739101011048313630000104b44120636f6e747261637420686173206265656e206372656174656420617420676976656e20616464726573732e34437265617465644661696c656404011c61646472657373910101104831363000020405014120636f6e74726163742077617320617474656d7074656420746f20626520637265617465642c206275742074686520657865637574696f6e206661696c65642e20457865637574656404011c616464726573739101011048313630000304f84120636f6e747261637420686173206265656e206578656375746564207375636365737366756c6c79207769746820737461746573206170706c6965642e3845786563757465644661696c656404011c61646472657373910101104831363000040465014120636f6e747261637420686173206265656e2065786563757465642077697468206572726f72732e20537461746573206172652072657665727465642077697468206f6e6c79206761732066656573206170706c6965642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574bd010c20657468657265756d0c6c6f670c4c6f6700000c011c616464726573739101011048313630000118746f70696373c10101245665633c483235363e0001106461746138011442797465730000c1010000023400c5010c3c70616c6c65745f626173655f6665651870616c6c6574144576656e7400010c404e65774261736546656550657247617304010c666565c9010110553235360000003c426173654665654f766572666c6f77000100344e6577456c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000200047c54686520604576656e746020656e756d206f6620746869732070616c6c6574c901083c7072696d69746976655f7479706573105532353600000400cd0101205b7536343b20345d0000cd01000003040000003000d1010c3473705f61726974686d65746963287065725f7468696e67731c5065726d696c6c0000040010010c7533320000d5010c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144576656e740404540001041c436c61696d65640c0124726563697069656e74000130543a3a4163636f756e744964000118736f75726365d90101304d756c746941646472657373000118616d6f756e7418013042616c616e63654f663c543e0000048c536f6d656f6e6520636c61696d656420736f6d65206e617469766520746f6b656e732e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574d9010c5470616c6c65745f61697264726f705f636c61696d73147574696c73304d756c7469416464726573730001080c45564d0400dd01013c457468657265756d41646472657373000000184e6174697665040000012c4163636f756e744964333200010000dd01105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733c457468657265756d4164647265737300000400950101205b75383b2032305d0000e1010c3070616c6c65745f70726f78791870616c6c6574144576656e740404540001143450726f78794578656375746564040118726573756c748001384469737061746368526573756c74000004bc412070726f78792077617320657865637574656420636f72726563746c792c20776974682074686520676976656e2e2c507572654372656174656410011070757265000130543a3a4163636f756e74496400010c77686f000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f787954797065000150646973616d626967756174696f6e5f696e646578e901010c753136000108dc412070757265206163636f756e7420686173206265656e2063726561746564206279206e65772070726f7879207769746820676976656e90646973616d626967756174696f6e20696e64657820616e642070726f787920747970652e24416e6e6f756e6365640c01107265616c000130543a3a4163636f756e74496400011470726f7879000130543a3a4163636f756e74496400012463616c6c5f6861736834013443616c6c486173684f663c543e000204e0416e20616e6e6f756e63656d656e742077617320706c6163656420746f206d616b6520612063616c6c20696e20746865206675747572652e2850726f7879416464656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00030448412070726f7879207761732061646465642e3050726f787952656d6f76656410012464656c656761746f72000130543a3a4163636f756e74496400012464656c656761746565000130543a3a4163636f756e74496400012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00040450412070726f7879207761732072656d6f7665642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574e501085874616e676c655f746573746e65745f72756e74696d652450726f7879547970650001100c416e790000002c4e6f6e5472616e7366657200010028476f7665726e616e63650002001c5374616b696e6700030000e9010000050400ed010c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144576656e74040454000154384f70657261746f724a6f696e656404010c77686f000130543a3a4163636f756e7449640000045c416e206f70657261746f7220686173206a6f696e65642e604f70657261746f724c656176696e675363686564756c656404010c77686f000130543a3a4163636f756e7449640001048c416e206f70657261746f7220686173207363686564756c656420746f206c656176652e584f70657261746f724c6561766543616e63656c6c656404010c77686f000130543a3a4163636f756e744964000204b8416e206f70657261746f72206861732063616e63656c6c6564207468656972206c6561766520726571756573742e544f70657261746f724c65617665457865637574656404010c77686f000130543a3a4163636f756e744964000304b4416e206f70657261746f7220686173206578656375746564207468656972206c6561766520726571756573742e404f70657261746f72426f6e644d6f726508010c77686f000130543a3a4163636f756e74496400013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00040498416e206f70657261746f722068617320696e63726561736564207468656972207374616b652e644f70657261746f72426f6e644c6573735363686564756c656408010c77686f000130543a3a4163636f756e744964000138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000504c8416e206f70657261746f7220686173207363686564756c656420746f206465637265617365207468656972207374616b652e604f70657261746f72426f6e644c657373457865637574656404010c77686f000130543a3a4163636f756e744964000604b8416e206f70657261746f7220686173206578656375746564207468656972207374616b652064656372656173652e644f70657261746f72426f6e644c65737343616e63656c6c656404010c77686f000130543a3a4163636f756e744964000704dc416e206f70657261746f72206861732063616e63656c6c6564207468656972207374616b6520646563726561736520726571756573742e4c4f70657261746f7257656e744f66666c696e6504010c77686f000130543a3a4163636f756e74496400080474416e206f70657261746f722068617320676f6e65206f66666c696e652e484f70657261746f7257656e744f6e6c696e6504010c77686f000130543a3a4163636f756e74496400090470416e206f70657261746f722068617320676f6e65206f6e6c696e652e244465706f73697465640c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000a046041206465706f73697420686173206265656e206d6164652e445363686564756c656477697468647261770c010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000b047c416e20776974686472617720686173206265656e207363686564756c65642e404578656375746564776974686472617704010c77686f000130543a3a4163636f756e744964000c0478416e20776974686472617720686173206265656e2065786563757465642e4443616e63656c6c6564776974686472617704010c77686f000130543a3a4163636f756e744964000d047c416e20776974686472617720686173206265656e2063616e63656c6c65642e2444656c65676174656410010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000e046c412064656c65676174696f6e20686173206265656e206d6164652e685363686564756c656444656c656761746f72426f6e644c65737310010c77686f000130543a3a4163636f756e7449640001206f70657261746f72000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e00012061737365745f6964f101014441737365743c543a3a417373657449643e000f04bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e207363686564756c65642e64457865637574656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001004b8412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2065786563757465642e6843616e63656c6c656444656c656761746f72426f6e644c65737304010c77686f000130543a3a4163636f756e744964001104bc412064656c656761746f7220756e7374616b65207265717565737420686173206265656e2063616e63656c6c65642e3c4f70657261746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e001204644f70657261746f7220686173206265656e20736c61736865644044656c656761746f72536c617368656408010c77686f000130543a3a4163636f756e744964000118616d6f756e7418013042616c616e63654f663c543e0013046844656c656761746f7220686173206265656e20736c61736865642c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e0014049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e04744576656e747320656d6974746564206279207468652070616c6c65742ef1010c4474616e676c655f7072696d697469766573207365727669636573144173736574041c417373657449640118010818437573746f6d040018011c4173736574496400000014457263323004009101013473705f636f72653a3a4831363000010000f5010c3c70616c6c65745f7365727669636573186d6f64756c65144576656e7404045400014040426c75657072696e74437265617465640801146f776e6572000130543a3a4163636f756e74496404bc546865206163636f756e742074686174206372656174656420746865207365727669636520626c75657072696e742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0004a441206e6577207365727669636520626c75657072696e7420686173206265656e20637265617465642e3c507265526567697374726174696f6e0801206f70657261746f72000130543a3a4163636f756e74496404bc546865206163636f756e742074686174207072652d7265676973746572656420617320616e206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e0104dc416e206f70657261746f7220686173207072652d7265676973746572656420666f722061207365727669636520626c75657072696e742e285265676973746572656410012070726f7669646572000130543a3a4163636f756e74496404a8546865206163636f756e74207468617420726567697374657265642061732061206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e012c707265666572656e636573f901014c4f70657261746f72507265666572656e63657304f454686520707265666572656e63657320666f7220746865206f70657261746f7220666f72207468697320737065636966696320626c75657072696e742e0144726567697374726174696f6e5f61726773050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e049054686520617267756d656e7473207573656420666f7220726567697374726174696f6e2e020490416e206e6577206f70657261746f7220686173206265656e20726567697374657265642e30556e726567697374657265640801206f70657261746f72000130543a3a4163636f756e74496404b4546865206163636f756e74207468617420756e7265676973746572656420617320616d206f70657261746f722e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e030488416e206f70657261746f7220686173206265656e20756e726567697374657265642e4c507269636554617267657473557064617465640c01206f70657261746f72000130543a3a4163636f756e74496404c4546865206163636f756e74207468617420757064617465642074686520617070726f76616c20707265666572656e63652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e013470726963655f74617267657473010201305072696365546172676574730458546865206e657720707269636520746172676574732e0404cc546865207072696365207461726765747320666f7220616e206f70657261746f7220686173206265656e20757064617465642e40536572766963655265717565737465641801146f776e6572000130543a3a4163636f756e744964049c546865206163636f756e742074686174207265717565737465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c73350201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f766564350201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e01186173736574733902013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e05048441206e6577207365727669636520686173206265656e207265717565737465642e585365727669636552657175657374417070726f7665641401206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e74207468617420617070726f7665642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e014470656e64696e675f617070726f76616c73350201445665633c543a3a4163636f756e7449643e04dc546865206c697374206f66206f70657261746f72732074686174206e65656420746f20617070726f76652074686520736572766963652e0120617070726f766564350201445665633c543a3a4163636f756e7449643e04f0546865206c697374206f66206f70657261746f727320746861742061746f6d61746963616c7920617070726f7665642074686520736572766963652e060490412073657276696365207265717565737420686173206265656e20617070726f7665642e58536572766963655265717565737452656a65637465640c01206f70657261746f72000130543a3a4163636f756e7449640498546865206163636f756e7420746861742072656a65637465642074686520736572766963652e0128726571756573745f696430010c7536340478546865204944206f6620746865207365727669636520726571756573742e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e070490412073657276696365207265717565737420686173206265656e2072656a65637465642e4053657276696365496e697469617465641401146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128726571756573745f696430010c75363404c0546865204944206f662074686520736572766963652072657175657374207468617420676f7420617070726f7665642e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e01186173736574733902013c5665633c543a3a417373657449643e040101546865206c697374206f6620617373657420494473207468617420617265206265696e67207573656420746f207365637572652074686520736572766963652e08047441207365727669636520686173206265656e20696e697469617465642e44536572766963655465726d696e617465640c01146f776e6572000130543a3a4163636f756e7449640464546865206f776e6572206f662074686520736572766963652e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e0130626c75657072696e745f696430010c7536340480546865204944206f6620746865207365727669636520626c75657072696e742e09047841207365727669636520686173206265656e207465726d696e617465642e244a6f6243616c6c656414011863616c6c6572000130543a3a4163636f756e7449640480546865206163636f756e7420746861742063616c6c656420746865206a6f622e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e011061726773050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e046454686520617267756d656e7473206f6620746865206a6f622e0a045841206a6f6220686173206265656e2063616c6c65642e484a6f62526573756c745375626d69747465641401206f70657261746f72000130543a3a4163636f756e74496404a8546865206163636f756e742074686174207375626d697474656420746865206a6f6220726573756c742e0128736572766963655f696430010c7536340458546865204944206f662074686520736572766963652e011c63616c6c5f696430010c753634044c546865204944206f66207468652063616c6c2e010c6a6f620801087538045454686520696e646578206f6620746865206a6f622e0118726573756c74050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e045854686520726573756c74206f6620746865206a6f622e0b048041206a6f6220726573756c7420686173206265656e207375626d69747465642e2c45766d526576657274656410011066726f6d9101011048313630000108746f91010110483136300001106461746138011c5665633c75383e000118726561736f6e38011c5665633c75383e000c049445564d20657865637574696f6e2072657665727465642077697468206120726561736f6e2e38556e6170706c696564536c617368180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780d048c416e204f70657261746f722068617320616e20756e6170706c69656420736c6173682e38536c617368446973636172646564180114696e64657810010c753332045c54686520696e646578206f662074686520736c6173682e01206f70657261746f72000130543a3a4163636f756e74496404a0546865206163636f756e7420746861742068617320616e20756e6170706c69656420736c6173682e0118616d6f756e7418013042616c616e63654f663c543e046054686520616d6f756e74206f662074686520736c6173682e0128736572766963655f696430010c7536340428536572766963652049440130626c75657072696e745f696430010c7536340430426c75657072696e74204944010c65726110010c753332042445726120696e6465780e0484416e20556e6170706c69656420536c61736820676f74206469736361726465642e904d6173746572426c75657072696e74536572766963654d616e61676572526576697365640801207265766973696f6e10010c75333204f0546865207265766973696f6e206e756d626572206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e011c61646472657373910101104831363004d05468652061646472657373206f6620746865204d617374657220426c75657072696e742053657276696365204d616e616765722e0f04d8546865204d617374657220426c75657072696e742053657276696365204d616e6167657220686173206265656e20726576697365642e047c54686520604576656e746020656e756d206f6620746869732070616c6c6574f9010c4474616e676c655f7072696d6974697665732073657276696365734c4f70657261746f72507265666572656e636573000008010c6b6579fd0101205b75383b2036355d00013470726963655f74617267657473010201305072696365546172676574730000fd0100000341000000080001020c4474616e676c655f7072696d69746976657320736572766963657330507269636554617267657473000014010c63707530010c75363400010c6d656d30010c75363400012c73746f726167655f68646430010c75363400012c73746f726167655f73736430010c75363400013073746f726167655f6e766d6530010c753634000005020000020902000902104474616e676c655f7072696d697469766573207365727669636573146669656c64144669656c6408044300244163636f756e74496401000140104e6f6e6500000010426f6f6c0400200110626f6f6c0001001455696e74380400080108753800020010496e743804000d02010869380003001855696e7431360400e901010c75313600040014496e74313604001102010c6931360005001855696e743332040010010c75333200060014496e74333204001502010c6933320007001855696e743634040030010c75363400080014496e74363404001902010c69363400090018537472696e6704001d02017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e000a00144279746573040021020180426f756e6465645665633c75382c20433a3a4d61784669656c647353697a653e000b001441727261790400250201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000c00104c6973740400250201c4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c647353697a653e000d001853747275637408001d02017c426f756e646564537472696e673c433a3a4d61784669656c647353697a653e00002902016d01426f756e6465645665633c0a28426f756e646564537472696e673c433a3a4d61784669656c647353697a653e2c20426f783c4669656c643c432c204163636f756e7449643e3e292c20433a3a0a4d61784669656c647353697a653e000e00244163636f756e74496404000001244163636f756e744964006400000d02000005090011020000050a0015020000050b0019020000050c001d02104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040021020144426f756e6465645665633c75382c20533e000021020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000025020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010902045300000400050201185665633c543e000029020c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454012d02045300000400310201185665633c543e00002d02000004081d0209020031020000022d020035020000020000390200000218003d020c4470616c6c65745f74616e676c655f6c73741870616c6c6574144576656e740404540001481c437265617465640801246465706f7369746f72000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000004604120706f6f6c20686173206265656e20637265617465642e18426f6e6465641001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c4964000118626f6e64656418013042616c616e63654f663c543e0001186a6f696e6564200110626f6f6c0001049441206d656d62657220686173206265636f6d6520626f6e64656420696e206120706f6f6c2e1c506169644f75740c01186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c49640001187061796f757418013042616c616e63654f663c543e0002048c41207061796f757420686173206265656e206d61646520746f2061206d656d6265722e20556e626f6e6465641401186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e00010c657261100120457261496e64657800032c9841206d656d6265722068617320756e626f6e6465642066726f6d20746865697220706f6f6c2e0039012d206062616c616e6365602069732074686520636f72726573706f6e64696e672062616c616e6365206f6620746865206e756d626572206f6620706f696e7473207468617420686173206265656e5501202072657175657374656420746f20626520756e626f6e646564202874686520617267756d656e74206f66207468652060756e626f6e6460207472616e73616374696f6e292066726f6d2074686520626f6e6465641c2020706f6f6c2e45012d2060706f696e74736020697320746865206e756d626572206f6620706f696e747320746861742061726520697373756564206173206120726573756c74206f66206062616c616e636560206265696e67c82020646973736f6c76656420696e746f2074686520636f72726573706f6e64696e6720756e626f6e64696e6720706f6f6c2ee42d206065726160206973207468652065726120696e207768696368207468652062616c616e63652077696c6c20626520756e626f6e6465642e5501496e2074686520616273656e6365206f6620736c617368696e672c2074686573652076616c7565732077696c6c206d617463682e20496e207468652070726573656e6365206f6620736c617368696e672c207468654d016e756d626572206f6620706f696e74732074686174206172652069737375656420696e2074686520756e626f6e64696e6720706f6f6c2077696c6c206265206c657373207468616e2074686520616d6f756e746472657175657374656420746f20626520756e626f6e6465642e2457697468647261776e1001186d656d626572000130543a3a4163636f756e74496400011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e000118706f696e747318013042616c616e63654f663c543e0004189c41206d656d626572206861732077697468647261776e2066726f6d20746865697220706f6f6c2e00250154686520676976656e206e756d626572206f662060706f696e7473602068617665206265656e20646973736f6c76656420696e2072657475726e20666f72206062616c616e6365602e00590153696d696c617220746f2060556e626f6e64656460206576656e742c20696e2074686520616273656e6365206f6620736c617368696e672c2074686520726174696f206f6620706f696e7420746f2062616c616e63652877696c6c20626520312e2444657374726f79656404011c706f6f6c5f6964100118506f6f6c4964000504684120706f6f6c20686173206265656e2064657374726f7965642e3053746174654368616e67656408011c706f6f6c5f6964100118506f6f6c49640001246e65775f737461746541020124506f6f6c53746174650006047c546865207374617465206f66206120706f6f6c20686173206368616e676564344d656d62657252656d6f76656408011c706f6f6c5f6964100118506f6f6c49640001186d656d626572000130543a3a4163636f756e74496400070c9841206d656d62657220686173206265656e2072656d6f7665642066726f6d206120706f6f6c2e0051015468652072656d6f76616c2063616e20626520766f6c756e74617279202877697468647261776e20616c6c20756e626f6e6465642066756e647329206f7220696e766f6c756e7461727920286b69636b6564292e30526f6c6573557064617465640c0110726f6f748801504f7074696f6e3c543a3a4163636f756e7449643e00011c626f756e6365728801504f7074696f6e3c543a3a4163636f756e7449643e0001246e6f6d696e61746f728801504f7074696f6e3c543a3a4163636f756e7449643e000808550154686520726f6c6573206f66206120706f6f6c2068617665206265656e207570646174656420746f2074686520676976656e206e657720726f6c65732e204e6f7465207468617420746865206465706f7369746f724463616e206e65766572206368616e67652e2c506f6f6c536c617368656408011c706f6f6c5f6964100118506f6f6c496400011c62616c616e636518013042616c616e63654f663c543e0009040d01546865206163746976652062616c616e6365206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e50556e626f6e64696e67506f6f6c536c61736865640c011c706f6f6c5f6964100118506f6f6c496400010c657261100120457261496e64657800011c62616c616e636518013042616c616e63654f663c543e000a04250154686520756e626f6e6420706f6f6c206174206065726160206f6620706f6f6c2060706f6f6c5f69646020686173206265656e20736c617368656420746f206062616c616e6365602e54506f6f6c436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c496400011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e000b04b44120706f6f6c277320636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e60506f6f6c4d6178436f6d6d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c000c04d44120706f6f6c2773206d6178696d756d20636f6d6d697373696f6e2073657474696e6720686173206265656e206368616e6765642e7c506f6f6c436f6d6d697373696f6e4368616e6765526174655570646174656408011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654502019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e000d04cc4120706f6f6c277320636f6d6d697373696f6e20606368616e67655f726174656020686173206265656e206368616e6765642e90506f6f6c436f6d6d697373696f6e436c61696d5065726d697373696f6e5570646174656408011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e490201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e000e04c8506f6f6c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20686173206265656e20757064617465642e54506f6f6c436f6d6d697373696f6e436c61696d656408011c706f6f6c5f6964100118506f6f6c4964000128636f6d6d697373696f6e18013042616c616e63654f663c543e000f0484506f6f6c20636f6d6d697373696f6e20686173206265656e20636c61696d65642e644d696e42616c616e63654465666963697441646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001004c8546f70706564207570206465666963697420696e2066726f7a656e204544206f66207468652072657761726420706f6f6c2e604d696e42616c616e636545786365737341646a757374656408011c706f6f6c5f6964100118506f6f6c4964000118616d6f756e7418013042616c616e63654f663c543e001104b0436c61696d6564206578636573732066726f7a656e204544206f66207468652072657761726420706f6f6c2e04584576656e7473206f6620746869732070616c6c65742e4102104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c537461746500010c104f70656e0000001c426c6f636b65640001002844657374726f79696e67000200004502104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e50436f6d6d697373696f6e4368616e676552617465042c426c6f636b4e756d6265720130000801306d61785f696e637265617365f4011c50657262696c6c0001246d696e5f64656c617930012c426c6f636b4e756d6265720000490204184f7074696f6e040454014d020108104e6f6e6500000010536f6d6504004d0200000100004d02104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e64436f6d6d697373696f6e436c61696d5065726d697373696f6e04244163636f756e74496401000108385065726d697373696f6e6c6573730000001c4163636f756e7404000001244163636f756e7449640001000051020c3870616c6c65745f726577617264731870616c6c6574144576656e740404540001143852657761726473436c61696d65640c011c6163636f756e74000130543a3a4163636f756e7449640001146173736574f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e0000049c526577617264732068617665206265656e20636c61696d656420627920616e206163636f756e7454496e63656e74697665415059416e644361705365740c01207661756c745f6964100128543a3a5661756c74496400010c6170795502014c73705f72756e74696d653a3a50657263656e7400010c63617018013042616c616e63654f663c543e00010419014576656e7420656d6974746564207768656e20616e20696e63656e746976652041505920616e6420636170206172652073657420666f72206120726577617264207661756c7450426c75657072696e7457686974656c6973746564040130626c75657072696e745f696430012c426c75657072696e744964000204e44576656e7420656d6974746564207768656e206120626c75657072696e742069732077686974656c697374656420666f7220726577617264734c417373657455706461746564496e5661756c740c01207661756c745f6964100128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6e5902012c4173736574416374696f6e00030498417373657420686173206265656e207570646174656420746f20726577617264207661756c74605661756c74526577617264436f6e666967557064617465640401207661756c745f6964100128543a3a5661756c744964000400047c54686520604576656e746020656e756d206f6620746869732070616c6c657455020c3473705f61726974686d65746963287065725f7468696e67731c50657263656e74000004000801087538000059020c3870616c6c65745f726577617264731474797065732c4173736574416374696f6e0001080c4164640000001852656d6f7665000100005d0208306672616d655f73797374656d14506861736500010c384170706c7945787472696e736963040010010c7533320000003046696e616c697a6174696f6e00010038496e697469616c697a6174696f6e000200006102000002390100650208306672616d655f73797374656d584c61737452756e74696d6555706772616465496e666f0000080130737065635f76657273696f6e6902014c636f6465633a3a436f6d706163743c7533323e000124737065635f6e616d65ad01016473705f72756e74696d653a3a52756e74696d65537472696e670000690200000610006d0208306672616d655f73797374656d60436f646555706772616465417574686f72697a6174696f6e0404540000080124636f64655f6861736834011c543a3a48617368000134636865636b5f76657273696f6e200110626f6f6c000071020c306672616d655f73797374656d1870616c6c65741043616c6c04045400012c1872656d61726b04011872656d61726b38011c5665633c75383e00000c684d616b6520736f6d65206f6e2d636861696e2072656d61726b2e008843616e20626520657865637574656420627920657665727920606f726967696e602e387365745f686561705f7061676573040114706167657330010c753634000104f853657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e207365745f636f6465040110636f646538011c5665633c75383e0002046453657420746865206e65772072756e74696d6520636f64652e5c7365745f636f64655f776974686f75745f636865636b73040110636f646538011c5665633c75383e000310190153657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e0051014e6f746520746861742072756e74696d652075706772616465732077696c6c206e6f742072756e20696620746869732069732063616c6c656420776974682061206e6f742d696e6372656173696e6720737065632076657273696f6e212c7365745f73746f726167650401146974656d73750201345665633c4b657956616c75653e0004046853657420736f6d65206974656d73206f662073746f726167652e306b696c6c5f73746f726167650401106b6579737d0201205665633c4b65793e000504744b696c6c20736f6d65206974656d732066726f6d2073746f726167652e2c6b696c6c5f70726566697808011870726566697838010c4b657900011c7375626b65797310010c75333200061011014b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e0039012a2a4e4f54453a2a2a2057652072656c79206f6e2074686520526f6f74206f726967696e20746f2070726f7669646520757320746865206e756d626572206f66207375626b65797320756e6465723d0174686520707265666978207765206172652072656d6f76696e6720746f2061636375726174656c792063616c63756c6174652074686520776569676874206f6620746869732066756e6374696f6e2e4472656d61726b5f776974685f6576656e7404011872656d61726b38011c5665633c75383e000704a44d616b6520736f6d65206f6e2d636861696e2072656d61726b20616e6420656d6974206576656e742e44617574686f72697a655f75706772616465040124636f64655f6861736834011c543a3a486173680009106101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e80617574686f72697a655f757067726164655f776974686f75745f636865636b73040124636f64655f6861736834011c543a3a48617368000a206101417574686f72697a6520616e207570677261646520746f206120676976656e2060636f64655f686173686020666f72207468652072756e74696d652e205468652072756e74696d652063616e20626520737570706c696564186c617465722e005d015741524e494e473a205468697320617574686f72697a657320616e207570677261646520746861742077696c6c2074616b6520706c61636520776974686f757420616e792073616665747920636865636b732c20666f7259016578616d706c652074686174207468652073706563206e616d652072656d61696e73207468652073616d6520616e642074686174207468652076657273696f6e206e756d62657220696e637265617365732e204e6f74f07265636f6d6d656e64656420666f72206e6f726d616c207573652e205573652060617574686f72697a655f757067726164656020696e73746561642e007c546869732063616c6c20726571756972657320526f6f74206f726967696e2e606170706c795f617574686f72697a65645f75706772616465040110636f646538011c5665633c75383e000b24550150726f766964652074686520707265696d616765202872756e74696d652062696e617279292060636f64656020666f7220616e2075706772616465207468617420686173206265656e20617574686f72697a65642e00490149662074686520617574686f72697a6174696f6e20726571756972656420612076657273696f6e20636865636b2c20746869732063616c6c2077696c6c20656e73757265207468652073706563206e616d65e872656d61696e7320756e6368616e67656420616e6420746861742074686520737065632076657273696f6e2068617320696e637265617365642e005901446570656e64696e67206f6e207468652072756e74696d65277320604f6e536574436f64656020636f6e66696775726174696f6e2c20746869732066756e6374696f6e206d6179206469726563746c79206170706c791101746865206e65772060636f64656020696e207468652073616d6520626c6f636b206f7220617474656d707420746f207363686564756c652074686520757067726164652e0060416c6c206f726967696e732061726520616c6c6f7765642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e75020000027902007902000004083838007d02000002380081020c306672616d655f73797374656d186c696d69747330426c6f636b5765696768747300000c0128626173655f626c6f636b2801185765696768740001246d61785f626c6f636b2801185765696768740001247065725f636c617373850201845065724469737061746368436c6173733c57656967687473506572436c6173733e000085020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c617373040454018902000c01186e6f726d616c890201045400012c6f7065726174696f6e616c89020104540001246d616e6461746f72798902010454000089020c306672616d655f73797374656d186c696d6974733c57656967687473506572436c6173730000100138626173655f65787472696e7369632801185765696768740001346d61785f65787472696e7369638d0201384f7074696f6e3c5765696768743e0001246d61785f746f74616c8d0201384f7074696f6e3c5765696768743e00012072657365727665648d0201384f7074696f6e3c5765696768743e00008d0204184f7074696f6e04045401280108104e6f6e6500000010536f6d65040028000001000091020c306672616d655f73797374656d186c696d6974732c426c6f636b4c656e677468000004010c6d6178950201545065724469737061746368436c6173733c7533323e000095020c346672616d655f737570706f7274206469737061746368405065724469737061746368436c6173730404540110000c01186e6f726d616c1001045400012c6f7065726174696f6e616c100104540001246d616e6461746f72791001045400009902082873705f776569676874733c52756e74696d65446257656967687400000801107265616430010c753634000114777269746530010c75363400009d02082873705f76657273696f6e3852756e74696d6556657273696f6e0000200124737065635f6e616d65ad01013452756e74696d65537472696e67000124696d706c5f6e616d65ad01013452756e74696d65537472696e67000144617574686f72696e675f76657273696f6e10010c753332000130737065635f76657273696f6e10010c753332000130696d706c5f76657273696f6e10010c75333200011061706973a102011c4170697356656300014c7472616e73616374696f6e5f76657273696f6e10010c75333200013473746174655f76657273696f6e08010875380000a102040c436f7704045401a502000400a502000000a502000002a90200a90200000408ad021000ad02000003080000000800b1020c306672616d655f73797374656d1870616c6c6574144572726f720404540001243c496e76616c6964537065634e616d650000081101546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e685370656356657273696f6e4e65656473546f496e63726561736500010841015468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6550616e6420746865206e65772072756e74696d652e744661696c6564546f4578747261637452756e74696d6556657273696f6e00020cec4661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e0009014569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e4c4e6f6e44656661756c74436f6d706f73697465000304fc537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e3c4e6f6e5a65726f526566436f756e74000404350154686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e3043616c6c46696c7465726564000504d0546865206f726967696e2066696c7465722070726576656e74207468652063616c6c20746f20626520646973706174636865642e6c4d756c7469426c6f636b4d6967726174696f6e734f6e676f696e67000604550141206d756c74692d626c6f636b206d6967726174696f6e206973206f6e676f696e6720616e642070726576656e7473207468652063757272656e7420636f64652066726f6d206265696e67207265706c616365642e444e6f7468696e67417574686f72697a6564000704584e6f207570677261646520617574686f72697a65642e30556e617574686f72697a656400080494546865207375626d697474656420636f6465206973206e6f7420617574686f72697a65642e046c4572726f7220666f72207468652053797374656d2070616c6c6574b5020c4070616c6c65745f74696d657374616d701870616c6c65741043616c6c0404540001040c73657404010c6e6f772c0124543a3a4d6f6d656e7400004c54536574207468652063757272656e742074696d652e005501546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6ed470686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e0041015468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e7420737065636966696564206279685b60436f6e6669673a3a4d696e696d756d506572696f64605d2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0051015468697320646973706174636820636c617373206973205f4d616e6461746f72795f20746f20656e73757265206974206765747320657865637574656420696e2074686520626c6f636b2e204265206177617265510174686174206368616e67696e672074686520636f6d706c6578697479206f6620746869732063616c6c20636f756c6420726573756c742065786861757374696e6720746865207265736f757263657320696e206184626c6f636b20746f206578656375746520616e79206f746865722063616c6c732e0034232320436f6d706c657869747931012d20604f2831296020284e6f7465207468617420696d706c656d656e746174696f6e73206f6620604f6e54696d657374616d7053657460206d75737420616c736f20626520604f283129602955012d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f283129602062656361757365206f6620604469645570646174653a3a74616b656020696e402020606f6e5f66696e616c697a656029d42d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f736574602e204d75737420626520604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb9020c2c70616c6c65745f7375646f1870616c6c65741043616c6c040454000114107375646f04011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000004350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e547375646f5f756e636865636b65645f77656967687408011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000114350141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e2d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b05375646f207573657220746f20737065636966792074686520776569676874206f66207468652063616c6c2e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e1c7365745f6b657904010c6e6577c50201504163636f756e7449644c6f6f6b75704f663c543e0002085d0141757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f106b65792e1c7375646f5f617308010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0003104d0141757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d406120676976656e206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2872656d6f76655f6b657900040c845065726d616e656e746c792072656d6f76657320746865207375646f206b65792e006c2a2a546869732063616e6e6f7420626520756e2d646f6e652e2a2a040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ebd02085874616e676c655f746573746e65745f72756e74696d652c52756e74696d6543616c6c0001981853797374656d0400710201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53797374656d2c2052756e74696d653e0001002454696d657374616d700400b50201b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54696d657374616d702c2052756e74696d653e000200105375646f0400b90201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5375646f2c2052756e74696d653e000300184173736574730400c10201ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4173736574732c2052756e74696d653e0005002042616c616e6365730400c90201b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c42616c616e6365732c2052756e74696d653e00060010426162650400d10201a50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426162652c2052756e74696d653e0009001c4772616e6470610400f50201b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4772616e6470612c2052756e74696d653e000a001c496e64696365730400250301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496e64696365732c2052756e74696d653e000b002444656d6f63726163790400290301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44656d6f63726163792c2052756e74696d653e000c001c436f756e63696c0400450301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436f756e63696c2c2052756e74696d653e000d001c56657374696e670400490301b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c56657374696e672c2052756e74696d653e000e0024456c656374696f6e730400510301b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e732c2052756e74696d653e000f0068456c656374696f6e50726f76696465724d756c746950686173650400590301fd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c456c656374696f6e50726f76696465724d756c746950686173652c2052756e74696d653e0010001c5374616b696e670400410401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5374616b696e672c2052756e74696d653e0011001c53657373696f6e0400750401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657373696f6e2c2052756e74696d653e00120020547265617375727904007d0401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c54726561737572792c2052756e74696d653e00140020426f756e746965730400850401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426f756e746965732c2052756e74696d653e001500344368696c64426f756e746965730400890401c90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4368696c64426f756e746965732c2052756e74696d653e00160020426167734c69737404008d0401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426167734c6973742c2052756e74696d653e0017003c4e6f6d696e6174696f6e506f6f6c730400910401d10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4e6f6d696e6174696f6e506f6f6c732c2052756e74696d653e001800245363686564756c65720400ad0401b90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5363686564756c65722c2052756e74696d653e00190020507265696d6167650400b50401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c507265696d6167652c2052756e74696d653e001a001c547850617573650400b90401b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c547850617573652c2052756e74696d653e001c0020496d4f6e6c696e650400bd0401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c496d4f6e6c696e652c2052756e74696d653e001d00204964656e746974790400c90401b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4964656e746974792c2052756e74696d653e001e001c5574696c6974790400690501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c5574696c6974792c2052756e74696d653e001f00204d756c74697369670400810501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c74697369672c2052756e74696d653e00200020457468657265756d0400890501b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c457468657265756d2c2052756e74696d653e0021000c45564d0400b10501a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c45564d2c2052756e74696d653e0022002844796e616d69634665650400c10501bd0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c44796e616d69634665652c2052756e74696d653e0024001c426173654665650400c50501b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c426173654665652c2052756e74696d653e00250044486f7466697853756666696369656e74730400c90501d90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c486f7466697853756666696369656e74732c2052756e74696d653e00260018436c61696d730400d10501ad0173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c436c61696d732c2052756e74696d653e0027001450726f78790400fd0501a90173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c50726f78792c2052756e74696d653e002c00504d756c7469417373657444656c65676174696f6e0400050601e50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4d756c7469417373657444656c65676174696f6e2c2052756e74696d653e002d002053657276696365730400250601b50173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c53657276696365732c2052756e74696d653e0033000c4c73740400f50601a10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c4c73742c2052756e74696d653e0034001c5265776172647304001d0701b10173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a64697370617463680a3a3a43616c6c61626c6543616c6c466f723c526577617264732c2052756e74696d653e00350000c1020c3470616c6c65745f6173736574731870616c6c65741043616c6c080454000449000180186372656174650c010869646d01014c543a3a41737365744964506172616d6574657200011461646d696ec50201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e6365180128543a3a42616c616e636500004ce849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d2061207075626c6963206f726967696e2e00250154686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c7920616e6420697473206f776e657220697320746865206f726967696e2e006101546865206f726967696e206d75737420636f6e666f726d20746f2074686520636f6e6669677572656420604372656174654f726967696e6020616e6420686176652073756666696369656e742066756e647320667265652e00bc46756e6473206f662073656e64657220617265207265736572766564206279206041737365744465706f736974602e002c506172616d65746572733a59012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d206061646d696e603a205468652061646d696e206f66207468697320636c617373206f66206173736574732e205468652061646d696e2069732074686520696e697469616c2061646472657373206f6620656163689c6d656d626572206f662074686520617373657420636c61737327732061646d696e207465616d2e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e0098456d69747320604372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296030666f7263655f63726561746510010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e00013469735f73756666696369656e74200110626f6f6c00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500014cf849737375652061206e657720636c617373206f662066756e6769626c65206173736574732066726f6d20612070726976696c65676564206f726967696e2e00b454686973206e657720617373657420636c61737320686173206e6f2061737365747320696e697469616c6c792e00a4546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e602e009c556e6c696b652060637265617465602c206e6f2066756e6473206172652072657365727665642e0059012d20606964603a20546865206964656e746966696572206f6620746865206e65772061737365742e2054686973206d757374206e6f742062652063757272656e746c7920696e2075736520746f206964656e746966793101616e206578697374696e672061737365742e204966205b604e65787441737365744964605d206973207365742c207468656e2074686973206d75737420626520657175616c20746f2069742e59012d20606f776e6572603a20546865206f776e6572206f66207468697320636c617373206f66206173736574732e20546865206f776e6572206861732066756c6c20737570657275736572207065726d697373696f6e7325016f76657220746869732061737365742c20627574206d6179206c61746572206368616e676520616e6420636f6e66696775726520746865207065726d697373696f6e73207573696e6790607472616e736665725f6f776e6572736869706020616e6420607365745f7465616d602e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e00ac456d6974732060466f7263654372656174656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f283129603473746172745f64657374726f7904010869646d01014c543a3a41737365744964506172616d6574657200022cdc5374617274207468652070726f63657373206f662064657374726f79696e6720612066756e6769626c6520617373657420636c6173732e0059016073746172745f64657374726f79602069732074686520666972737420696e206120736572696573206f662065787472696e7369637320746861742073686f756c642062652063616c6c65642c20746f20616c6c6f77786465737472756374696f6e206f6620616e20617373657420636c6173732e005101546865206f726967696e206d75737420636f6e666f726d20746f2060466f7263654f726967696e60206f72206d75737420626520605369676e65646020627920746865206173736574277320606f776e6572602e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00f854686520617373657420636c617373206d7573742062652066726f7a656e206265666f72652063616c6c696e67206073746172745f64657374726f79602e4064657374726f795f6163636f756e747304010869646d01014c543a3a41737365744964506172616d65746572000330cc44657374726f7920616c6c206163636f756e7473206173736f6369617465642077697468206120676976656e2061737365742e005d016064657374726f795f6163636f756e7473602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79310164657374726f7920616c6c206163636f756e74732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d697460206163636f756e747320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d4456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f7965644163636f756e747360206576656e742e4464657374726f795f617070726f76616c7304010869646d01014c543a3a41737365744964506172616d65746572000430610144657374726f7920616c6c20617070726f76616c73206173736f6369617465642077697468206120676976656e20617373657420757020746f20746865206d61782028543a3a52656d6f76654974656d734c696d6974292e0061016064657374726f795f617070726f76616c73602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e642074686584617373657420697320696e2061206044657374726f79696e67602073746174652e005d0144756520746f20776569676874207265737472696374696f6e732c20746869732066756e6374696f6e206d6179206e65656420746f2062652063616c6c6564206d756c7469706c652074696d657320746f2066756c6c79390164657374726f7920616c6c20617070726f76616c732e2049742077696c6c2064657374726f79206052656d6f76654974656d734c696d69746020617070726f76616c7320617420612074696d652e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00d8456163682063616c6c20656d6974732074686520604576656e743a3a44657374726f796564417070726f76616c7360206576656e742e3866696e6973685f64657374726f7904010869646d01014c543a3a41737365744964506172616d65746572000528c4436f6d706c6574652064657374726f79696e6720617373657420616e6420756e726573657276652063757272656e63792e0055016066696e6973685f64657374726f79602073686f756c64206f6e6c792062652063616c6c6564206166746572206073746172745f64657374726f796020686173206265656e2063616c6c65642c20616e64207468655901617373657420697320696e2061206044657374726f79696e67602073746174652e20416c6c206163636f756e7473206f7220617070726f76616c732073686f756c642062652064657374726f796564206265666f72651468616e642e004d012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652064657374726f7965642e2054686973206d757374206964656e7469667920616e206578697374696e6720202061737365742e00e045616368207375636365737366756c2063616c6c20656d6974732074686520604576656e743a3a44657374726f79656460206576656e742e106d696e740c010869646d01014c543a3a41737365744964506172616d6574657200012c62656e6566696369617279c50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000630884d696e7420617373657473206f66206120706172746963756c617220636c6173732e003901546865206f726967696e206d757374206265205369676e656420616e64207468652073656e646572206d7573742062652074686520497373756572206f662074686520617373657420606964602e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206d696e7465642e0d012d206062656e6566696369617279603a20546865206163636f756e7420746f206265206372656469746564207769746820746865206d696e746564206173736574732ec42d2060616d6f756e74603a2054686520616d6f756e74206f662074686520617373657420746f206265206d696e7465642e0094456d697473206049737375656460206576656e74207768656e207375636365737366756c2e00385765696768743a20604f2831296055014d6f6465733a205072652d6578697374696e672062616c616e6365206f66206062656e6566696369617279603b204163636f756e74207072652d6578697374656e6365206f66206062656e6566696369617279602e106275726e0c010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500073c4501526564756365207468652062616c616e6365206f66206077686f60206279206173206d75636820617320706f737369626c6520757020746f2060616d6f756e746020617373657473206f6620606964602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204d616e61676572206f662074686520617373657420606964602e00d04261696c73207769746820604e6f4163636f756e746020696620746865206077686f6020697320616c726561647920646561642e00fc2d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74206275726e65642ea02d206077686f603a20546865206163636f756e7420746f20626520646562697465642066726f6d2e29012d2060616d6f756e74603a20546865206d6178696d756d20616d6f756e74206279207768696368206077686f6027732062616c616e63652073686f756c6420626520726564756365642e005101456d69747320604275726e6564602077697468207468652061637475616c20616d6f756e74206275726e65642e20496620746869732074616b6573207468652062616c616e636520746f2062656c6f772074686539016d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74206275726e656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296009014d6f6465733a20506f73742d6578697374656e6365206f66206077686f603b20507265202620706f7374205a6f6d6269652d737461747573206f66206077686f602e207472616e736665720c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000848d04d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e4c7472616e736665725f6b6565705f616c6976650c010869646d01014c543a3a41737365744964506172616d65746572000118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e636500094859014d6f766520736f6d65206173736574732066726f6d207468652073656e646572206163636f756e7420746f20616e6f746865722c206b656570696e67207468652073656e646572206163636f756e7420616c6976652e00584f726967696e206d757374206265205369676e65642e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e9c2d2060746172676574603a20546865206163636f756e7420746f2062652063726564697465642e51012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652073656e64657227732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e646101607461726765746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e5d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652073656e6465722062616c616e63652061626f7665207a65726f206275742062656c6f77bc746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f662060746172676574603b20506f73742d6578697374656e6365206f662073656e6465723b204163636f756e74207072652d6578697374656e6365206f662460746172676574602e38666f7263655f7472616e7366657210010869646d01014c543a3a41737365744964506172616d65746572000118736f75726365c50201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e6365000a4cb44d6f766520736f6d65206173736574732066726f6d206f6e65206163636f756e7420746f20616e6f746865722e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e0011012d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206861766520736f6d6520616d6f756e74207472616e736665727265642e982d2060736f75726365603a20546865206163636f756e7420746f20626520646562697465642e942d206064657374603a20546865206163636f756e7420746f2062652063726564697465642e59012d2060616d6f756e74603a2054686520616d6f756e74206279207768696368207468652060736f757263656027732062616c616e6365206f66206173736574732073686f756c64206265207265647563656420616e64590160646573746027732062616c616e636520696e637265617365642e2054686520616d6f756e742061637475616c6c79207472616e73666572726564206d617920626520736c696768746c79206772656174657220696e4d017468652063617365207468617420746865207472616e7366657220776f756c64206f74686572776973652074616b65207468652060736f75726365602062616c616e63652061626f7665207a65726f20627574d462656c6f7720746865206d696e696d756d2062616c616e63652e204d7573742062652067726561746572207468616e207a65726f2e006101456d69747320605472616e73666572726564602077697468207468652061637475616c20616d6f756e74207472616e736665727265642e20496620746869732074616b65732074686520736f757263652062616c616e63655d01746f2062656c6f7720746865206d696e696d756d20666f72207468652061737365742c207468656e2074686520616d6f756e74207472616e7366657272656420697320696e6372656173656420746f2074616b6520697420746f207a65726f2e00385765696768743a20604f2831296051014d6f6465733a205072652d6578697374656e6365206f66206064657374603b20506f73742d6578697374656e6365206f662060736f75726365603b204163636f756e74207072652d6578697374656e6365206f661c6064657374602e18667265657a6508010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000b305501446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e20617373657420606964602066726f6d20616e206163636f756e74206077686f602e206077686f604d016d75737420616c726561647920657869737420617320616e20656e74727920696e20604163636f756e746073206f66207468652061737365742e20496620796f752077616e7420746f20667265657a6520616ef46163636f756e74207468617420646f6573206e6f74206861766520616e20656e7472792c207573652060746f7563685f6f74686572602066697273742e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e882d206077686f603a20546865206163636f756e7420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f28312960107468617708010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000c28e8416c6c6f7720756e70726976696c65676564207472616e736665727320746f20616e642066726f6d20616e206163636f756e7420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e902d206077686f603a20546865206163636f756e7420746f20626520756e66726f7a656e2e003c456d6974732060546861776564602e00385765696768743a20604f2831296030667265657a655f617373657404010869646d01014c543a3a41737365744964506172616d65746572000d24f0446973616c6c6f77206675727468657220756e70726976696c65676564207472616e736665727320666f722074686520617373657420636c6173732e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2e003c456d697473206046726f7a656e602e00385765696768743a20604f2831296028746861775f617373657404010869646d01014c543a3a41737365744964506172616d65746572000e24c4416c6c6f7720756e70726976696c65676564207472616e736665727320666f722074686520617373657420616761696e2e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c64206265207468652041646d696e206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f206265207468617765642e003c456d6974732060546861776564602e00385765696768743a20604f28312960487472616e736665725f6f776e65727368697008010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e000f28744368616e676520746865204f776e6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742e0054456d69747320604f776e65724368616e676564602e00385765696768743a20604f28312960207365745f7465616d10010869646d01014c543a3a41737365744964506172616d65746572000118697373756572c50201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec50201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c50201504163636f756e7449644c6f6f6b75704f663c543e001030c44368616e676520746865204973737565722c2041646d696e20616e6420467265657a6572206f6620616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00c42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f2062652066726f7a656e2ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e0050456d69747320605465616d4368616e676564602e00385765696768743a20604f28312960307365745f6d6574616461746110010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c7308010875380011407853657420746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00d846756e6473206f662073656e64657220617265207265736572766564206163636f7264696e6720746f2074686520666f726d756c613a5101604d657461646174614465706f73697442617365202b204d657461646174614465706f73697450657242797465202a20286e616d652e6c656e202b2073796d626f6c2e6c656e29602074616b696e6720696e746f8c6163636f756e7420616e7920616c72656164792072657365727665642066756e64732e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e00385765696768743a20604f2831296038636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200122c80436c65617220746865206d6574616461746120666f7220616e2061737365742e002d014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c6420626520746865204f776e6572206f662074686520617373657420606964602e00a4416e79206465706f73697420697320667265656420666f7220746865206173736574206f776e65722e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f7365745f6d6574616461746114010869646d01014c543a3a41737365744964506172616d657465720001106e616d6538011c5665633c75383e00011873796d626f6c38011c5665633c75383e000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c001338b8466f72636520746865206d6574616461746120666f7220616e20617373657420746f20736f6d652076616c75652e006c4f726967696e206d75737420626520466f7263654f726967696e2e0068416e79206465706f736974206973206c65667420616c6f6e652e00b82d20606964603a20546865206964656e746966696572206f662074686520617373657420746f207570646174652e4d012d20606e616d65603a20546865207573657220667269656e646c79206e616d65206f6620746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e4d012d206073796d626f6c603a205468652065786368616e67652073796d626f6c20666f7220746869732061737365742e204c696d6974656420696e206c656e6774682062792060537472696e674c696d6974602e2d012d2060646563696d616c73603a20546865206e756d626572206f6620646563696d616c732074686973206173736574207573657320746f20726570726573656e74206f6e6520756e69742e0050456d69747320604d65746164617461536574602e0051015765696768743a20604f284e202b20532960207768657265204e20616e6420532061726520746865206c656e677468206f6620746865206e616d6520616e642073796d626f6c20726573706563746976656c792e50666f7263655f636c6561725f6d6574616461746104010869646d01014c543a3a41737365744964506172616d6574657200142c80436c65617220746865206d6574616461746120666f7220616e2061737365742e006c4f726967696e206d75737420626520466f7263654f726967696e2e0060416e79206465706f7369742069732072657475726e65642e00b42d20606964603a20546865206964656e746966696572206f662074686520617373657420746f20636c6561722e0060456d69747320604d65746164617461436c6561726564602e00385765696768743a20604f2831296048666f7263655f61737365745f73746174757320010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e000118697373756572c50201504163636f756e7449644c6f6f6b75704f663c543e00011461646d696ec50201504163636f756e7449644c6f6f6b75704f663c543e00011c667265657a6572c50201504163636f756e7449644c6f6f6b75704f663c543e00012c6d696e5f62616c616e63656d010128543a3a42616c616e636500013469735f73756666696369656e74200110626f6f6c00012469735f66726f7a656e200110626f6f6c00155898416c746572207468652061747472696275746573206f66206120676976656e2061737365742e00744f726967696e206d7573742062652060466f7263654f726967696e602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e9c2d20606f776e6572603a20546865206e6577204f776e6572206f6620746869732061737365742ea42d2060697373756572603a20546865206e657720497373756572206f6620746869732061737365742e9c2d206061646d696e603a20546865206e65772041646d696e206f6620746869732061737365742eac2d2060667265657a6572603a20546865206e657720467265657a6572206f6620746869732061737365742e4d012d20606d696e5f62616c616e6365603a20546865206d696e696d756d2062616c616e6365206f662074686973206e6577206173736574207468617420616e792073696e676c65206163636f756e74206d7573743d01686176652e20496620616e206163636f756e7427732062616c616e636520697320726564756365642062656c6f7720746869732c207468656e20697420636f6c6c617073657320746f207a65726f2e51012d206069735f73756666696369656e74603a20576865746865722061206e6f6e2d7a65726f2062616c616e6365206f662074686973206173736574206973206465706f736974206f662073756666696369656e744d0176616c756520746f206163636f756e7420666f722074686520737461746520626c6f6174206173736f6369617465642077697468206974732062616c616e63652073746f726167652e2049662073657420746f55016074727565602c207468656e206e6f6e2d7a65726f2062616c616e636573206d61792062652073746f72656420776974686f757420612060636f6e73756d657260207265666572656e63652028616e6420746875734d01616e20454420696e207468652042616c616e6365732070616c6c6574206f7220776861746576657220656c7365206973207573656420746f20636f6e74726f6c20757365722d6163636f756e742073746174652067726f777468292e3d012d206069735f66726f7a656e603a2057686574686572207468697320617373657420636c6173732069732066726f7a656e2065786365707420666f72207065726d697373696f6e65642f61646d696e34696e737472756374696f6e732e00e8456d697473206041737365745374617475734368616e67656460207769746820746865206964656e74697479206f66207468652061737365742e00385765696768743a20604f2831296040617070726f76655f7472616e736665720c010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650016502d01417070726f766520616e20616d6f756e74206f6620617373657420666f72207472616e7366657220627920612064656c6567617465642074686972642d7061727479206163636f756e742e00584f726967696e206d757374206265205369676e65642e004d01456e737572657320746861742060417070726f76616c4465706f7369746020776f727468206f66206043757272656e6379602069732072657365727665642066726f6d207369676e696e67206163636f756e745501666f722074686520707572706f7365206f6620686f6c64696e672074686520617070726f76616c2e20496620736f6d65206e6f6e2d7a65726f20616d6f756e74206f662061737365747320697320616c72656164794901617070726f7665642066726f6d207369676e696e67206163636f756e7420746f206064656c6567617465602c207468656e20697420697320746f70706564207570206f7220756e726573657276656420746f546d656574207468652072696768742076616c75652e0045014e4f54453a20546865207369676e696e67206163636f756e7420646f6573206e6f74206e65656420746f206f776e2060616d6f756e7460206f66206173736574732061742074686520706f696e74206f66446d616b696e6720746869732063616c6c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e0d012d206064656c6567617465603a20546865206163636f756e7420746f2064656c6567617465207065726d697373696f6e20746f207472616e736665722061737365742e49012d2060616d6f756e74603a2054686520616d6f756e74206f662061737365742074686174206d6179206265207472616e73666572726564206279206064656c6567617465602e204966207468657265206973e0616c726561647920616e20617070726f76616c20696e20706c6163652c207468656e207468697320616374732061646469746976656c792e0090456d6974732060417070726f7665645472616e7366657260206f6e20737563636573732e00385765696768743a20604f283129603c63616e63656c5f617070726f76616c08010869646d01014c543a3a41737365744964506172616d6574657200012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e001734490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e003d014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c616365206265747765656e207369676e657220616e642c6064656c6567617465602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f2831296054666f7263655f63616e63656c5f617070726f76616c0c010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e00012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e001834490143616e63656c20616c6c206f6620736f6d6520617373657420617070726f76656420666f722064656c656761746564207472616e7366657220627920612074686972642d7061727479206163636f756e742e0049014f726967696e206d7573742062652065697468657220466f7263654f726967696e206f72205369676e6564206f726967696e207769746820746865207369676e6572206265696e67207468652041646d696e686163636f756e74206f662074686520617373657420606964602e004901556e726573657276657320616e79206465706f7369742070726576696f75736c792072657365727665642062792060617070726f76655f7472616e736665726020666f722074686520617070726f76616c2e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e05012d206064656c6567617465603a20546865206163636f756e742064656c656761746564207065726d697373696f6e20746f207472616e736665722061737365742e0094456d6974732060417070726f76616c43616e63656c6c656460206f6e20737563636573732e00385765696768743a20604f28312960447472616e736665725f617070726f76656410010869646d01014c543a3a41737365744964506172616d657465720001146f776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e00012c64657374696e6174696f6ec50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e746d010128543a3a42616c616e63650019484d015472616e7366657220736f6d652061737365742062616c616e63652066726f6d20612070726576696f75736c792064656c656761746564206163636f756e7420746f20736f6d652074686972642d7061727479206163636f756e742e0049014f726967696e206d757374206265205369676e656420616e64207468657265206d75737420626520616e20617070726f76616c20696e20706c6163652062792074686520606f776e65726020746f207468651c7369676e65722e00590149662074686520656e7469726520616d6f756e7420617070726f76656420666f72207472616e73666572206973207472616e736665727265642c207468656e20616e79206465706f7369742070726576696f75736c79b472657365727665642062792060617070726f76655f7472616e736665726020697320756e72657365727665642e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742e61012d20606f776e6572603a20546865206163636f756e742077686963682070726576696f75736c7920617070726f76656420666f722061207472616e73666572206f66206174206c656173742060616d6f756e746020616e64bc66726f6d207768696368207468652061737365742062616c616e63652077696c6c2062652077697468647261776e2e61012d206064657374696e6174696f6e603a20546865206163636f756e7420746f207768696368207468652061737365742062616c616e6365206f662060616d6f756e74602077696c6c206265207472616e736665727265642eb42d2060616d6f756e74603a2054686520616d6f756e74206f662061737365747320746f207472616e736665722e009c456d69747320605472616e73666572726564417070726f76656460206f6e20737563636573732e00385765696768743a20604f2831296014746f75636804010869646d01014c543a3a41737365744964506172616d65746572001a24c043726561746520616e206173736574206163636f756e7420666f72206e6f6e2d70726f7669646572206173736574732e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e005d012d20606f726967696e603a204d757374206265205369676e65643b20746865207369676e6572206163636f756e74206d75737420686176652073756666696369656e742066756e647320666f722061206465706f736974382020746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e18726566756e6408010869646d01014c543a3a41737365744964506172616d65746572000128616c6c6f775f6275726e200110626f6f6c001b28590152657475726e20746865206465706f7369742028696620616e7929206f6620616e206173736574206163636f756e74206f72206120636f6e73756d6572207265666572656e63652028696620616e7929206f6620616e206163636f756e742e0068546865206f726967696e206d757374206265205369676e65642e003d012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f72207768696368207468652063616c6c657220776f756c64206c696b6520746865206465706f7369742c2020726566756e6465642e5d012d2060616c6c6f775f6275726e603a20496620607472756560207468656e20617373657473206d61792062652064657374726f79656420696e206f7264657220746f20636f6d706c6574652074686520726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e3c7365745f6d696e5f62616c616e636508010869646d01014c543a3a41737365744964506172616d6574657200012c6d696e5f62616c616e6365180128543a3a42616c616e6365001c30945365747320746865206d696e696d756d2062616c616e6365206f6620616e2061737365742e0021014f6e6c7920776f726b73206966207468657265206172656e277420616e79206163636f756e747320746861742061726520686f6c64696e6720746865206173736574206f72206966e0746865206e65772076616c7565206f6620606d696e5f62616c616e636560206973206c657373207468616e20746865206f6c64206f6e652e00fc4f726967696e206d757374206265205369676e656420616e64207468652073656e6465722068617320746f20626520746865204f776e6572206f66207468652c617373657420606964602e00902d20606964603a20546865206964656e746966696572206f66207468652061737365742ec02d20606d696e5f62616c616e6365603a20546865206e65772076616c7565206f6620606d696e5f62616c616e6365602e00d4456d697473206041737365744d696e42616c616e63654368616e67656460206576656e74207768656e207375636365737366756c2e2c746f7563685f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e001d288843726561746520616e206173736574206163636f756e7420666f72206077686f602e00c041206465706f7369742077696c6c2062652074616b656e2066726f6d20746865207369676e6572206163636f756e742e0061012d20606f726967696e603a204d757374206265205369676e65642062792060467265657a657260206f72206041646d696e60206f662074686520617373657420606964603b20746865207369676e6572206163636f756e74dc20206d75737420686176652073756666696369656e742066756e647320666f722061206465706f73697420746f2062652074616b656e2e09012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420746f20626520637265617465642e8c2d206077686f603a20546865206163636f756e7420746f20626520637265617465642e0098456d6974732060546f756368656460206576656e74207768656e207375636365737366756c2e30726566756e645f6f7468657208010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e001e285d0152657475726e20746865206465706f7369742028696620616e7929206f66206120746172676574206173736574206163636f756e742e2055736566756c20696620796f752061726520746865206465706f7369746f722e005d01546865206f726967696e206d757374206265205369676e656420616e642065697468657220746865206163636f756e74206f776e65722c206465706f7369746f722c206f72206173736574206041646d696e602e20496e61016f7264657220746f206275726e2061206e6f6e2d7a65726f2062616c616e6365206f66207468652061737365742c207468652063616c6c6572206d75737420626520746865206163636f756e7420616e642073686f756c64347573652060726566756e64602e0019012d20606964603a20546865206964656e746966696572206f662074686520617373657420666f7220746865206163636f756e7420686f6c64696e672061206465706f7369742e7c2d206077686f603a20546865206163636f756e7420746f20726566756e642e009c456d6974732060526566756e64656460206576656e74207768656e207375636365737366756c2e14626c6f636b08010869646d01014c543a3a41737365744964506172616d6574657200010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e001f285901446973616c6c6f77206675727468657220756e70726976696c65676564207472616e7366657273206f6620616e206173736574206069646020746f20616e642066726f6d20616e206163636f756e74206077686f602e0035014f726967696e206d757374206265205369676e656420616e64207468652073656e6465722073686f756c642062652074686520467265657a6572206f662074686520617373657420606964602e00b82d20606964603a20546865206964656e746966696572206f6620746865206163636f756e7427732061737365742e942d206077686f603a20546865206163636f756e7420746f20626520756e626c6f636b65642e0040456d6974732060426c6f636b6564602e00385765696768743a20604f28312960040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5020c2873705f72756e74696d65306d756c746961646472657373304d756c74694164647265737308244163636f756e7449640100304163636f756e74496e6465780110011408496404000001244163636f756e74496400000014496e6465780400690201304163636f756e74496e6465780001000c526177040038011c5665633c75383e0002002441646472657373333204000401205b75383b2033325d000300244164647265737332300400950101205b75383b2032305d00040000c9020c3c70616c6c65745f62616c616e6365731870616c6c65741043616c6c080454000449000124507472616e736665725f616c6c6f775f646561746808011064657374c50201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e636500001cd45472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e003501607472616e736665725f616c6c6f775f6465617468602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e11014966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74b06f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e38666f7263655f7472616e736665720c0118736f75726365c50201504163636f756e7449644c6f6f6b75704f663c543e00011064657374c50201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000208610145786163746c7920617320607472616e736665725f616c6c6f775f6465617468602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74446d6179206265207370656369666965642e4c7472616e736665725f6b6565705f616c69766508011064657374c50201504163636f756e7449644c6f6f6b75704f663c543e00011476616c75656d010128543a3a42616c616e6365000318590153616d6520617320746865205b607472616e736665725f616c6c6f775f6465617468605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74606b696c6c20746865206f726967696e206163636f756e742e00e8393925206f66207468652074696d6520796f752077616e74205b607472616e736665725f616c6c6f775f6465617468605d20696e73746561642e00f05b607472616e736665725f616c6c6f775f6465617468605d3a207374727563742e50616c6c65742e68746d6c236d6574686f642e7472616e73666572307472616e736665725f616c6c08011064657374c50201504163636f756e7449644c6f6f6b75704f663c543e0001286b6565705f616c697665200110626f6f6c00043c05015472616e736665722074686520656e74697265207472616e7366657261626c652062616c616e63652066726f6d207468652063616c6c6572206163636f756e742e0059014e4f54453a20546869732066756e6374696f6e206f6e6c7920617474656d70747320746f207472616e73666572205f7472616e7366657261626c655f2062616c616e6365732e2054686973206d65616e7320746861746101616e79206c6f636b65642c2072657365727665642c206f72206578697374656e7469616c206465706f7369747320287768656e20606b6565705f616c6976656020697320607472756560292c2077696c6c206e6f742062655d017472616e7366657272656420627920746869732066756e6374696f6e2e20546f20656e73757265207468617420746869732066756e6374696f6e20726573756c747320696e2061206b696c6c6564206163636f756e742c4501796f75206d69676874206e65656420746f207072657061726520746865206163636f756e742062792072656d6f76696e6720616e79207265666572656e636520636f756e746572732c2073746f72616765406465706f736974732c206574632e2e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205369676e65642e00a02d206064657374603a2054686520726563697069656e74206f6620746865207472616e736665722e59012d20606b6565705f616c697665603a204120626f6f6c65616e20746f2064657465726d696e652069662074686520607472616e736665725f616c6c60206f7065726174696f6e2073686f756c642073656e6420616c6c4d0120206f66207468652066756e647320746865206163636f756e74206861732c2063617573696e67207468652073656e646572206163636f756e7420746f206265206b696c6c6564202866616c7365292c206f72590120207472616e736665722065766572797468696e6720657863657074206174206c6561737420746865206578697374656e7469616c206465706f7369742c2077686963682077696c6c2067756172616e74656520746f9c20206b656570207468652073656e646572206163636f756e7420616c697665202874727565292e3c666f7263655f756e7265736572766508010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000118616d6f756e74180128543a3a42616c616e636500050cb0556e7265736572766520736f6d652062616c616e63652066726f6d2061207573657220627920666f7263652e006c43616e206f6e6c792062652063616c6c656420627920524f4f542e40757067726164655f6163636f756e747304010c77686f350201445665633c543a3a4163636f756e7449643e0006207055706772616465206120737065636966696564206163636f756e742e00742d20606f726967696e603a204d75737420626520605369676e6564602e902d206077686f603a20546865206163636f756e7420746f2062652075706772616465642e005501546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966206174206c6561737420616c6c2062757420313025206f6620746865206163636f756e7473206e656564656420746f410162652075706772616465642e20285765206c657420736f6d65206e6f74206861766520746f206265207570677261646564206a75737420696e206f7264657220746f20616c6c6f7720666f722074686558706f73736962696c697479206f6620636875726e292e44666f7263655f7365745f62616c616e636508010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e0001206e65775f667265656d010128543a3a42616c616e636500080cac5365742074686520726567756c61722062616c616e6365206f66206120676976656e206163636f756e742e00b0546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e6c666f7263655f61646a7573745f746f74616c5f69737375616e6365080124646972656374696f6ecd02014c41646a7573746d656e74446972656374696f6e00011464656c74616d010128543a3a42616c616e6365000914b841646a7573742074686520746f74616c2069737375616e636520696e20612073617475726174696e67207761792e00fc43616e206f6e6c792062652063616c6c656420627920726f6f7420616e6420616c77617973206e65656473206120706f736974697665206064656c7461602e002423204578616d706c65106275726e08011476616c75656d010128543a3a42616c616e63650001286b6565705f616c697665200110626f6f6c000a1cfc4275726e2074686520737065636966696564206c697175696420667265652062616c616e63652066726f6d20746865206f726967696e206163636f756e742e002501496620746865206f726967696e2773206163636f756e7420656e64732075702062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c7409016f6620746865206275726e20616e6420606b6565705f616c697665602069732066616c73652c20746865206163636f756e742077696c6c206265207265617065642e005101556e6c696b652073656e64696e672066756e647320746f2061205f6275726e5f20616464726573732c207768696368206d6572656c79206d616b6573207468652066756e647320696e61636365737369626c652c21017468697320606275726e60206f7065726174696f6e2077696c6c2072656475636520746f74616c2069737375616e63652062792074686520616d6f756e74205f6275726e65645f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ecd020c3c70616c6c65745f62616c616e6365731474797065734c41646a7573746d656e74446972656374696f6e00010820496e63726561736500000020446563726561736500010000d1020c2c70616c6c65745f626162651870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66d5020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e5020140543a3a4b65794f776e657250726f6f6600001009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66d5020190426f783c45717569766f636174696f6e50726f6f663c486561646572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f66e5020140543a3a4b65794f776e657250726f6f6600012009015265706f727420617574686f726974792065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667905017468652065717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f660d01616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63652077696c6c306265207265706f727465642e0d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e48706c616e5f636f6e6669675f6368616e6765040118636f6e666967e90201504e657874436f6e66696744657363726970746f720002105d01506c616e20616e2065706f636820636f6e666967206368616e67652e205468652065706f636820636f6e666967206368616e6765206973207265636f7264656420616e642077696c6c20626520656e6163746564206f6e5101746865206e6578742063616c6c20746f2060656e6163745f65706f63685f6368616e6765602e2054686520636f6e6669672077696c6c20626520616374697661746564206f6e652065706f63682061667465722e59014d756c7469706c652063616c6c7320746f2074686973206d6574686f642077696c6c207265706c61636520616e79206578697374696e6720706c616e6e656420636f6e666967206368616e6765207468617420686164546e6f74206265656e20656e6163746564207965742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed502084873705f636f6e73656e7375735f736c6f74734445717569766f636174696f6e50726f6f66081848656164657201d90208496401dd02001001206f6666656e646572dd0201084964000110736c6f74e1020110536c6f7400013066697273745f686561646572d90201184865616465720001347365636f6e645f686561646572d90201184865616465720000d902102873705f72756e74696d651c67656e65726963186865616465721848656164657208184e756d62657201301048617368000014012c706172656e745f68617368340130486173683a3a4f75747075740001186e756d6265722c01184e756d62657200012873746174655f726f6f74340130486173683a3a4f757470757400013c65787472696e736963735f726f6f74340130486173683a3a4f75747075740001186469676573743c01184469676573740000dd020c4473705f636f6e73656e7375735f626162650c617070185075626c69630000040004013c737232353531393a3a5075626c69630000e102084873705f636f6e73656e7375735f736c6f747310536c6f740000040030010c7536340000e502082873705f73657373696f6e3c4d656d6265727368697050726f6f6600000c011c73657373696f6e10013053657373696f6e496e646578000128747269655f6e6f6465737d0201305665633c5665633c75383e3e00013c76616c696461746f725f636f756e7410013856616c696461746f72436f756e740000e9020c4473705f636f6e73656e7375735f626162651c64696765737473504e657874436f6e66696744657363726970746f7200010408563108010463ed020128287536342c2075363429000134616c6c6f7765645f736c6f7473f1020130416c6c6f776564536c6f747300010000ed0200000408303000f102084473705f636f6e73656e7375735f6261626530416c6c6f776564536c6f747300010c305072696d617279536c6f7473000000745072696d617279416e645365636f6e64617279506c61696e536c6f74730001006c5072696d617279416e645365636f6e64617279565246536c6f747300020000f5020c3870616c6c65745f6772616e6470611870616c6c65741043616c6c04045400010c4c7265706f72745f65717569766f636174696f6e08014865717569766f636174696f6e5f70726f6f66f90201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f6621030140543a3a4b65794f776e657250726f6f6600001009015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e707265706f72745f65717569766f636174696f6e5f756e7369676e656408014865717569766f636174696f6e5f70726f6f66f90201c8426f783c45717569766f636174696f6e50726f6f663c543a3a486173682c20426c6f636b4e756d626572466f723c543e3e3e00013c6b65795f6f776e65725f70726f6f6621030140543a3a4b65794f776e657250726f6f6600012409015265706f727420766f7465722065717569766f636174696f6e2f6d69736265686176696f722e2054686973206d6574686f642077696c6c2076657269667920746865f465717569766f636174696f6e2070726f6f6620616e642076616c69646174652074686520676976656e206b6579206f776e6572736869702070726f6f66f8616761696e73742074686520657874726163746564206f6666656e6465722e20496620626f7468206172652076616c69642c20746865206f6666656e63654477696c6c206265207265706f727465642e000d01546869732065787472696e736963206d7573742062652063616c6c656420756e7369676e656420616e642069742069732065787065637465642074686174206f6e6c791501626c6f636b20617574686f72732077696c6c2063616c6c206974202876616c69646174656420696e206056616c6964617465556e7369676e656460292c2061732073756368150169662074686520626c6f636b20617574686f7220697320646566696e65642069742077696c6c20626520646566696e6564206173207468652065717569766f636174696f6e247265706f727465722e306e6f74655f7374616c6c656408011464656c6179300144426c6f636b4e756d626572466f723c543e00016c626573745f66696e616c697a65645f626c6f636b5f6e756d626572300144426c6f636b4e756d626572466f723c543e0002303d014e6f74652074686174207468652063757272656e7420617574686f7269747920736574206f6620746865204752414e4450412066696e616c6974792067616467657420686173207374616c6c65642e006101546869732077696c6c2074726967676572206120666f7263656420617574686f7269747920736574206368616e67652061742074686520626567696e6e696e67206f6620746865206e6578742073657373696f6e2c20746f6101626520656e6163746564206064656c61796020626c6f636b7320616674657220746861742e20546865206064656c6179602073686f756c64206265206869676820656e6f75676820746f20736166656c7920617373756d654901746861742074686520626c6f636b207369676e616c6c696e672074686520666f72636564206368616e67652077696c6c206e6f742062652072652d6f7267656420652e672e203130303020626c6f636b732e5d0154686520626c6f636b2070726f64756374696f6e207261746520287768696368206d617920626520736c6f77656420646f776e2062656361757365206f662066696e616c697479206c616767696e67292073686f756c64510162652074616b656e20696e746f206163636f756e74207768656e2063686f6f73696e6720746865206064656c6179602e20546865204752414e44504120766f74657273206261736564206f6e20746865206e65775501617574686f726974792077696c6c20737461727420766f74696e67206f6e20746f70206f662060626573745f66696e616c697a65645f626c6f636b5f6e756d6265726020666f72206e65772066696e616c697a65644d01626c6f636b732e2060626573745f66696e616c697a65645f626c6f636b5f6e756d626572602073686f756c64206265207468652068696768657374206f6620746865206c61746573742066696e616c697a6564c4626c6f636b206f6620616c6c2076616c696461746f7273206f6620746865206e657720617574686f72697479207365742e00584f6e6c792063616c6c61626c6520627920726f6f742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef902085073705f636f6e73656e7375735f6772616e6470614445717569766f636174696f6e50726f6f660804480134044e0130000801187365745f6964300114536574496400013065717569766f636174696f6efd02014845717569766f636174696f6e3c482c204e3e0000fd02085073705f636f6e73656e7375735f6772616e6470613045717569766f636174696f6e0804480134044e013001081c507265766f74650400010301890166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265766f74653c0a482c204e3e2c20417574686f726974795369676e61747572652c3e00000024507265636f6d6d69740400150301910166696e616c6974795f6772616e6470613a3a45717569766f636174696f6e3c417574686f7269747949642c2066696e616c6974795f6772616e6470613a3a507265636f6d6d69740a3c482c204e3e2c20417574686f726974795369676e61747572652c3e000100000103084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456010503045301090300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273741103011828562c2053290001187365636f6e641103011828562c20532900000503084066696e616c6974795f6772616e6470611c507265766f74650804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e000009030c5073705f636f6e73656e7375735f6772616e6470610c617070245369676e6174757265000004000d030148656432353531393a3a5369676e617475726500000d0300000340000000080011030000040805030903001503084066696e616c6974795f6772616e6470613045717569766f636174696f6e0c08496401a80456011903045301090300100130726f756e645f6e756d62657230010c7536340001206964656e74697479a80108496400011466697273741d03011828562c2053290001187365636f6e641d03011828562c20532900001903084066696e616c6974795f6772616e64706124507265636f6d6d69740804480134044e01300008012c7461726765745f68617368340104480001347461726765745f6e756d6265723001044e00001d030000040819030903002103081c73705f636f726510566f69640001000025030c3870616c6c65745f696e64696365731870616c6c65741043616c6c04045400011414636c61696d040114696e64657810013c543a3a4163636f756e74496e6465780000309841737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e00dc5061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00f02d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e207472616e7366657208010c6e6577c50201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e6465780001305d0141737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6eb86973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0025012d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e1066726565040114696e64657810013c543a3a4163636f756e74496e646578000230944672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e005d015061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e000d012d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e0084456d6974732060496e646578467265656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e38666f7263655f7472616e736665720c010c6e6577c50201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c543a3a4163636f756e74496e646578000118667265657a65200110626f6f6c0003345501466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c7265616479e868656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00a42d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e5d012d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e41012d2060667265657a65603a2069662073657420746f206074727565602c2077696c6c20667265657a652074686520696e64657820736f2069742063616e6e6f74206265207472616e736665727265642e0090456d6974732060496e64657841737369676e656460206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e18667265657a65040114696e64657810013c543a3a4163636f756e74496e6465780004304101467265657a6520616e20696e64657820736f2069742077696c6c20616c7761797320706f696e7420746f207468652073656e646572206163636f756e742e205468697320636f6e73756d657320746865206465706f7369742e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d757374206861766520616c6e6f6e2d66726f7a656e206163636f756e742060696e646578602e00ac2d2060696e646578603a2074686520696e64657820746f2062652066726f7a656e20696e20706c6163652e0088456d6974732060496e64657846726f7a656e60206966207375636365737366756c2e0034232320436f6d706c6578697479242d20604f283129602e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e29030c4070616c6c65745f64656d6f63726163791870616c6c65741043616c6c04045400014c1c70726f706f736508012070726f706f73616c2d030140426f756e64656443616c6c4f663c543e00011476616c75656d01013042616c616e63654f663c543e0000249c50726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e001501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737480686176652066756e647320746f20636f76657220746865206465706f7369742e00d42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e15012d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e0044456d697473206050726f706f736564602e187365636f6e6404012070726f706f73616c6902012450726f70496e646578000118b45369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e64657211016d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e00c82d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e10766f74650801247265665f696e6465786902013c5265666572656e64756d496e646578000110766f7465b801644163636f756e74566f74653c42616c616e63654f663c543e3e00021c3101566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3bb86f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00dc2d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e842d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e40656d657267656e63795f63616e63656c0401247265665f696e64657810013c5265666572656e64756d496e6465780003204d015363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d652c7265666572656e64756d2e00f8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e00d02d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e003c5765696768743a20604f283129602e4065787465726e616c5f70726f706f736504012070726f706f73616c2d030140426f756e64656443616c6c4f663c543e0004182d015363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c2c7265666572656e64756d2e00e8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e6465787465726e616c5f70726f706f73655f6d616a6f7269747904012070726f706f73616c2d030140426f756e64656443616c6c4f663c543e00052c55015363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c655c616e2065787465726e616c207265666572656e64756d2e00ec546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f283129606065787465726e616c5f70726f706f73655f64656661756c7404012070726f706f73616c2d030140426f756e64656443616c6c4f663c543e00062c45015363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f807363686564756c6520616e2065787465726e616c207265666572656e64756d2e00e8546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e00d42d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e004901556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061987072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e00385765696768743a20604f2831296028666173745f747261636b0c013470726f706f73616c5f6861736834011c543a3a48617368000134766f74696e675f706572696f64300144426c6f636b4e756d626572466f723c543e00011464656c6179300144426c6f636b4e756d626572466f723c543e0007404d015363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c65646101696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e65e8627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e00d0546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e00f42d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e5d012d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f88094d75737420626520616c776179732067726561746572207468616e207a65726f2e350109466f72206046617374547261636b4f726967696e60206d75737420626520657175616c206f722067726561746572207468616e206046617374547261636b566f74696e67506572696f64602e51012d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265b82020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e0040456d697473206053746172746564602e00385765696768743a20604f28312960347665746f5f65787465726e616c04013470726f706f73616c5f6861736834011c543a3a48617368000824b85665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e00d8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e002d012d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e003c456d69747320605665746f6564602e00fc5765696768743a20604f2856202b206c6f6728562929602077686572652056206973206e756d626572206f6620606578697374696e67207665746f657273604463616e63656c5f7265666572656e64756d0401247265665f696e6465786902013c5265666572656e64756d496e64657800091c5052656d6f76652061207265666572656e64756d2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e00d42d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e004423205765696768743a20604f283129602e2064656c65676174650c0108746fc50201504163636f756e7449644c6f6f6b75704f663c543e000128636f6e76696374696f6e39030128436f6e76696374696f6e00011c62616c616e636518013042616c616e63654f663c543e000a50390144656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e0055015468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f7220746865c874696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a7420202d2062652064656c65676174696e6720616c72656164793b206f72590120202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656494202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e0045012d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e55012d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e20746865410120206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e61012d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d757374206e6f74b420206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e0048456d697473206044656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e28756e64656c6567617465000b30cc556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e005d01546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64dc6f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062655463757272656e746c792064656c65676174696e672e0050456d6974732060556e64656c656761746564602e003d015765696768743a20604f28522960207768657265205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722064656c65676174696e6720746f20686173c82020766f746564206f6e2e205765696768742069732063686172676564206173206966206d6178696d756d20766f7465732e58636c6561725f7075626c69635f70726f706f73616c73000c1470436c6561727320616c6c207075626c69632070726f706f73616c732e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e003c5765696768743a20604f283129602e18756e6c6f636b040118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e000d1ca0556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e00b82d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e00bc5765696768743a20604f2852296020776974682052206e756d626572206f6620766f7465206f66207461726765742e2c72656d6f76655f766f7465040114696e64657810013c5265666572656e64756d496e646578000e6c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e000c49663a882d20746865207265666572656e64756d207761732063616e63656c6c65642c206f727c2d20746865207265666572656e64756d206973206f6e676f696e672c206f72902d20746865207265666572656e64756d2068617320656e64656420737563682074686174fc20202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f72d420202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f728420202d20746865206163636f756e74206d61646520612073706c697420766f74655d012e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72655866756e6473206265696e6720617661696c61626c652e00a849662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643aec2d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64dc2d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64bc2d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f76657259012e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c766559012a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756de46f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e004901546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465887265676973746572656420666f72207265666572656e64756d2060696e646578602e00f42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e4472656d6f76655f6f746865725f766f7465080118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e000114696e64657810013c5265666572656e64756d496e646578000f3c7c52656d6f7665206120766f746520666f722061207265666572656e64756d2e004d0149662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f2d016072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c5501656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7298626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e00c8546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e004d012d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f725420207265666572656e64756d2060696e646578602ef42d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e0055015765696768743a20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2ed820205765696768742069732063616c63756c6174656420666f7220746865206d6178696d756d206e756d626572206f6620766f74652e24626c61636b6c69737408013470726f706f73616c5f6861736834011c543a3a4861736800013c6d617962655f7265665f696e6465783d03015c4f7074696f6e3c5265666572656e64756d496e6465783e00103c45015065726d616e656e746c7920706c61636520612070726f706f73616c20696e746f2074686520626c61636b6c6973742e20546869732070726576656e74732069742066726f6d2065766572206265696e673c70726f706f73656420616761696e2e00510149662063616c6c6564206f6e206120717565756564207075626c6963206f722065787465726e616c2070726f706f73616c2c207468656e20746869732077696c6c20726573756c7420696e206974206265696e67510172656d6f7665642e2049662074686520607265665f696e6465786020737570706c69656420697320616e20616374697665207265666572656e64756d2077697468207468652070726f706f73616c20686173682c687468656e2069742077696c6c2062652063616e63656c6c65642e00ec546865206469737061746368206f726967696e206f6620746869732063616c6c206d7573742062652060426c61636b6c6973744f726967696e602e00f82d206070726f706f73616c5f68617368603a205468652070726f706f73616c206861736820746f20626c61636b6c697374207065726d616e656e746c792e45012d20607265665f696e646578603a20416e206f6e676f696e67207265666572656e64756d2077686f73652068617368206973206070726f706f73616c5f68617368602c2077686963682077696c6c2062652863616e63656c6c65642e0041015765696768743a20604f28702960202874686f756768206173207468697320697320616e20686967682d70726976696c6567652064697370617463682c20776520617373756d65206974206861732061502020726561736f6e61626c652076616c7565292e3c63616e63656c5f70726f706f73616c04012870726f705f696e6465786902012450726f70496e64657800111c4852656d6f766520612070726f706f73616c2e000101546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c50726f706f73616c4f726967696e602e00d02d206070726f705f696e646578603a2054686520696e646578206f66207468652070726f706f73616c20746f2063616e63656c2e00e45765696768743a20604f28702960207768657265206070203d205075626c696350726f70733a3a3c543e3a3a6465636f64655f6c656e282960307365745f6d657461646174610801146f776e6572c001344d657461646174614f776e65720001286d617962655f686173684103013c4f7074696f6e3c543a3a486173683e00123cd8536574206f7220636c6561722061206d65746164617461206f6620612070726f706f73616c206f722061207265666572656e64756d2e002c506172616d65746572733acc2d20606f726967696e603a204d75737420636f72726573706f6e6420746f2074686520604d657461646174614f776e6572602e3d01202020202d206045787465726e616c4f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479417070726f766560402020202020207468726573686f6c642e5901202020202d206045787465726e616c44656661756c744f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053757065724d616a6f72697479416761696e737460402020202020207468726573686f6c642e4501202020202d206045787465726e616c4d616a6f726974794f726967696e6020666f7220616e2065787465726e616c2070726f706f73616c207769746820746865206053696d706c654d616a6f7269747960402020202020207468726573686f6c642ec8202020202d20605369676e65646020627920612063726561746f7220666f722061207075626c69632070726f706f73616c2ef4202020202d20605369676e65646020746f20636c6561722061206d6574616461746120666f7220612066696e6973686564207265666572656e64756d2ee4202020202d2060526f6f746020746f207365742061206d6574616461746120666f7220616e206f6e676f696e67207265666572656e64756d2eb42d20606f776e6572603a20616e206964656e746966696572206f662061206d65746164617461206f776e65722e51012d20606d617962655f68617368603a205468652068617368206f6620616e206f6e2d636861696e2073746f72656420707265696d6167652e20604e6f6e656020746f20636c6561722061206d657461646174612e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e2d0310346672616d655f737570706f72741874726169747324707265696d616765731c426f756e64656408045401bd020448013103010c184c656761637904011068617368340124483a3a4f757470757400000018496e6c696e65040035030134426f756e646564496e6c696e65000100184c6f6f6b757008011068617368340124483a3a4f757470757400010c6c656e10010c7533320002000031030c2873705f72756e74696d65187472616974732c426c616b6554776f3235360000000035030c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000039030c4070616c6c65745f64656d6f637261637928636f6e76696374696f6e28436f6e76696374696f6e00011c104e6f6e65000000204c6f636b65643178000100204c6f636b65643278000200204c6f636b65643378000300204c6f636b65643478000400204c6f636b65643578000500204c6f636b65643678000600003d0304184f7074696f6e04045401100108104e6f6e6500000010536f6d650400100000010000410304184f7074696f6e04045401340108104e6f6e6500000010536f6d65040034000001000045030c4470616c6c65745f636f6c6c6563746976651870616c6c65741043616c6c0804540004490001182c7365745f6d656d626572730c012c6e65775f6d656d62657273350201445665633c543a3a4163636f756e7449643e0001147072696d658801504f7074696f6e3c543a3a4163636f756e7449643e0001246f6c645f636f756e7410012c4d656d626572436f756e74000060805365742074686520636f6c6c6563746976652773206d656d626572736869702e0045012d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e642070726f7669646520697420736f727465642ee02d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e59012d20606f6c645f636f756e74603a2054686520757070657220626f756e6420666f72207468652070726576696f7573206e756d626572206f66206d656d6265727320696e2073746f726167652e205573656420666f7250202077656967687420657374696d6174696f6e2e00d4546865206469737061746368206f6620746869732063616c6c206d75737420626520605365744d656d626572734f726967696e602e0051014e4f54453a20446f6573206e6f7420656e666f7263652074686520657870656374656420604d61784d656d6265727360206c696d6974206f6e2074686520616d6f756e74206f66206d656d626572732c2062757421012020202020207468652077656967687420657374696d6174696f6e732072656c79206f6e20697420746f20657374696d61746520646973706174636861626c65207765696768742e002823205741524e494e473a005901546865206070616c6c65742d636f6c6c656374697665602063616e20616c736f206265206d616e61676564206279206c6f676963206f757473696465206f66207468652070616c6c6574207468726f75676820746865b8696d706c656d656e746174696f6e206f6620746865207472616974205b604368616e67654d656d62657273605d2e5501416e792063616c6c20746f20607365745f6d656d6265727360206d757374206265206361726566756c207468617420746865206d656d6265722073657420646f65736e277420676574206f7574206f662073796e63a477697468206f74686572206c6f676963206d616e6167696e6720746865206d656d626572207365742e0038232320436f6d706c65786974793a502d20604f284d50202b204e29602077686572653ae020202d20604d60206f6c642d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429e020202d20604e60206e65772d6d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564299820202d206050602070726f706f73616c732d636f756e742028636f64652d626f756e646564291c6578656375746508012070726f706f73616cbd02017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646902010c753332000124f0446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e00a84f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e0038232320436f6d706c65786974793a5c2d20604f2842202b204d202b205029602077686572653ad82d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429882d20604d60206d656d626572732d636f756e742028636f64652d626f756e64656429a82d2060506020636f6d706c6578697479206f66206469737061746368696e67206070726f706f73616c601c70726f706f73650c01247468726573686f6c646902012c4d656d626572436f756e7400012070726f706f73616cbd02017c426f783c3c5420617320436f6e6669673c493e3e3a3a50726f706f73616c3e0001306c656e6774685f626f756e646902010c753332000238f84164642061206e65772070726f706f73616c20746f2065697468657220626520766f746564206f6e206f72206578656375746564206469726563746c792e00845265717569726573207468652073656e64657220746f206265206d656d6265722e004101607468726573686f6c64602064657465726d696e65732077686574686572206070726f706f73616c60206973206578656375746564206469726563746c792028607468726573686f6c64203c20326029546f722070757420757020666f7220766f74696e672e0034232320436f6d706c6578697479ac2d20604f2842202b204d202b2050312960206f7220604f2842202b204d202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c420202d206272616e6368696e6720697320696e666c75656e63656420627920607468726573686f6c64602077686572653af4202020202d20605031602069732070726f706f73616c20657865637574696f6e20636f6d706c65786974792028607468726573686f6c64203c20326029fc202020202d20605032602069732070726f706f73616c732d636f756e742028636f64652d626f756e646564292028607468726573686f6c64203e3d2032602910766f74650c012070726f706f73616c34011c543a3a48617368000114696e6465786902013450726f706f73616c496e64657800011c617070726f7665200110626f6f6c000324f041646420616e20617965206f72206e617920766f746520666f72207468652073656e64657220746f2074686520676976656e2070726f706f73616c2e008c5265717569726573207468652073656e64657220746f2062652061206d656d6265722e0049015472616e73616374696f6e20666565732077696c6c2062652077616976656420696620746865206d656d62657220697320766f74696e67206f6e20616e7920706172746963756c61722070726f706f73616c5101666f72207468652066697273742074696d6520616e64207468652063616c6c206973207375636365737366756c2e2053756273657175656e7420766f7465206368616e6765732077696c6c206368617267652061106665652e34232320436f6d706c657869747909012d20604f284d296020776865726520604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e646564294c646973617070726f76655f70726f706f73616c04013470726f706f73616c5f6861736834011c543a3a486173680005285901446973617070726f766520612070726f706f73616c2c20636c6f73652c20616e642072656d6f76652069742066726f6d207468652073797374656d2c207265676172646c657373206f66206974732063757272656e741873746174652e00884d7573742062652063616c6c65642062792074686520526f6f74206f726967696e2e002c506172616d65746572733a1d012a206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20746861742073686f756c6420626520646973617070726f7665642e0034232320436f6d706c6578697479ac4f285029207768657265205020697320746865206e756d626572206f66206d61782070726f706f73616c7314636c6f736510013470726f706f73616c5f6861736834011c543a3a48617368000114696e6465786902013450726f706f73616c496e64657800015470726f706f73616c5f7765696768745f626f756e642801185765696768740001306c656e6774685f626f756e646902010c7533320006604d01436c6f7365206120766f746520746861742069732065697468657220617070726f7665642c20646973617070726f766564206f722077686f736520766f74696e6720706572696f642068617320656e6465642e0055014d61792062652063616c6c656420627920616e79207369676e6564206163636f756e7420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e00490149662063616c6c6564206265666f72652074686520656e64206f662074686520766f74696e6720706572696f642069742077696c6c206f6e6c7920636c6f73652074686520766f7465206966206974206973bc68617320656e6f75676820766f74657320746f20626520617070726f766564206f7220646973617070726f7665642e00490149662063616c6c65642061667465722074686520656e64206f662074686520766f74696e6720706572696f642061627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e732501756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e00610149662074686520636c6f7365206f7065726174696f6e20636f6d706c65746573207375636365737366756c6c79207769746820646973617070726f76616c2c20746865207472616e73616374696f6e206665652077696c6c5d016265207761697665642e204f746865727769736520657865637574696f6e206f662074686520617070726f766564206f7065726174696f6e2077696c6c206265206368617267656420746f207468652063616c6c65722e0061012b206070726f706f73616c5f7765696768745f626f756e64603a20546865206d6178696d756d20616d6f756e74206f662077656967687420636f6e73756d656420627920657865637574696e672074686520636c6f7365642470726f706f73616c2e61012b20606c656e6774685f626f756e64603a2054686520757070657220626f756e6420666f7220746865206c656e677468206f66207468652070726f706f73616c20696e2073746f726167652e20436865636b65642076696135016073746f726167653a3a726561646020736f206974206973206073697a655f6f663a3a3c7533323e2829203d3d203460206c6172676572207468616e207468652070757265206c656e6774682e0034232320436f6d706c6578697479742d20604f2842202b204d202b205031202b20503229602077686572653ae020202d20604260206973206070726f706f73616c602073697a6520696e20627974657320286c656e6774682d6665652d626f756e64656429dc20202d20604d60206973206d656d626572732d636f756e742028636f64652d20616e6420676f7665726e616e63652d626f756e64656429c820202d20605031602069732074686520636f6d706c6578697479206f66206070726f706f73616c6020707265696d6167652ea420202d20605032602069732070726f706f73616c2d636f756e742028636f64652d626f756e64656429040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e49030c3870616c6c65745f76657374696e671870616c6c65741043616c6c0404540001181076657374000024b8556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e005d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e28766573745f6f74686572040118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e00012cb8556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051012d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c646c6f636b656420756e64657220746869732070616c6c65742e00d0456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e0034232320436f6d706c6578697479242d20604f283129602e3c7665737465645f7472616e73666572080118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c654d0301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00023464437265617465206120766573746564207472616e736665722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00cc2d2060746172676574603a20546865206163636f756e7420726563656976696e6720746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e54666f7263655f7665737465645f7472616e736665720c0118736f75726365c50201504163636f756e7449644c6f6f6b75704f663c543e000118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e0001207363686564756c654d0301b056657374696e67496e666f3c42616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e3e00033860466f726365206120766573746564207472616e736665722e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00e82d2060736f75726365603a20546865206163636f756e742077686f73652066756e64732073686f756c64206265207472616e736665727265642e11012d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732ef02d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e005c456d697473206056657374696e6743726561746564602e00fc4e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b2e0034232320436f6d706c6578697479242d20604f283129602e3c6d657267655f7363686564756c657308013c7363686564756c65315f696e64657810010c75333200013c7363686564756c65325f696e64657810010c7533320004545d014d657267652074776f2076657374696e67207363686564756c657320746f6765746865722c206372656174696e672061206e65772076657374696e67207363686564756c65207468617420756e6c6f636b73206f7665725501746865206869676865737420706f737369626c6520737461727420616e6420656e6420626c6f636b732e20496620626f7468207363686564756c6573206861766520616c7265616479207374617274656420746865590163757272656e7420626c6f636b2077696c6c206265207573656420617320746865207363686564756c652073746172743b207769746820746865206361766561742074686174206966206f6e65207363686564756c655d0169732066696e6973686564206279207468652063757272656e7420626c6f636b2c20746865206f746865722077696c6c206265207472656174656420617320746865206e6577206d6572676564207363686564756c652c2c756e6d6f6469666965642e00f84e4f54453a20496620607363686564756c65315f696e646578203d3d207363686564756c65325f696e6465786020746869732069732061206e6f2d6f702e41014e4f54453a20546869732077696c6c20756e6c6f636b20616c6c207363686564756c6573207468726f756768207468652063757272656e7420626c6f636b207072696f7220746f206d657267696e672e61014e4f54453a20496620626f7468207363686564756c6573206861766520656e646564206279207468652063757272656e7420626c6f636b2c206e6f206e6577207363686564756c652077696c6c206265206372656174656464616e6420626f74682077696c6c2062652072656d6f7665642e006c4d6572676564207363686564756c6520617474726962757465733a35012d20607374617274696e675f626c6f636b603a20604d4158287363686564756c65312e7374617274696e675f626c6f636b2c207363686564756c6564322e7374617274696e675f626c6f636b2c48202063757272656e745f626c6f636b29602e21012d2060656e64696e675f626c6f636b603a20604d4158287363686564756c65312e656e64696e675f626c6f636b2c207363686564756c65322e656e64696e675f626c6f636b29602e59012d20606c6f636b6564603a20607363686564756c65312e6c6f636b65645f61742863757272656e745f626c6f636b29202b207363686564756c65322e6c6f636b65645f61742863757272656e745f626c6f636b29602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e00e82d20607363686564756c65315f696e646578603a20696e646578206f6620746865206669727374207363686564756c6520746f206d657267652eec2d20607363686564756c65325f696e646578603a20696e646578206f6620746865207365636f6e64207363686564756c6520746f206d657267652e74666f7263655f72656d6f76655f76657374696e675f7363686564756c65080118746172676574c502018c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263650001387363686564756c655f696e64657810010c7533320005187c466f7263652072656d6f766520612076657374696e67207363686564756c6500c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e00c82d2060746172676574603a20416e206163636f756e7420746861742068617320612076657374696e67207363686564756c6515012d20607363686564756c655f696e646578603a205468652076657374696e67207363686564756c6520696e64657820746861742073686f756c642062652072656d6f766564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e4d030c3870616c6c65745f76657374696e673076657374696e675f696e666f2c56657374696e67496e666f081c42616c616e636501182c426c6f636b4e756d6265720130000c01186c6f636b656418011c42616c616e63650001247065725f626c6f636b18011c42616c616e63650001387374617274696e675f626c6f636b30012c426c6f636b4e756d626572000051030c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c65741043616c6c04045400011810766f7465080114766f746573350201445665633c543a3a4163636f756e7449643e00011476616c75656d01013042616c616e63654f663c543e00004c5901566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e20546869732063616e2062652063616c6c656420746fe07365742074686520696e697469616c20766f7465732c206f722075706461746520616c7265616479206578697374696e6720766f7465732e005d0155706f6e20696e697469616c20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e642061206465706f73697420616d6f756e742069734d0172657365727665642e20546865206465706f736974206973206261736564206f6e20746865206e756d626572206f6620766f74657320616e642063616e2062652075706461746564206f7665722074696d652e004c5468652060766f746573602073686f756c643a4420202d206e6f7420626520656d7074792e550120202d206265206c657373207468616e20746865206e756d626572206f6620706f737369626c652063616e646964617465732e204e6f7465207468617420616c6c2063757272656e74206d656d6265727320616e6411012020202072756e6e6572732d75702061726520616c736f206175746f6d61746963616c6c792063616e6469646174657320666f7220746865206e65787420726f756e642e0049014966206076616c756560206973206d6f7265207468616e206077686f60277320667265652062616c616e63652c207468656e20746865206d6178696d756d206f66207468652074776f20697320757365642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e6700550149742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f202a2a4e4f542a2a20706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865a86c6f636b20616e64206b65657020736f6d6520666f722066757274686572206f7065726174696f6e732e3072656d6f76655f766f7465720001146c52656d6f766520606f726967696e60206173206120766f7465722e00b8546869732072656d6f76657320746865206c6f636b20616e642072657475726e7320746865206465706f7369742e00fc546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420616e64206265206120766f7465722e407375626d69745f63616e64696461637904013c63616e6469646174655f636f756e746902010c75333200023c11015375626d6974206f6e6573656c6620666f722063616e6469646163792e204120666978656420616d6f756e74206f66206465706f736974206973207265636f726465642e005d01416c6c2063616e64696461746573206172652077697065642061742074686520656e64206f6620746865207465726d2e205468657920656974686572206265636f6d652061206d656d6265722f72756e6e65722d75702ccc6f72206c65617665207468652073797374656d207768696c65207468656972206465706f73697420697320736c61736865642e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642e002c232323205761726e696e67005d014576656e20696620612063616e64696461746520656e6473207570206265696e672061206d656d6265722c2074686579206d7573742063616c6c205b6043616c6c3a3a72656e6f756e63655f63616e646964616379605d5901746f20676574207468656972206465706f736974206261636b2e204c6f73696e67207468652073706f7420696e20616e20656c656374696f6e2077696c6c20616c77617973206c65616420746f206120736c6173682e000901546865206e756d626572206f662063757272656e742063616e64696461746573206d7573742062652070726f7669646564206173207769746e65737320646174612e34232320436f6d706c6578697479a44f2843202b206c6f672843292920776865726520432069732063616e6469646174655f636f756e742e4872656e6f756e63655f63616e64696461637904012872656e6f756e63696e675503012852656e6f756e63696e670003504d0152656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c3c6f7574636f6d65732065786973743a0049012d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c20746865206465706f736974206973f02020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e61012d20606f726967696e6020697320612063757272656e742072756e6e65722d75702e20496e207468697320636173652c20746865206465706f73697420697320756e72657365727665642c2072657475726e656420616e648c20206f726967696e2069732072656d6f76656420617320612072756e6e65722d75702e55012d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c20746865206465706f73697420697320756e726573657276656420616e64206f726967696e2069735501202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e6101202053696d696c617220746f205b6072656d6f76655f6d656d626572605d2853656c663a3a72656d6f76655f6d656d626572292c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865795901202061726520696d6d6564696174656c7920757365642e20496620746865207072696d652069732072656e6f756e63696e672c207468656e206e6f207072696d652077696c6c20657869737420756e74696c207468653420206e65787420726f756e642e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642c20616e642068617665206f6e65206f66207468652061626f766520726f6c65732ee05468652074797065206f662072656e6f756e63696e67206d7573742062652070726f7669646564206173207769746e65737320646174612e0034232320436f6d706c6578697479dc20202d2052656e6f756e63696e673a3a43616e64696461746528636f756e74293a204f28636f756e74202b206c6f6728636f756e7429297020202d2052656e6f756e63696e673a3a4d656d6265723a204f2831297820202d2052656e6f756e63696e673a3a52756e6e657255703a204f2831293472656d6f76655f6d656d6265720c010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000128736c6173685f626f6e64200110626f6f6c000138726572756e5f656c656374696f6e200110626f6f6c000440590152656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f667c746865206f7574676f696e67206d656d62657220697320736c61736865642e005501496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c616365732074686555016f7574676f696e67206d656d6265722e204f74686572776973652c2069662060726572756e5f656c656374696f6e60206973206074727565602c2061206e65772070687261676d656e20656c656374696f6e2069737c737461727465642c20656c73652c206e6f7468696e672068617070656e732e00590149662060736c6173685f626f6e64602069732073657420746f20747275652c2074686520626f6e64206f6620746865206d656d626572206265696e672072656d6f76656420697320736c61736865642e20456c73652c3c69742069732072657475726e65642e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0041014e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e0034232320436f6d706c657869747905012d20436865636b2064657461696c73206f662072656d6f76655f616e645f7265706c6163655f6d656d626572282920616e6420646f5f70687261676d656e28292e50636c65616e5f646566756e63745f766f746572730801286e756d5f766f7465727310010c75333200012c6e756d5f646566756e637410010c7533320005244501436c65616e20616c6c20766f746572732077686f2061726520646566756e63742028692e652e207468657920646f206e6f7420736572766520616e7920707572706f736520617420616c6c292e20546865ac6465706f736974206f66207468652072656d6f76656420766f74657273206172652072657475726e65642e0001015468697320697320616e20726f6f742066756e6374696f6e20746f2062652075736564206f6e6c7920666f7220636c65616e696e67207468652073746174652e00b8546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520726f6f742e0034232320436f6d706c65786974798c2d20436865636b2069735f646566756e63745f766f74657228292064657461696c732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5503086470616c6c65745f656c656374696f6e735f70687261676d656e2852656e6f756e63696e6700010c184d656d6265720000002052756e6e657255700001002443616e64696461746504006902010c7533320002000059030c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c65741043616c6c0404540001143c7375626d69745f756e7369676e65640801307261775f736f6c7574696f6e5d0301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e00011c7769746e6573732d040158536f6c7574696f6e4f72536e617073686f7453697a65000038a45375626d6974206120736f6c7574696f6e20666f722074686520756e7369676e65642070686173652e00c8546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f6e6f6e655f5f2e003d0154686973207375626d697373696f6e20697320636865636b6564206f6e2074686520666c792e204d6f72656f7665722c207468697320756e7369676e656420736f6c7574696f6e206973206f6e6c79550176616c696461746564207768656e207375626d697474656420746f2074686520706f6f6c2066726f6d20746865202a2a6c6f63616c2a2a206e6f64652e204566666563746976656c792c2074686973206d65616e735d0174686174206f6e6c79206163746976652076616c696461746f72732063616e207375626d69742074686973207472616e73616374696f6e207768656e20617574686f72696e67206120626c6f636b202873696d696c617240746f20616e20696e686572656e74292e005901546f2070726576656e7420616e7920696e636f727265637420736f6c7574696f6e2028616e642074687573207761737465642074696d652f776569676874292c2074686973207472616e73616374696f6e2077696c6c4d0170616e69632069662074686520736f6c7574696f6e207375626d6974746564206279207468652076616c696461746f7220697320696e76616c696420696e20616e79207761792c206566666563746976656c799c70757474696e6720746865697220617574686f72696e6720726577617264206174207269736b2e00e04e6f206465706f736974206f7220726577617264206973206173736f63696174656420776974682074686973207375626d697373696f6e2e6c7365745f6d696e696d756d5f756e747275737465645f73636f72650401406d617962655f6e6578745f73636f7265310401544f7074696f6e3c456c656374696f6e53636f72653e000114b05365742061206e65772076616c756520666f7220604d696e696d756d556e7472757374656453636f7265602e00d84469737061746368206f726967696e206d75737420626520616c69676e656420776974682060543a3a466f7263654f726967696e602e00f05468697320636865636b2063616e206265207475726e6564206f66662062792073657474696e67207468652076616c756520746f20604e6f6e65602e747365745f656d657267656e63795f656c656374696f6e5f726573756c74040120737570706f72747335040158537570706f7274733c543a3a4163636f756e7449643e0002205901536574206120736f6c7574696f6e20696e207468652071756575652c20746f2062652068616e646564206f757420746f2074686520636c69656e74206f6620746869732070616c6c657420696e20746865206e6578748863616c6c20746f2060456c656374696f6e50726f76696465723a3a656c656374602e004501546869732063616e206f6e6c79206265207365742062792060543a3a466f7263654f726967696e602c20616e64206f6e6c79207768656e207468652070686173652069732060456d657267656e6379602e00610154686520736f6c7574696f6e206973206e6f7420636865636b656420666f7220616e7920666561736962696c69747920616e6420697320617373756d656420746f206265207472757374776f727468792c20617320616e795101666561736962696c69747920636865636b20697473656c662063616e20696e207072696e6369706c652063617573652074686520656c656374696f6e2070726f6365737320746f206661696c202864756520746f686d656d6f72792f77656967687420636f6e73747261696e73292e187375626d69740401307261775f736f6c7574696f6e5d0301b0426f783c526177536f6c7574696f6e3c536f6c7574696f6e4f663c543a3a4d696e6572436f6e6669673e3e3e0003249c5375626d6974206120736f6c7574696f6e20666f7220746865207369676e65642070686173652e00d0546865206469737061746368206f726967696e20666f20746869732063616c6c206d757374206265205f5f7369676e65645f5f2e005d0154686520736f6c7574696f6e20697320706f74656e7469616c6c79207175657565642c206261736564206f6e2074686520636c61696d65642073636f726520616e642070726f6365737365642061742074686520656e64506f6620746865207369676e65642070686173652e005d0141206465706f73697420697320726573657276656420616e64207265636f7264656420666f722074686520736f6c7574696f6e2e204261736564206f6e20746865206f7574636f6d652c2074686520736f6c7574696f6e15016d696768742062652072657761726465642c20736c61736865642c206f722067657420616c6c206f7220612070617274206f6620746865206465706f736974206261636b2e4c676f7665726e616e63655f66616c6c6261636b0801406d617962655f6d61785f766f746572733d03012c4f7074696f6e3c7533323e0001446d617962655f6d61785f746172676574733d03012c4f7074696f6e3c7533323e00041080547269676765722074686520676f7665726e616e63652066616c6c6261636b2e004901546869732063616e206f6e6c792062652063616c6c6564207768656e205b6050686173653a3a456d657267656e6379605d20697320656e61626c65642c20617320616e20616c7465726e617469766520746fc063616c6c696e67205b6043616c6c3a3a7365745f656d657267656e63795f656c656374696f6e5f726573756c74605d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e5d03089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173652c526177536f6c7574696f6e040453016103000c0120736f6c7574696f6e610301045300011473636f7265e00134456c656374696f6e53636f7265000114726f756e6410010c75333200006103085874616e676c655f746573746e65745f72756e74696d65384e706f73536f6c7574696f6e31360000400118766f74657331650300000118766f74657332710300000118766f74657333850300000118766f74657334910300000118766f746573359d0300000118766f74657336a90300000118766f74657337b50300000118766f74657338c10300000118766f74657339cd030000011c766f7465733130d9030000011c766f7465733131e5030000011c766f7465733132f1030000011c766f7465733133fd030000011c766f746573313409040000011c766f746573313515040000011c766f74657331362104000000650300000269030069030000040869026d03006d03000006e90100710300000275030075030000040c690279036d03007903000004086d037d03007d0300000681030081030c3473705f61726974686d65746963287065725f7468696e67731850657255313600000400e901010c7531360000850300000289030089030000040c69028d036d03008d0300000302000000790300910300000295030095030000040c690299036d03009903000003030000007903009d03000002a10300a1030000040c6902a5036d0300a50300000304000000790300a903000002ad0300ad030000040c6902b1036d0300b10300000305000000790300b503000002b90300b9030000040c6902bd036d0300bd0300000306000000790300c103000002c50300c5030000040c6902c9036d0300c90300000307000000790300cd03000002d10300d1030000040c6902d5036d0300d50300000308000000790300d903000002dd0300dd030000040c6902e1036d0300e10300000309000000790300e503000002e90300e9030000040c6902ed036d0300ed030000030a000000790300f103000002f50300f5030000040c6902f9036d0300f9030000030b000000790300fd0300000201040001040000040c690205046d030005040000030c00000079030009040000020d04000d040000040c690211046d030011040000030d000000790300150400000219040019040000040c69021d046d03001d040000030e000000790300210400000225040025040000040c690229046d030029040000030f0000007903002d04089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736558536f6c7574696f6e4f72536e617073686f7453697a650000080118766f746572736902010c75333200011c746172676574736902010c7533320000310404184f7074696f6e04045401e00108104e6f6e6500000010536f6d650400e000000100003504000002390400390400000408003d04003d04084473705f6e706f735f656c656374696f6e731c537570706f727404244163636f756e744964010000080114746f74616c18013c457874656e64656442616c616e6365000118766f74657273d001845665633c284163636f756e7449642c20457874656e64656442616c616e6365293e00004104103870616c6c65745f7374616b696e671870616c6c65741870616c6c65741043616c6c04045400017810626f6e6408011476616c75656d01013042616c616e63654f663c543e0001147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000040610154616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c80626520746865206163636f756e74207468617420636f6e74726f6c732069742e002d016076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e002101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e003c456d6974732060426f6e646564602e34232320436f6d706c6578697479d02d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e1c2d204f2831292e642d20546872656520657874726120444220656e74726965732e004d014e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e65645901756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20286f7220657175616c20746f20302920616e6420676574732072656d6f76656420617320647573742e28626f6e645f65787472610401386d61785f6164646974696f6e616c6d01013042616c616e63654f663c543e000138610141646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757030666f72207374616b696e672e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e004d01557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e5501556e6c696b65205b60626f6e64605d2853656c663a3a626f6e6429206f72205b60756e626f6e64605d2853656c663a3a756e626f6e642920746869732066756e6374696f6e20646f6573206e6f7420696d706f7365bc616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e003c456d6974732060426f6e646564602e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e1c2d204f2831292e18756e626f6e6404011476616c75656d01013042616c616e63654f663c543e00024c51015363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e64fc706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e2101543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0045014f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665bc7468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e0031014e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d6178556e6c6f636b696e674368756e6b736029410163616e20636f2d657869737473206174207468652073616d652074696d652e20496620746865726520617265206e6f20756e6c6f636b696e67206368756e6b7320736c6f747320617661696c61626c6545015b6043616c6c3a3a77697468647261775f756e626f6e646564605d2069732063616c6c656420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e00390149662061207573657220656e636f756e74657273207468652060496e73756666696369656e74426f6e6460206572726f72207768656e2063616c6c696e6720746869732065787472696e7369632c1901746865792073686f756c642063616c6c20606368696c6c6020666972737420696e206f7264657220746f206672656520757020746865697220626f6e6465642066756e64732e0044456d6974732060556e626f6e646564602e009453656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e4477697468647261775f756e626f6e6465640401486e756d5f736c617368696e675f7370616e7310010c75333200035c290152656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e0055015468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722469742077616e74732e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722e0048456d697473206057697468647261776e602e006853656520616c736f205b6043616c6c3a3a756e626f6e64605d2e0034232320506172616d65746572730051012d20606e756d5f736c617368696e675f7370616e736020696e6469636174657320746865206e756d626572206f66206d6574616461746120736c617368696e67207370616e7320746f20636c656172207768656e5501746869732063616c6c20726573756c747320696e206120636f6d706c6574652072656d6f76616c206f6620616c6c2074686520646174612072656c6174656420746f20746865207374617368206163636f756e742e3d01496e207468697320636173652c2074686520606e756d5f736c617368696e675f7370616e7360206d757374206265206c6172676572206f7220657175616c20746f20746865206e756d626572206f665d01736c617368696e67207370616e73206173736f636961746564207769746820746865207374617368206163636f756e7420696e20746865205b60536c617368696e675370616e73605d2073746f7261676520747970652c25016f7468657277697365207468652063616c6c2077696c6c206661696c2e205468652063616c6c20776569676874206973206469726563746c792070726f706f7274696f6e616c20746f54606e756d5f736c617368696e675f7370616e73602e0034232320436f6d706c6578697479d84f285329207768657265205320697320746865206e756d626572206f6620736c617368696e67207370616e7320746f2072656d6f766509014e4f54453a2057656967687420616e6e6f746174696f6e20697320746865206b696c6c207363656e6172696f2c20776520726566756e64206f74686572776973652e2076616c69646174650401147072656673f8013856616c696461746f725072656673000414e44465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e206e6f6d696e61746504011c74617267657473450401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e0005280d014465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c65786974792d012d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f662060746172676574736020284e29050177686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542028543a3a4d61784e6f6d696e6174696f6e73292ed42d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e146368696c6c000628c44465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e502d20436f6e7461696e73206f6e6520726561642ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e247365745f70617965650401147061796565f0017c52657761726444657374696e6174696f6e3c543a3a4163636f756e7449643e000730b42852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e0034232320436f6d706c6578697479182d204f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e242d2d2d2d2d2d2d2d2d387365745f636f6e74726f6c6c657200083845012852652d29736574732074686520636f6e74726f6c6c6572206f66206120737461736820746f2074686520737461736820697473656c662e20546869732066756e6374696f6e2070726576696f75736c794d01616363657074656420612060636f6e74726f6c6c65726020617267756d656e7420746f207365742074686520636f6e74726f6c6c657220746f20616e206163636f756e74206f74686572207468616e207468655901737461736820697473656c662e20546869732066756e6374696f6e616c69747920686173206e6f77206265656e2072656d6f7665642c206e6f77206f6e6c792073657474696e672074686520636f6e74726f6c6c65728c746f207468652073746173682c206966206974206973206e6f7420616c72656164792e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479104f283129e42d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e942d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732ec42d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e4c7365745f76616c696461746f725f636f756e7404010c6e65776902010c75333200091890536574732074686520696465616c206e756d626572206f662076616c696461746f72732e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c6578697479104f28312960696e6372656173655f76616c696461746f725f636f756e740401286164646974696f6e616c6902010c753332000a1ce8496e6372656d656e74732074686520696465616c206e756d626572206f662076616c696461746f727320757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e547363616c655f76616c696461746f725f636f756e74040118666163746f725502011c50657263656e74000b1c11015363616c652075702074686520696465616c206e756d626572206f662076616c696461746f7273206279206120666163746f7220757020746f206d6178696d756d206f668c60456c656374696f6e50726f7669646572426173653a3a4d617857696e6e657273602e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320436f6d706c65786974799853616d65206173205b6053656c663a3a7365745f76616c696461746f725f636f756e74605d2e34666f7263655f6e6f5f65726173000c34ac466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e3901546875732074686520656c656374696f6e2070726f63657373206d6179206265206f6e676f696e67207768656e20746869732069732063616c6c65642e20496e2074686973206361736520746865dc656c656374696f6e2077696c6c20636f6e74696e756520756e74696c20746865206e65787420657261206973207472696767657265642e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f28312934666f7263655f6e65775f657261000d384901466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c2062659c726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e0034232320436f6d706c65786974793c2d204e6f20617267756d656e74732e382d205765696768743a204f283129447365745f696e76756c6e657261626c6573040134696e76756c6e657261626c6573350201445665633c543a3a4163636f756e7449643e000e0cc8536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e34666f7263655f756e7374616b650801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c753332000f200901466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e50666f7263655f6e65775f6572615f616c776179730010240101466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e0084546865206469737061746368206f726967696e206d75737420626520526f6f742e002423205761726e696e6700190154686520656c656374696f6e2070726f6365737320737461727473206d756c7469706c6520626c6f636b73206265666f72652074686520656e64206f6620746865206572612e4901496620746869732069732063616c6c6564206a757374206265666f72652061206e657720657261206973207472696767657265642c2074686520656c656374696f6e2070726f63657373206d6179206e6f748c6861766520656e6f75676820626c6f636b7320746f20676574206120726573756c742e5463616e63656c5f64656665727265645f736c61736808010c657261100120457261496e646578000134736c6173685f696e6469636573490401205665633c7533323e0011149443616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e009843616e2062652063616c6c6564206279207468652060543a3a41646d696e4f726967696e602e000101506172616d65746572733a2065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e387061796f75745f7374616b65727308013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780012341901506179206f7574206e6578742070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e206572612e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e00490154686520726577617264207061796f757420636f756c6420626520706167656420696e20636173652074686572652061726520746f6f206d616e79206e6f6d696e61746f7273206261636b696e67207468655d016076616c696461746f725f7374617368602e20546869732063616c6c2077696c6c207061796f757420756e7061696420706167657320696e20616e20617363656e64696e67206f726465722e20546f20636c61696d2061b4737065636966696320706167652c2075736520607061796f75745f7374616b6572735f62795f70616765602e6000f0496620616c6c2070616765732061726520636c61696d65642c2069742072657475726e7320616e206572726f722060496e76616c696450616765602e187265626f6e6404011476616c75656d01013042616c616e63654f663c543e00131cdc5265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e00d4546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722e0034232320436f6d706c6578697479d02d2054696d6520636f6d706c65786974793a204f284c292c207768657265204c20697320756e6c6f636b696e67206368756e6b73882d20426f756e64656420627920604d6178556e6c6f636b696e674368756e6b73602e28726561705f73746173680801147374617368000130543a3a4163636f756e7449640001486e756d5f736c617368696e675f7370616e7310010c7533320014485d0152656d6f766520616c6c2064617461207374727563747572657320636f6e6365726e696e672061207374616b65722f7374617368206f6e636520697420697320617420612073746174652077686572652069742063616e0501626520636f6e736964657265642060647573746020696e20746865207374616b696e672073797374656d2e2054686520726571756972656d656e7473206172653a000501312e207468652060746f74616c5f62616c616e636560206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e1101322e206f722c2074686520606c65646765722e746f74616c60206f66207468652073746173682069732062656c6f77206578697374656e7469616c206465706f7369742e6101332e206f722c206578697374656e7469616c206465706f736974206973207a65726f20616e64206569746865722060746f74616c5f62616c616e636560206f7220606c65646765722e746f74616c60206973207a65726f2e00550154686520666f726d65722063616e2068617070656e20696e206361736573206c696b65206120736c6173683b20746865206c6174746572207768656e20612066756c6c7920756e626f6e646564206163636f756e7409016973207374696c6c20726563656976696e67207374616b696e67207265776172647320696e206052657761726444657374696e6174696f6e3a3a5374616b6564602e00310149742063616e2062652063616c6c656420627920616e796f6e652c206173206c6f6e672061732060737461736860206d65657473207468652061626f766520726571756972656d656e74732e00dc526566756e647320746865207472616e73616374696f6e20666565732075706f6e207375636365737366756c20657865637574696f6e2e0034232320506172616d65746572730045012d20606e756d5f736c617368696e675f7370616e73603a20526566657220746f20636f6d6d656e7473206f6e205b6043616c6c3a3a77697468647261775f756e626f6e646564605d20666f72206d6f72652064657461696c732e106b69636b04010c77686f450401645665633c4163636f756e7449644c6f6f6b75704f663c543e3e00152ce052656d6f76652074686520676976656e206e6f6d696e6174696f6e732066726f6d207468652063616c6c696e672076616c696461746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e005101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e004d012d206077686f603a2041206c697374206f66206e6f6d696e61746f72207374617368206163636f756e74732077686f20617265206e6f6d696e6174696e6720746869732076616c696461746f72207768696368c0202073686f756c64206e6f206c6f6e676572206265206e6f6d696e6174696e6720746869732076616c696461746f722e0055014e6f74653a204d616b696e6720746869732063616c6c206f6e6c79206d616b65732073656e736520696620796f7520666972737420736574207468652076616c696461746f7220707265666572656e63657320746f78626c6f636b20616e792066757274686572206e6f6d696e6174696f6e732e4c7365745f7374616b696e675f636f6e666967731c01486d696e5f6e6f6d696e61746f725f626f6e644d040158436f6e6669674f703c42616c616e63654f663c543e3e0001486d696e5f76616c696461746f725f626f6e644d040158436f6e6669674f703c42616c616e63654f663c543e3e00014c6d61785f6e6f6d696e61746f725f636f756e7451040134436f6e6669674f703c7533323e00014c6d61785f76616c696461746f725f636f756e7451040134436f6e6669674f703c7533323e00013c6368696c6c5f7468726573686f6c6455040144436f6e6669674f703c50657263656e743e0001386d696e5f636f6d6d697373696f6e59040144436f6e6669674f703c50657262696c6c3e0001486d61785f7374616b65645f7265776172647355040144436f6e6669674f703c50657263656e743e001644ac5570646174652074686520766172696f7573207374616b696e6720636f6e66696775726174696f6e73202e0025012a20606d696e5f6e6f6d696e61746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f2062652061206e6f6d696e61746f722e25012a20606d696e5f76616c696461746f725f626f6e64603a20546865206d696e696d756d2061637469766520626f6e64206e656564656420746f20626520612076616c696461746f722e55012a20606d61785f6e6f6d696e61746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e2062652061206e6f6d696e61746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e55012a20606d61785f76616c696461746f725f636f756e74603a20546865206d6178206e756d626572206f662075736572732077686f2063616e20626520612076616c696461746f72206174206f6e63652e205768656e98202073657420746f20604e6f6e65602c206e6f206c696d697420697320656e666f726365642e59012a20606368696c6c5f7468726573686f6c64603a2054686520726174696f206f6620606d61785f6e6f6d696e61746f725f636f756e7460206f7220606d61785f76616c696461746f725f636f756e74602077686963681901202073686f756c642062652066696c6c656420696e206f7264657220666f722074686520606368696c6c5f6f7468657260207472616e73616374696f6e20746f20776f726b2e61012a20606d696e5f636f6d6d697373696f6e603a20546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e550120205468697320697320636865636b6564206f6e6c792075706f6e2063616c6c696e67206076616c6964617465602e204578697374696e672076616c696461746f727320617265206e6f742061666665637465642e00c452756e74696d654f726967696e206d75737420626520526f6f7420746f2063616c6c20746869732066756e6374696f6e2e0035014e4f54453a204578697374696e67206e6f6d696e61746f727320616e642076616c696461746f72732077696c6c206e6f742062652061666665637465642062792074686973207570646174652e1101746f206b69636b2070656f706c6520756e64657220746865206e6577206c696d6974732c20606368696c6c5f6f74686572602073686f756c642062652063616c6c65642e2c6368696c6c5f6f746865720401147374617368000130543a3a4163636f756e74496400176841014465636c61726520612060636f6e74726f6c6c65726020746f2073746f702070617274696369706174696e672061732065697468657220612076616c696461746f72206f72206e6f6d696e61746f722e00d8456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e004101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2c206275742063616e2062652063616c6c656420627920616e796f6e652e0059014966207468652063616c6c6572206973207468652073616d652061732074686520636f6e74726f6c6c6572206265696e672074617267657465642c207468656e206e6f206675727468657220636865636b7320617265d8656e666f726365642c20616e6420746869732066756e6374696f6e2062656861766573206a757374206c696b6520606368696c6c602e005d014966207468652063616c6c657220697320646966666572656e74207468616e2074686520636f6e74726f6c6c6572206265696e672074617267657465642c2074686520666f6c6c6f77696e6720636f6e646974696f6e73306d757374206265206d65743a001d012a2060636f6e74726f6c6c657260206d7573742062656c6f6e6720746f2061206e6f6d696e61746f722077686f20686173206265636f6d65206e6f6e2d6465636f6461626c652c000c4f723a003d012a204120604368696c6c5468726573686f6c6460206d7573742062652073657420616e6420636865636b656420776869636820646566696e657320686f7720636c6f736520746f20746865206d6178550120206e6f6d696e61746f7273206f722076616c696461746f7273207765206d757374207265616368206265666f72652075736572732063616e207374617274206368696c6c696e67206f6e652d616e6f746865722e59012a204120604d61784e6f6d696e61746f72436f756e746020616e6420604d617856616c696461746f72436f756e7460206d75737420626520736574207768696368206973207573656420746f2064657465726d696e65902020686f7720636c6f73652077652061726520746f20746865207468726573686f6c642e5d012a204120604d696e4e6f6d696e61746f72426f6e646020616e6420604d696e56616c696461746f72426f6e6460206d7573742062652073657420616e6420636865636b65642c2077686963682064657465726d696e65735101202069662074686973206973206120706572736f6e20746861742073686f756c64206265206368696c6c6564206265636175736520746865792068617665206e6f74206d657420746865207468726573686f6c64402020626f6e642072657175697265642e005501546869732063616e2062652068656c7066756c20696620626f6e6420726571756972656d656e74732061726520757064617465642c20616e64207765206e65656420746f2072656d6f7665206f6c642075736572739877686f20646f206e6f74207361746973667920746865736520726571756972656d656e74732e68666f7263655f6170706c795f6d696e5f636f6d6d697373696f6e04013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400180c4501466f72636520612076616c696461746f7220746f2068617665206174206c6561737420746865206d696e696d756d20636f6d6d697373696f6e2e20546869732077696c6c206e6f74206166666563742061610176616c696461746f722077686f20616c726561647920686173206120636f6d6d697373696f6e2067726561746572207468616e206f7220657175616c20746f20746865206d696e696d756d2e20416e79206163636f756e743863616e2063616c6c20746869732e487365745f6d696e5f636f6d6d697373696f6e04010c6e6577f4011c50657262696c6c00191025015365747320746865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e207468617420656163682076616c696461746f7273206d757374206d61696e7461696e2e005901546869732063616c6c20686173206c6f7765722070726976696c65676520726571756972656d656e7473207468616e20607365745f7374616b696e675f636f6e6669676020616e642063616e2062652063616c6c6564cc6279207468652060543a3a41646d696e4f726967696e602e20526f6f742063616e20616c776179732063616c6c20746869732e587061796f75745f7374616b6572735f62795f706167650c013c76616c696461746f725f7374617368000130543a3a4163636f756e74496400010c657261100120457261496e6465780001107061676510011050616765001a443101506179206f757420612070616765206f6620746865207374616b65727320626568696e6420612076616c696461746f7220666f722074686520676976656e2065726120616e6420706167652e00e82d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e31012d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e31012d2060706167656020697320746865207061676520696e646578206f66206e6f6d696e61746f727320746f20706179206f757420776974682076616c7565206265747765656e203020616e64b02020606e756d5f6e6f6d696e61746f7273202f20543a3a4d61784578706f737572655061676553697a65602e005501546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966746974206973206e6f74206f6e65206f6620746865207374616b6572732e003d01496620612076616c696461746f7220686173206d6f7265207468616e205b60436f6e6669673a3a4d61784578706f737572655061676553697a65605d206e6f6d696e61746f7273206261636b696e6729017468656d2c207468656e20746865206c697374206f66206e6f6d696e61746f72732069732070616765642c207769746820656163682070616765206265696e672063617070656420617455015b60436f6e6669673a3a4d61784578706f737572655061676553697a65602e5d20496620612076616c696461746f7220686173206d6f7265207468616e206f6e652070616765206f66206e6f6d696e61746f72732c49017468652063616c6c206e6565647320746f206265206d61646520666f72206561636820706167652073657061726174656c7920696e206f7264657220666f7220616c6c20746865206e6f6d696e61746f727355016261636b696e6720612076616c696461746f7220746f207265636569766520746865207265776172642e20546865206e6f6d696e61746f727320617265206e6f7420736f72746564206163726f73732070616765736101616e6420736f2069742073686f756c64206e6f7420626520617373756d6564207468652068696768657374207374616b657220776f756c64206265206f6e2074686520746f706d6f7374207061676520616e642076696365490176657273612e204966207265776172647320617265206e6f7420636c61696d656420696e205b60436f6e6669673a3a486973746f72794465707468605d20657261732c207468657920617265206c6f73742e307570646174655f7061796565040128636f6e74726f6c6c6572000130543a3a4163636f756e744964001b18e04d6967726174657320616e206163636f756e742773206052657761726444657374696e6174696f6e3a3a436f6e74726f6c6c65726020746fa46052657761726444657374696e6174696f6e3a3a4163636f756e7428636f6e74726f6c6c657229602e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e003101546869732077696c6c20776169766520746865207472616e73616374696f6e20666565206966207468652060706179656560206973207375636365737366756c6c79206d696772617465642e686465707265636174655f636f6e74726f6c6c65725f626174636804012c636f6e74726f6c6c6572735d0401f4426f756e6465645665633c543a3a4163636f756e7449642c20543a3a4d6178436f6e74726f6c6c657273496e4465707265636174696f6e42617463683e001c1c5d01557064617465732061206261746368206f6620636f6e74726f6c6c6572206163636f756e747320746f20746865697220636f72726573706f6e64696e67207374617368206163636f756e7420696620746865792061726561016e6f74207468652073616d652e2049676e6f72657320616e7920636f6e74726f6c6c6572206163636f756e7473207468617420646f206e6f742065786973742c20616e6420646f6573206e6f74206f706572617465206966b874686520737461736820616e6420636f6e74726f6c6c65722061726520616c7265616479207468652073616d652e005101456666656374732077696c6c2062652066656c7420696e7374616e746c792028617320736f6f6e20617320746869732066756e6374696f6e20697320636f6d706c65746564207375636365737366756c6c79292e00b4546865206469737061746368206f726967696e206d7573742062652060543a3a41646d696e4f726967696e602e38726573746f72655f6c65646765721001147374617368000130543a3a4163636f756e7449640001406d617962655f636f6e74726f6c6c65728801504f7074696f6e3c543a3a4163636f756e7449643e00012c6d617962655f746f74616c610401504f7074696f6e3c42616c616e63654f663c543e3e00013c6d617962655f756e6c6f636b696e6765040115014f7074696f6e3c426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a0a4d6178556e6c6f636b696e674368756e6b733e3e001d2c0501526573746f72657320746865207374617465206f662061206c656467657220776869636820697320696e20616e20696e636f6e73697374656e742073746174652e00dc54686520726571756972656d656e747320746f20726573746f72652061206c6564676572206172652074686520666f6c6c6f77696e673a642a2054686520737461736820697320626f6e6465643b206f720d012a20546865207374617368206973206e6f7420626f6e64656420627574206974206861732061207374616b696e67206c6f636b206c65667420626568696e643b206f7225012a204966207468652073746173682068617320616e206173736f636961746564206c656467657220616e642069747320737461746520697320696e636f6e73697374656e743b206f721d012a20496620746865206c6564676572206973206e6f7420636f72727570746564202a6275742a20697473207374616b696e67206c6f636b206973206f7574206f662073796e632e00610154686520606d617962655f2a6020696e70757420706172616d65746572732077696c6c206f76657277726974652074686520636f72726573706f6e64696e67206461746120616e64206d65746164617461206f662074686559016c6564676572206173736f6369617465642077697468207468652073746173682e2049662074686520696e70757420706172616d657465727320617265206e6f74207365742c20746865206c65646765722077696c6c9062652072657365742076616c7565732066726f6d206f6e2d636861696e2073746174652e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e4504000002c50200490400000210004d04103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200005104103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f7665000200005504103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f70040454015502010c104e6f6f700000000c536574040055020104540001001852656d6f7665000200005904103870616c6c65745f7374616b696e671870616c6c65741870616c6c657420436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f7665000200005d040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400350201185665633c543e0000610404184f7074696f6e04045401180108104e6f6e6500000010536f6d650400180000010000650404184f7074696f6e0404540169040108104e6f6e6500000010536f6d6504006904000001000069040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016d04045300000400710401185665633c543e00006d04083870616c6c65745f7374616b696e672c556e6c6f636b4368756e6b041c42616c616e636501180008011476616c75656d01011c42616c616e636500010c65726169020120457261496e646578000071040000026d040075040c3870616c6c65745f73657373696f6e1870616c6c65741043616c6c040454000108207365745f6b6579730801106b6579737904011c543a3a4b65797300011470726f6f6638011c5665633c75383e000024e453657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e1d01416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722ec05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e00d0546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e0034232320436f6d706c657869747959012d20604f283129602e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f69647328296020776869636820697320202066697865642e2870757267655f6b657973000130c852656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e00c05468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e005501546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265205369676e656420616e6420746865206163636f756e74206d757374206265206569746865722062655d01636f6e7665727469626c6520746f20612076616c696461746f72204944207573696e672074686520636861696e2773207479706963616c2061646472657373696e672073797374656d20287468697320757375616c6c7951016d65616e73206265696e67206120636f6e74726f6c6c6572206163636f756e7429206f72206469726563746c7920636f6e7665727469626c6520696e746f20612076616c696461746f722049442028776869636894757375616c6c79206d65616e73206265696e672061207374617368206163636f756e74292e0034232320436f6d706c65786974793d012d20604f2831296020696e206e756d626572206f66206b65792074797065732e2041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f6698202060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e79040c5874616e676c655f746573746e65745f72756e74696d65186f70617175652c53657373696f6e4b65797300000c011062616265dd0201c43c42616265206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c696300011c6772616e647061a801d03c4772616e647061206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c6963000124696d5f6f6e6c696e655d0101d43c496d4f6e6c696e65206173202463726174653a3a426f756e64546f52756e74696d654170705075626c69633e3a3a5075626c696300007d040c3c70616c6c65745f74726561737572791870616c6c65741043616c6c0804540004490001182c7370656e645f6c6f63616c080118616d6f756e746d01013c42616c616e63654f663c542c20493e00012c62656e6566696369617279c50201504163636f756e7449644c6f6f6b75704f663c543e000344b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e0045014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c656173742060616d6f756e74602e002c2323232044657461696c7345014e4f54453a20466f72207265636f72642d6b656570696e6720707572706f7365732c207468652070726f706f736572206973206465656d656420746f206265206571756976616c656e7420746f207468653062656e65666963696172792e003823232320506172616d657465727341012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602ee82d206062656e6566696369617279603a205468652064657374696e6174696f6e206163636f756e7420666f7220746865207472616e736665722e00242323204576656e747300b4456d697473205b604576656e743a3a5370656e64417070726f766564605d206966207375636365737366756c2e3c72656d6f76655f617070726f76616c04012c70726f706f73616c5f69646902013450726f706f73616c496e6465780004542d01466f72636520612070726576696f75736c7920617070726f7665642070726f706f73616c20746f2062652072656d6f7665642066726f6d2074686520617070726f76616c2071756575652e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c7300c0546865206f726967696e616c206465706f7369742077696c6c206e6f206c6f6e6765722062652072657475726e65642e003823232320506172616d6574657273a02d206070726f706f73616c5f6964603a2054686520696e646578206f6620612070726f706f73616c003823232320436f6d706c6578697479ac2d204f2841292077686572652060416020697320746865206e756d626572206f6620617070726f76616c730028232323204572726f727345012d205b604572726f723a3a50726f706f73616c4e6f74417070726f766564605d3a20546865206070726f706f73616c5f69646020737570706c69656420776173206e6f7420666f756e6420696e2074686551012020617070726f76616c2071756575652c20692e652e2c207468652070726f706f73616c20686173206e6f74206265656e20617070726f7665642e205468697320636f756c6420616c736f206d65616e207468655901202070726f706f73616c20646f6573206e6f7420657869737420616c746f6765746865722c2074687573207468657265206973206e6f2077617920697420776f756c642068617665206265656e20617070726f766564542020696e2074686520666972737420706c6163652e147370656e6410012861737365745f6b696e64840144426f783c543a3a41737365744b696e643e000118616d6f756e746d010150417373657442616c616e63654f663c542c20493e00012c62656e6566696369617279000178426f783c42656e65666963696172794c6f6f6b75704f663c542c20493e3e00012876616c69645f66726f6d810401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000568b850726f706f736520616e6420617070726f76652061207370656e64206f662074726561737572792066756e64732e00482323204469737061746368204f726967696e001d014d757374206265205b60436f6e6669673a3a5370656e644f726967696e605d207769746820746865206053756363657373602076616c7565206265696e67206174206c65617374550160616d6f756e7460206f66206061737365745f6b696e646020696e20746865206e61746976652061737365742e2054686520616d6f756e74206f66206061737365745f6b696e646020697320636f6e766572746564d4666f7220617373657274696f6e207573696e6720746865205b60436f6e6669673a3a42616c616e6365436f6e766572746572605d2e002823232044657461696c7300490143726561746520616e20617070726f766564207370656e6420666f72207472616e7366657272696e6720612073706563696669632060616d6f756e7460206f66206061737365745f6b696e646020746f2061610164657369676e617465642062656e65666963696172792e20546865207370656e64206d75737420626520636c61696d6564207573696e672074686520607061796f75746020646973706174636861626c652077697468696e74746865205b60436f6e6669673a3a5061796f7574506572696f64605d2e003823232320506172616d657465727315012d206061737365745f6b696e64603a20416e20696e64696361746f72206f662074686520737065636966696320617373657420636c61737320746f206265207370656e742e41012d2060616d6f756e74603a2054686520616d6f756e7420746f206265207472616e736665727265642066726f6d2074686520747265617375727920746f20746865206062656e6566696369617279602eb82d206062656e6566696369617279603a205468652062656e6566696369617279206f6620746865207370656e642e55012d206076616c69645f66726f6d603a2054686520626c6f636b206e756d6265722066726f6d20776869636820746865207370656e642063616e20626520636c61696d65642e2049742063616e20726566657220746f1901202074686520706173742069662074686520726573756c74696e67207370656e6420686173206e6f74207965742065787069726564206163636f7264696e6720746f20746865450120205b60436f6e6669673a3a5061796f7574506572696f64605d2e20496620604e6f6e65602c20746865207370656e642063616e20626520636c61696d656420696d6d6564696174656c792061667465722c2020617070726f76616c2e00242323204576656e747300c8456d697473205b604576656e743a3a41737365745370656e64417070726f766564605d206966207375636365737366756c2e187061796f7574040114696e6465781001285370656e64496e64657800064c38436c61696d2061207370656e642e00482323204469737061746368204f726967696e00384d757374206265207369676e6564002823232044657461696c730055015370656e6473206d75737420626520636c61696d65642077697468696e20736f6d652074656d706f72616c20626f756e64732e2041207370656e64206d617920626520636c61696d65642077697468696e206f6e65d45b60436f6e6669673a3a5061796f7574506572696f64605d2066726f6d20746865206076616c69645f66726f6d6020626c6f636b2e5501496e2063617365206f662061207061796f7574206661696c7572652c20746865207370656e6420737461747573206d75737420626520757064617465642077697468207468652060636865636b5f73746174757360dc646973706174636861626c65206265666f7265207265747279696e672077697468207468652063757272656e742066756e6374696f6e2e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e74730090456d697473205b604576656e743a3a50616964605d206966207375636365737366756c2e30636865636b5f737461747573040114696e6465781001285370656e64496e64657800074c2901436865636b2074686520737461747573206f6620746865207370656e6420616e642072656d6f76652069742066726f6d207468652073746f726167652069662070726f6365737365642e00482323204469737061746368204f726967696e003c4d757374206265207369676e65642e002823232044657461696c730001015468652073746174757320636865636b20697320612070726572657175697369746520666f72207265747279696e672061206661696c6564207061796f75742e490149662061207370656e64206861732065697468657220737563636565646564206f7220657870697265642c2069742069732072656d6f7665642066726f6d207468652073746f726167652062792074686973ec66756e6374696f6e2e20496e207375636820696e7374616e6365732c207472616e73616374696f6e20666565732061726520726566756e6465642e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300f8456d697473205b604576656e743a3a5061796d656e744661696c6564605d20696620746865207370656e64207061796f757420686173206661696c65642e0101456d697473205b604576656e743a3a5370656e6450726f636573736564605d20696620746865207370656e64207061796f75742068617320737563636565642e28766f69645f7370656e64040114696e6465781001285370656e64496e6465780008407c566f69642070726576696f75736c7920617070726f766564207370656e642e00482323204469737061746368204f726967696e00844d757374206265205b60436f6e6669673a3a52656a6563744f726967696e605d2e002823232044657461696c73001d0141207370656e6420766f6964206973206f6e6c7920706f737369626c6520696620746865207061796f757420686173206e6f74206265656e20617474656d70746564207965742e003823232320506172616d65746572736c2d2060696e646578603a20546865207370656e6420696e6465782e00242323204576656e747300c0456d697473205b604576656e743a3a41737365745370656e64566f69646564605d206966207375636365737366756c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e810404184f7074696f6e04045401300108104e6f6e6500000010536f6d65040030000001000085040c3c70616c6c65745f626f756e746965731870616c6c65741043616c6c0804540004490001243870726f706f73655f626f756e747908011476616c75656d01013c42616c616e63654f663c542c20493e00012c6465736372697074696f6e38011c5665633c75383e0000305450726f706f73652061206e657720626f756e74792e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0051015061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c206173510160446174614465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e2049742077696c6c20626520756e72657365727665642075706f6e20617070726f76616c2c646f7220736c6173686564207768656e2072656a65637465642e00f82d206063757261746f72603a205468652063757261746f72206163636f756e742077686f6d2077696c6c206d616e616765207468697320626f756e74792e642d2060666565603a205468652063757261746f72206665652e25012d206076616c7565603a2054686520746f74616c207061796d656e7420616d6f756e74206f66207468697320626f756e74792c2063757261746f722066656520696e636c756465642ec02d20606465736372697074696f6e603a20546865206465736372697074696f6e206f66207468697320626f756e74792e38617070726f76655f626f756e7479040124626f756e74795f69646902012c426f756e7479496e64657800011c5d01417070726f7665206120626f756e74792070726f706f73616c2e2041742061206c617465722074696d652c2074686520626f756e74792077696c6c2062652066756e64656420616e64206265636f6d6520616374697665a8616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e3c70726f706f73655f63757261746f720c0124626f756e74795f69646902012c426f756e7479496e64657800011c63757261746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013c42616c616e63654f663c542c20493e0002189450726f706f736520612063757261746f7220746f20612066756e64656420626f756e74792e00a44d6179206f6e6c792062652063616c6c65642066726f6d2060543a3a5370656e644f726967696e602e0034232320436f6d706c65786974791c2d204f2831292e40756e61737369676e5f63757261746f72040124626f756e74795f69646902012c426f756e7479496e6465780003447c556e61737369676e2063757261746f722066726f6d206120626f756e74792e001d01546869732066756e6374696f6e2063616e206f6e6c792062652063616c6c656420627920746865206052656a6563744f726967696e602061207369676e6564206f726967696e2e003d01496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e602c20776520617373756d652074686174207468652063757261746f7220697331016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c2077652077696c6c20736c617368207468652063757261746f72207768656e20706f737369626c652e006101496620746865206f726967696e206973207468652063757261746f722c2077652074616b6520746869732061732061207369676e20746865792061726520756e61626c6520746f20646f207468656972206a6f6220616e645d01746865792077696c6c696e676c7920676976652075702e20576520636f756c6420736c617368207468656d2c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f207265636f76657220746865697235016465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966206974206973206162757365642e29005d0146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e6520696620616e64206f6e6c79206966207468652063757261746f722069732022696e616374697665222e205468697320616c6c6f77736101616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f7574207468617420612063757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e64390177652073686f756c64207069636b2061206e65772063757261746f722e20496e20746869732063617365207468652063757261746f722073686f756c6420616c736f20626520736c61736865642e0034232320436f6d706c65786974791c2d204f2831292e386163636570745f63757261746f72040124626f756e74795f69646902012c426f756e7479496e64657800041c94416363657074207468652063757261746f7220726f6c6520666f72206120626f756e74792e290141206465706f7369742077696c6c2062652072657365727665642066726f6d2063757261746f7220616e6420726566756e642075706f6e207375636365737366756c207061796f75742e00904d6179206f6e6c792062652063616c6c65642066726f6d207468652063757261746f722e0034232320436f6d706c65786974791c2d204f2831292e3061776172645f626f756e7479080124626f756e74795f69646902012c426f756e7479496e64657800012c62656e6566696369617279c50201504163636f756e7449644c6f6f6b75704f663c543e0005285901417761726420626f756e747920746f20612062656e6566696369617279206163636f756e742e205468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647338616674657220612064656c61792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f2061776172642e19012d206062656e6566696369617279603a205468652062656e6566696369617279206163636f756e742077686f6d2077696c6c207265636569766520746865207061796f75742e0034232320436f6d706c65786974791c2d204f2831292e30636c61696d5f626f756e7479040124626f756e74795f69646902012c426f756e7479496e646578000620ec436c61696d20746865207061796f75742066726f6d20616e206177617264656420626f756e7479206166746572207061796f75742064656c61792e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652062656e6566696369617279206f66207468697320626f756e74792e00882d2060626f756e74795f6964603a20426f756e747920494420746f20636c61696d2e0034232320436f6d706c65786974791c2d204f2831292e30636c6f73655f626f756e7479040124626f756e74795f69646902012c426f756e7479496e646578000724390143616e63656c20612070726f706f736564206f722061637469766520626f756e74792e20416c6c207468652066756e64732077696c6c2062652073656e7420746f20747265617375727920616e64cc7468652063757261746f72206465706f7369742077696c6c20626520756e726573657276656420696620706f737369626c652e00c84f6e6c792060543a3a52656a6563744f726967696e602069732061626c6520746f2063616e63656c206120626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f2063616e63656c2e0034232320436f6d706c65786974791c2d204f2831292e50657874656e645f626f756e74795f657870697279080124626f756e74795f69646902012c426f756e7479496e64657800011872656d61726b38011c5665633c75383e000824ac457874656e6420746865206578706972792074696d65206f6620616e2061637469766520626f756e74792e001501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f66207468697320626f756e74792e008c2d2060626f756e74795f6964603a20426f756e747920494420746f20657874656e642e8c2d206072656d61726b603a206164646974696f6e616c20696e666f726d6174696f6e2e0034232320436f6d706c65786974791c2d204f2831292e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e89040c5470616c6c65745f6368696c645f626f756e746965731870616c6c65741043616c6c04045400011c406164645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800011476616c75656d01013042616c616e63654f663c543e00012c6465736372697074696f6e38011c5665633c75383e00004c5c4164642061206e6577206368696c642d626f756e74792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f6620706172656e74dc626f756e747920616e642074686520706172656e7420626f756e7479206d75737420626520696e2022616374697665222073746174652e0005014368696c642d626f756e74792067657473206164646564207375636365737366756c6c7920262066756e642067657473207472616e736665727265642066726f6d0901706172656e7420626f756e747920746f206368696c642d626f756e7479206163636f756e742c20696620706172656e7420626f756e74792068617320656e6f7567686c66756e64732c20656c7365207468652063616c6c206661696c732e000d01557070657220626f756e6420746f206d6178696d756d206e756d626572206f662061637469766520206368696c6420626f756e7469657320746861742063616e206265a8616464656420617265206d616e61676564207669612072756e74696d6520747261697420636f6e666967985b60436f6e6669673a3a4d61784163746976654368696c64426f756e7479436f756e74605d2e0001014966207468652063616c6c20697320737563636573732c2074686520737461747573206f66206368696c642d626f756e7479206973207570646174656420746f20224164646564222e004d012d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e747920666f72207768696368206368696c642d626f756e7479206973206265696e672061646465642eb02d206076616c7565603a2056616c756520666f7220657865637574696e67207468652070726f706f73616c2edc2d20606465736372697074696f6e603a2054657874206465736372697074696f6e20666f7220746865206368696c642d626f756e74792e3c70726f706f73655f63757261746f72100140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e64657800011c63757261746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00010c6665656d01013042616c616e63654f663c543e00013ca050726f706f73652063757261746f7220666f722066756e646564206368696c642d626f756e74792e000d01546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652063757261746f72206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e20224164646564222073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6405017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202243757261746f7250726f706f73656422206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792eb42d206063757261746f72603a2041646472657373206f66206368696c642d626f756e74792063757261746f722eec2d2060666565603a207061796d656e742066656520746f206368696c642d626f756e74792063757261746f7220666f7220657865637574696f6e2e386163636570745f63757261746f72080140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e64657800024cb4416363657074207468652063757261746f7220726f6c6520666f7220746865206368696c642d626f756e74792e00f4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265207468652063757261746f72206f662074686973346368696c642d626f756e74792e00ec41206465706f7369742077696c6c2062652072657365727665642066726f6d207468652063757261746f7220616e6420726566756e642075706f6e887375636365737366756c207061796f7574206f722063616e63656c6c6174696f6e2e00f846656520666f722063757261746f722069732064656475637465642066726f6d2063757261746f7220666565206f6620706172656e7420626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e000d014368696c642d626f756e7479206d75737420626520696e202243757261746f7250726f706f736564222073746174652c20666f722070726f63657373696e6720746865090163616c6c2e20416e64207374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202241637469766522206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e40756e61737369676e5f63757261746f72080140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e64657800038894556e61737369676e2063757261746f722066726f6d2061206368696c642d626f756e74792e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c2063616e20626520656974686572206052656a6563744f726967696e602c206f72dc7468652063757261746f72206f662074686520706172656e7420626f756e74792c206f7220616e79207369676e6564206f726967696e2e00f8466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e20616e6420746865206368696c642d626f756e7479010163757261746f722c20706172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f7220746869732063616c6c20746f0901776f726b2e20576520616c6c6f77206368696c642d626f756e74792063757261746f7220616e6420543a3a52656a6563744f726967696e20746f2065786563757465c8746869732063616c6c20697272657370656374697665206f662074686520706172656e7420626f756e74792073746174652e00dc496620746869732066756e6374696f6e2069732063616c6c656420627920746865206052656a6563744f726967696e60206f72207468650501706172656e7420626f756e74792063757261746f722c20776520617373756d65207468617420746865206368696c642d626f756e74792063757261746f722069730d016d616c6963696f7573206f7220696e6163746976652e204173206120726573756c742c206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e000501496620746865206f726967696e20697320746865206368696c642d626f756e74792063757261746f722c2077652074616b6520746869732061732061207369676e09017468617420746865792061726520756e61626c6520746f20646f207468656972206a6f622c20616e64206172652077696c6c696e676c7920676976696e672075702e0901576520636f756c6420736c61736820746865206465706f7369742c2062757420666f72206e6f7720776520616c6c6f77207468656d20746f20756e7265736572766511017468656972206465706f73697420616e64206578697420776974686f75742069737375652e20285765206d61792077616e7420746f206368616e67652074686973206966386974206973206162757365642e2900050146696e616c6c792c20746865206f726967696e2063616e20626520616e796f6e652069666620746865206368696c642d626f756e74792063757261746f72206973090122696e616374697665222e204578706972792075706461746520647565206f6620706172656e7420626f756e7479206973207573656420746f20657374696d6174659c696e616374697665207374617465206f66206368696c642d626f756e74792063757261746f722e000d015468697320616c6c6f777320616e796f6e6520696e2074686520636f6d6d756e69747920746f2063616c6c206f757420746861742061206368696c642d626f756e7479090163757261746f72206973206e6f7420646f696e67207468656972206475652064696c6967656e63652c20616e642077652073686f756c64207069636b2061206e6577f86f6e652e20496e2074686973206361736520746865206368696c642d626f756e74792063757261746f72206465706f73697420697320736c61736865642e0001015374617465206f66206368696c642d626f756e7479206973206d6f76656420746f204164646564207374617465206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e4861776172645f6368696c645f626f756e74790c0140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e64657800012c62656e6566696369617279c50201504163636f756e7449644c6f6f6b75704f663c543e000444904177617264206368696c642d626f756e747920746f20612062656e65666963696172792e00f85468652062656e65666963696172792077696c6c2062652061626c6520746f20636c61696d207468652066756e647320616674657220612064656c61792e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652074686520706172656e742063757261746f72206f727463757261746f72206f662074686973206368696c642d626f756e74792e001101506172656e7420626f756e7479206d75737420626520696e206163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f14776f726b2e0009014368696c642d626f756e7479206d75737420626520696e206163746976652073746174652c20666f722070726f63657373696e67207468652063616c6c2e20416e6411017374617465206f66206368696c642d626f756e7479206973206d6f76656420746f202250656e64696e675061796f757422206f6e207375636365737366756c2063616c6c2c636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e942d206062656e6566696369617279603a2042656e6566696369617279206163636f756e742e48636c61696d5f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e6465780005400501436c61696d20746865207061796f75742066726f6d20616e2061776172646564206368696c642d626f756e7479206166746572207061796f75742064656c61792e00ec546865206469737061746368206f726967696e20666f7220746869732063616c6c206d617920626520616e79207369676e6564206f726967696e2e00050143616c6c20776f726b7320696e646570656e64656e74206f6620706172656e7420626f756e74792073746174652c204e6f206e65656420666f7220706172656e7474626f756e747920746f20626520696e206163746976652073746174652e0011015468652042656e65666963696172792069732070616964206f757420776974682061677265656420626f756e74792076616c75652e2043757261746f7220666565206973947061696420262063757261746f72206465706f73697420697320756e72657365727665642e0005014368696c642d626f756e7479206d75737420626520696e202250656e64696e675061796f7574222073746174652c20666f722070726f63657373696e6720746865fc63616c6c2e20416e6420696e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e6c7375636365737366756c2063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e48636c6f73655f6368696c645f626f756e7479080140706172656e745f626f756e74795f69646902012c426f756e7479496e64657800013c6368696c645f626f756e74795f69646902012c426f756e7479496e646578000658110143616e63656c20612070726f706f736564206f7220616374697665206368696c642d626f756e74792e204368696c642d626f756e7479206163636f756e742066756e64730901617265207472616e7366657272656420746f20706172656e7420626f756e7479206163636f756e742e20546865206368696c642d626f756e74792063757261746f72986465706f736974206d617920626520756e726573657276656420696620706f737369626c652e000901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652065697468657220706172656e742063757261746f72206f724860543a3a52656a6563744f726967696e602e00f0496620746865207374617465206f66206368696c642d626f756e74792069732060416374697665602c2063757261746f72206465706f7369742069732c756e72657365727665642e00f4496620746865207374617465206f66206368696c642d626f756e7479206973206050656e64696e675061796f7574602c2063616c6c206661696c7320267872657475726e73206050656e64696e675061796f757460206572726f722e000d01466f7220746865206f726967696e206f74686572207468616e20543a3a52656a6563744f726967696e2c20706172656e7420626f756e7479206d75737420626520696ef06163746976652073746174652c20666f722074686973206368696c642d626f756e74792063616c6c20746f20776f726b2e20466f72206f726967696e90543a3a52656a6563744f726967696e20657865637574696f6e20697320666f726365642e000101496e7374616e6365206f66206368696c642d626f756e74792069732072656d6f7665642066726f6d20746865207374617465206f6e207375636365737366756c4063616c6c20636f6d706c6574696f6e2e00b42d2060706172656e745f626f756e74795f6964603a20496e646578206f6620706172656e7420626f756e74792eac2d20606368696c645f626f756e74795f6964603a20496e646578206f66206368696c6420626f756e74792e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d040c4070616c6c65745f626167735f6c6973741870616c6c65741043616c6c08045400044900010c1472656261670401286469736c6f6361746564c50201504163636f756e7449644c6f6f6b75704f663c543e00002859014465636c617265207468617420736f6d6520606469736c6f636174656460206163636f756e74206861732c207468726f7567682072657761726473206f722070656e616c746965732c2073756666696369656e746c7951016368616e676564206974732073636f726520746861742069742073686f756c642070726f7065726c792066616c6c20696e746f206120646966666572656e7420626167207468616e206974732063757272656e74106f6e652e001d01416e796f6e652063616e2063616c6c20746869732066756e6374696f6e2061626f757420616e7920706f74656e7469616c6c79206469736c6f6361746564206163636f756e742e00490157696c6c20616c7761797320757064617465207468652073746f7265642073636f7265206f6620606469736c6f63617465646020746f2074686520636f72726563742073636f72652c206261736564206f6e406053636f726550726f7669646572602e00d4496620606469736c6f63617465646020646f6573206e6f74206578697374732c2069742072657475726e7320616e206572726f722e3c7075745f696e5f66726f6e745f6f6604011c6c696768746572c50201504163636f756e7449644c6f6f6b75704f663c543e000128d04d6f7665207468652063616c6c65722773204964206469726563746c7920696e2066726f6e74206f6620606c696768746572602e005901546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642063616e206f6e6c792062652063616c6c656420627920746865204964206f663501746865206163636f756e7420676f696e6720696e2066726f6e74206f6620606c696768746572602e2046656520697320706179656420627920746865206f726967696e20756e64657220616c6c3863697263756d7374616e6365732e00384f6e6c7920776f726b732069663a00942d20626f7468206e6f646573206172652077697468696e207468652073616d65206261672cd02d20616e6420606f726967696e602068617320612067726561746572206053636f726560207468616e20606c696768746572602e547075745f696e5f66726f6e745f6f665f6f7468657208011c68656176696572c50201504163636f756e7449644c6f6f6b75704f663c543e00011c6c696768746572c50201504163636f756e7449644c6f6f6b75704f663c543e00020c110153616d65206173205b6050616c6c65743a3a7075745f696e5f66726f6e745f6f66605d2c206275742069742063616e2062652063616c6c656420627920616e796f6e652e00c8466565206973207061696420627920746865206f726967696e20756e64657220616c6c2063697263756d7374616e6365732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e91040c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c65741043616c6c040454000168106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c496400002845015374616b652066756e64732077697468206120706f6f6c2e2054686520616d6f756e7420746f20626f6e64206973207472616e736665727265642066726f6d20746865206d656d62657220746f20746865dc706f6f6c73206163636f756e7420616e6420696d6d6564696174656c7920696e637265617365732074686520706f6f6c7320626f6e642e001823204e6f746500cc2a20416e206163636f756e742063616e206f6e6c792062652061206d656d626572206f6620612073696e676c6520706f6f6c2ed82a20416e206163636f756e742063616e6e6f74206a6f696e207468652073616d6520706f6f6c206d756c7469706c652074696d65732e41012a20546869732063616c6c2077696c6c202a6e6f742a206475737420746865206d656d626572206163636f756e742c20736f20746865206d656d626572206d7573742068617665206174206c65617374c82020606578697374656e7469616c206465706f736974202b20616d6f756e746020696e207468656972206163636f756e742ed02a204f6e6c79206120706f6f6c2077697468205b60506f6f6c53746174653a3a4f70656e605d2063616e206265206a6f696e656428626f6e645f657874726104011465787472619504015c426f6e6445787472613c42616c616e63654f663c543e3e00011c4501426f6e642060657874726160206d6f72652066756e64732066726f6d20606f726967696e6020696e746f2074686520706f6f6c20746f207768696368207468657920616c72656164792062656c6f6e672e0049014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d206569746865722074686520667265652062616c616e6365206f6620746865206163636f756e742c206f662066726f6d207468659c616363756d756c6174656420726577617264732c20736565205b60426f6e644578747261605d2e003d01426f6e64696e672065787472612066756e647320696d706c69657320616e206175746f6d61746963207061796f7574206f6620616c6c2070656e64696e6720726577617264732061732077656c6c2e09015365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f6620606f7468657260206d656d626572732e30636c61696d5f7061796f757400022055014120626f6e646564206d656d6265722063616e20757365207468697320746f20636c61696d207468656972207061796f7574206261736564206f6e20746865207265776172647320746861742074686520706f6f6c610168617320616363756d756c617465642073696e6365207468656972206c61737420636c61696d6564207061796f757420284f522073696e6365206a6f696e696e6720696620746869732069732074686569722066697273743d0174696d6520636c61696d696e672072657761726473292e20546865207061796f75742077696c6c206265207472616e7366657272656420746f20746865206d656d6265722773206163636f756e742e004901546865206d656d6265722077696c6c206561726e20726577617264732070726f2072617461206261736564206f6e20746865206d656d62657273207374616b65207673207468652073756d206f6620746865d06d656d6265727320696e2074686520706f6f6c73207374616b652e205265776172647320646f206e6f742022657870697265222e0041015365652060636c61696d5f7061796f75745f6f746865726020746f20636c61696d2072657761726473206f6e20626568616c66206f6620736f6d6520606f746865726020706f6f6c206d656d6265722e18756e626f6e640801386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e00037c4501556e626f6e6420757020746f2060756e626f6e64696e675f706f696e747360206f662074686520606d656d6265725f6163636f756e746027732066756e64732066726f6d2074686520706f6f6c2e2049744501696d706c696369746c7920636f6c6c65637473207468652072657761726473206f6e65206c6173742074696d652c2073696e6365206e6f7420646f696e6720736f20776f756c64206d65616e20736f6d656c7265776172647320776f756c6420626520666f726665697465642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463682e005d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e205468697320697320726566657265656420746f30202061732061206b69636b2ef42a2054686520706f6f6c2069732064657374726f79696e6720616e6420746865206d656d626572206973206e6f7420746865206465706f7369746f722e55012a2054686520706f6f6c2069732064657374726f79696e672c20746865206d656d62657220697320746865206465706f7369746f7220616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001101232320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463682028692e652e207468652063616c6c657220697320616c736f2074686548606d656d6265725f6163636f756e7460293a00882a205468652063616c6c6572206973206e6f7420746865206465706f7369746f722e55012a205468652063616c6c657220697320746865206465706f7369746f722c2074686520706f6f6c2069732064657374726f79696e6720616e64206e6f206f74686572206d656d626572732061726520696e207468651c2020706f6f6c2e001823204e6f7465001d0149662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f20756e626f6e6420776974682074686520706f6f6c206163636f756e742c51015b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c656420746f2074727920616e64206d696e696d697a6520756e6c6f636b696e67206368756e6b732e5901546865205b605374616b696e67496e746572666163653a3a756e626f6e64605d2077696c6c20696d706c696369746c792063616c6c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d5501746f2074727920746f2066726565206368756e6b73206966206e6563657373617279202869652e20696620756e626f756e64207761732063616c6c656420616e64206e6f20756e6c6f636b696e67206368756e6b73610161726520617661696c61626c65292e20486f77657665722c206974206d6179206e6f7420626520706f737369626c6520746f2072656c65617365207468652063757272656e7420756e6c6f636b696e67206368756e6b732c5d01696e20776869636820636173652c2074686520726573756c74206f6620746869732063616c6c2077696c6c206c696b656c792062652074686520604e6f4d6f72654368756e6b7360206572726f722066726f6d207468653c7374616b696e672073797374656d2e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000418550143616c6c206077697468647261775f756e626f6e6465646020666f722074686520706f6f6c73206163636f756e742e20546869732063616c6c2063616e206265206d61646520627920616e79206163636f756e742e004101546869732069732075736566756c2069662074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b7320746f2063616c6c2060756e626f6e64602c20616e6420736f6d65610163616e20626520636c6561726564206279207769746864726177696e672e20496e2074686520636173652074686572652061726520746f6f206d616e7920756e6c6f636b696e67206368756e6b732c2074686520757365725101776f756c642070726f6261626c792073656520616e206572726f72206c696b6520604e6f4d6f72654368756e6b736020656d69747465642066726f6d20746865207374616b696e672073797374656d207768656e5c7468657920617474656d707420746f20756e626f6e642e4477697468647261775f756e626f6e6465640801386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e0001486e756d5f736c617368696e675f7370616e7310010c7533320005585501576974686472617720756e626f6e6465642066756e64732066726f6d20606d656d6265725f6163636f756e74602e204966206e6f20626f6e6465642066756e64732063616e20626520756e626f6e6465642c20616e486572726f722069732072657475726e65642e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00a82320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463680009012a2054686520706f6f6c20697320696e2064657374726f79206d6f646520616e642074686520746172676574206973206e6f7420746865206465706f7369746f722e31012a205468652074617267657420697320746865206465706f7369746f7220616e6420746865792061726520746865206f6e6c79206d656d62657220696e207468652073756220706f6f6c732e0d012a2054686520706f6f6c20697320626c6f636b656420616e64207468652063616c6c6572206973206569746865722074686520726f6f74206f7220626f756e6365722e00982320436f6e646974696f6e7320666f72207065726d697373696f6e656420646973706174636800e82a205468652063616c6c6572206973207468652074617267657420616e64207468657920617265206e6f7420746865206465706f7369746f722e001823204e6f746500f42d204966207468652074617267657420697320746865206465706f7369746f722c2074686520706f6f6c2077696c6c2062652064657374726f7965642e61012d2049662074686520706f6f6c2068617320616e792070656e64696e6720736c6173682c20776520616c736f2074727920746f20736c61736820746865206d656d626572206265666f7265206c657474696e67207468656d5d0177697468647261772e20546869732063616c63756c6174696f6e206164647320736f6d6520776569676874206f7665726865616420616e64206973206f6e6c7920646566656e736976652e20496e207265616c6974792c5501706f6f6c20736c6173686573206d7573742068617665206265656e20616c7265616479206170706c69656420766961207065726d697373696f6e6c657373205b6043616c6c3a3a6170706c795f736c617368605d2e18637265617465100118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c50201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c50201504163636f756e7449644c6f6f6b75704f663c543e000644744372656174652061206e65772064656c65676174696f6e20706f6f6c2e002c2320417267756d656e74730055012a2060616d6f756e7460202d2054686520616d6f756e74206f662066756e647320746f2064656c656761746520746f2074686520706f6f6c2e205468697320616c736f2061637473206f66206120736f7274206f664d0120206465706f7369742073696e63652074686520706f6f6c732063726561746f722063616e6e6f742066756c6c7920756e626f6e642066756e647320756e74696c2074686520706f6f6c206973206265696e6730202064657374726f7965642e51012a2060696e64657860202d204120646973616d626967756174696f6e20696e64657820666f72206372656174696e6720746865206163636f756e742e204c696b656c79206f6e6c792075736566756c207768656ec020206372656174696e67206d756c7469706c6520706f6f6c7320696e207468652073616d652065787472696e7369632ed42a2060726f6f7460202d20546865206163636f756e7420746f20736574206173205b60506f6f6c526f6c65733a3a726f6f74605d2e0d012a20606e6f6d696e61746f7260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a6e6f6d696e61746f72605d2efc2a2060626f756e63657260202d20546865206163636f756e7420746f2073657420617320746865205b60506f6f6c526f6c65733a3a626f756e636572605d2e001823204e6f7465006101496e206164646974696f6e20746f2060616d6f756e74602c207468652063616c6c65722077696c6c207472616e7366657220746865206578697374656e7469616c206465706f7369743b20736f207468652063616c6c65720d016e656564732061742068617665206174206c656173742060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652e4c6372656174655f776974685f706f6f6c5f6964140118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c50201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c50201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000718ec4372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c206964002c2320417267756d656e7473009873616d6520617320606372656174656020776974682074686520696e636c7573696f6e206f66782a2060706f6f6c5f696460202d2060412076616c696420506f6f6c49642e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f7273350201445665633c543a3a4163636f756e7449643e0008307c4e6f6d696e617465206f6e20626568616c66206f662074686520706f6f6c2e004501546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6c28726f6f7420726f6c652e00490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e001823204e6f7465005d01496e206164646974696f6e20746f20612060726f6f7460206f7220606e6f6d696e61746f726020726f6c65206f6620606f726967696e602c20706f6f6c2773206465706f7369746f72206e6565647320746f2068617665f86174206c6561737420606465706f7369746f725f6d696e5f626f6e646020696e2074686520706f6f6c20746f207374617274206e6f6d696e6174696e672e247365745f737461746508011c706f6f6c5f6964100118506f6f6c496400011473746174651d010124506f6f6c5374617465000928745365742061206e657720737461746520666f722074686520706f6f6c2e0055014966206120706f6f6c20697320616c726561647920696e20746865206044657374726f79696e67602073746174652c207468656e20756e646572206e6f20636f6e646974696f6e2063616e20697473207374617465346368616e676520616761696e2e00c0546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206569746865723a00dc312e207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686520706f6f6c2c5d01322e2069662074686520706f6f6c20636f6e646974696f6e7320746f206265206f70656e20617265204e4f54206d6574202861732064657363726962656420627920606f6b5f746f5f62655f6f70656e60292c20616e6439012020207468656e20746865207374617465206f662074686520706f6f6c2063616e206265207065726d697373696f6e6c6573736c79206368616e67656420746f206044657374726f79696e67602e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a10805365742061206e6577206d6574616461746120666f722074686520706f6f6c2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e65642062792074686520626f756e6365722c206f722074686520726f6f7420726f6c65206f662074686514706f6f6c2e2c7365745f636f6e666967731801346d696e5f6a6f696e5f626f6e6499040158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e6499040158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c739d040134436f6e6669674f703c7533323e00012c6d61785f6d656d626572739d040134436f6e6669674f703c7533323e0001506d61785f6d656d626572735f7065725f706f6f6c9d040134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6ea1040144436f6e6669674f703c50657262696c6c3e000b2c410155706461746520636f6e66696775726174696f6e7320666f7220746865206e6f6d696e6174696f6e20706f6f6c732e20546865206f726967696e20666f7220746869732063616c6c206d757374206265605b60436f6e6669673a3a41646d696e4f726967696e605d2e002c2320417267756d656e747300a02a20606d696e5f6a6f696e5f626f6e6460202d20536574205b604d696e4a6f696e426f6e64605d2eb02a20606d696e5f6372656174655f626f6e6460202d20536574205b604d696e437265617465426f6e64605d2e842a20606d61785f706f6f6c7360202d20536574205b604d6178506f6f6c73605d2ea42a20606d61785f6d656d6265727360202d20536574205b604d6178506f6f6c4d656d62657273605d2ee42a20606d61785f6d656d626572735f7065725f706f6f6c60202d20536574205b604d6178506f6f6c4d656d62657273506572506f6f6c605d2ee02a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20536574205b60476c6f62616c4d6178436f6d6d697373696f6e605d2e307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f74a5040158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f72a5040158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e636572a5040158436f6e6669674f703c543a3a4163636f756e7449643e000c1c745570646174652074686520726f6c6573206f662074686520706f6f6c2e003d0154686520726f6f7420697320746865206f6e6c7920656e7469747920746861742063616e206368616e676520616e79206f662074686520726f6c65732c20696e636c7564696e6720697473656c662cb86578636c7564696e6720746865206465706f7369746f722c2077686f2063616e206e65766572206368616e67652e005101497420656d69747320616e206576656e742c206e6f74696679696e6720554973206f662074686520726f6c65206368616e67652e2054686973206576656e742069732071756974652072656c6576616e7420746f1d016d6f737420706f6f6c206d656d6265727320616e6420746865792073686f756c6420626520696e666f726d6564206f66206368616e67657320746f20706f6f6c20726f6c65732e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d40704368696c6c206f6e20626568616c66206f662074686520706f6f6c2e004101546865206469737061746368206f726967696e206f6620746869732063616c6c2063616e206265207369676e65642062792074686520706f6f6c206e6f6d696e61746f72206f722074686520706f6f6ca0726f6f7420726f6c652c2073616d65206173205b6050616c6c65743a3a6e6f6d696e617465605d2e004d01556e646572206365727461696e20636f6e646974696f6e732c20746869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79246163636f756e74292e00ac2320436f6e646974696f6e7320666f722061207065726d697373696f6e6c6573732064697370617463683a59012a205768656e20706f6f6c206465706f7369746f7220686173206c657373207468616e20604d696e4e6f6d696e61746f72426f6e6460207374616b65642c206f74686572776973652020706f6f6c206d656d626572735c202061726520756e61626c6520746f20756e626f6e642e009c2320436f6e646974696f6e7320666f72207065726d697373696f6e65642064697370617463683ad82a205468652063616c6c6572206861732061206e6f6d696e61746f72206f7220726f6f7420726f6c65206f662074686520706f6f6c2e490154686973206469726563746c7920666f7277617264207468652063616c6c20746f20746865207374616b696e672070616c6c65742c206f6e20626568616c66206f662074686520706f6f6c20626f6e646564206163636f756e742e40626f6e645f65787472615f6f746865720801186d656d626572c50201504163636f756e7449644c6f6f6b75704f663c543e00011465787472619504015c426f6e6445787472613c42616c616e63654f663c543e3e000e245501606f726967696e6020626f6e64732066756e64732066726f6d206065787472616020666f7220736f6d6520706f6f6c206d656d62657220606d656d6265726020696e746f207468656972207265737065637469766518706f6f6c732e004901606f726967696e602063616e20626f6e642065787472612066756e64732066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473207768656e20606f726967696e203d3d1c6f74686572602e004501496e207468652063617365206f6620606f726967696e20213d206f74686572602c20606f726967696e602063616e206f6e6c7920626f6e642065787472612070656e64696e672072657761726473206f661501606f7468657260206d656d6265727320617373756d696e67207365745f636c61696d5f7065726d697373696f6e20666f722074686520676976656e206d656d626572206973c0605065726d697373696f6e6c657373436f6d706f756e6460206f7220605065726d697373696f6e6c657373416c6c602e507365745f636c61696d5f7065726d697373696f6e0401287065726d697373696f6ea904013c436c61696d5065726d697373696f6e000f1c4901416c6c6f7773206120706f6f6c206d656d62657220746f20736574206120636c61696d207065726d697373696f6e20746f20616c6c6f77206f7220646973616c6c6f77207065726d697373696f6e6c65737360626f6e64696e6720616e64207769746864726177696e672e002c2320417267756d656e747300782a20606f726967696e60202d204d656d626572206f66206120706f6f6c2eb82a20607065726d697373696f6e60202d20546865207065726d697373696f6e20746f206265206170706c6965642e48636c61696d5f7061796f75745f6f746865720401146f74686572000130543a3a4163636f756e7449640010100101606f726967696e602063616e20636c61696d207061796f757473206f6e20736f6d6520706f6f6c206d656d62657220606f7468657260277320626568616c662e005501506f6f6c206d656d62657220606f7468657260206d7573742068617665206120605065726d697373696f6e6c657373576974686472617760206f7220605065726d697373696f6e6c657373416c6c6020636c61696da87065726d697373696f6e20666f7220746869732063616c6c20746f206265207375636365737366756c2e387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001114745365742074686520636f6d6d697373696f6e206f66206120706f6f6c2e5501426f7468206120636f6d6d697373696f6e2070657263656e7461676520616e64206120636f6d6d697373696f6e207061796565206d7573742062652070726f766964656420696e20746865206063757272656e74605d017475706c652e2057686572652061206063757272656e7460206f6620604e6f6e65602069732070726f76696465642c20616e792063757272656e7420636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e004d012d204966206120604e6f6e656020697320737570706c69656420746f20606e65775f636f6d6d697373696f6e602c206578697374696e6720636f6d6d697373696f6e2077696c6c2062652072656d6f7665642e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c0012149453657420746865206d6178696d756d20636f6d6d697373696f6e206f66206120706f6f6c2e0039012d20496e697469616c206d61782063616e2062652073657420746f20616e79206050657262696c6c602c20616e64206f6e6c7920736d616c6c65722076616c75657320746865726561667465722e35012d2043757272656e7420636f6d6d697373696f6e2077696c6c206265206c6f776572656420696e20746865206576656e7420697420697320686967686572207468616e2061206e6577206d6178342020636f6d6d697373696f6e2e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174652901019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001310a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400141464436c61696d2070656e64696e6720636f6d6d697373696f6e2e005d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e6564206279207468652060726f6f746020726f6c65206f662074686520706f6f6c2e2050656e64696e675d01636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e602e20546f74616c2070656e64696e6720636f6d6d697373696f6e78697320726573657420746f207a65726f2e207468652063757272656e742e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c496400151cec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001610cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e00610144657465726d696e65732077686f2063616e20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e204f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6cc869732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e2c6170706c795f736c6173680401386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e001724884170706c7920612070656e64696e6720736c617368206f6e2061206d656d6265722e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e005d015468652070656e64696e6720736c61736820616d6f756e74206f6620746865206d656d626572206d75737420626520657175616c206f72206d6f7265207468616e20604578697374656e7469616c4465706f736974602e5101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792028692e652e20627920616e79206163636f756e74292e2049662074686520657865637574696f6e49016973207375636365737366756c2c2066656520697320726566756e64656420616e642063616c6c6572206d6179206265207265776172646564207769746820612070617274206f662074686520736c6173680d016261736564206f6e20746865205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d20636f6e66696775726174696f6e2e486d6967726174655f64656c65676174696f6e0401386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e0018241d014d696772617465732064656c6567617465642066756e64732066726f6d2074686520706f6f6c206163636f756e7420746f2074686520606d656d6265725f6163636f756e74602e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e002901546869732069732061207065726d697373696f6e2d6c6573732063616c6c20616e6420726566756e647320616e792066656520696620636c61696d206973207375636365737366756c2e005d0149662074686520706f6f6c20686173206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746865207374616b656420746f6b656e73206f6620706f6f6c206d656d62657273290163616e206265206d6f76656420616e642068656c6420696e207468656972206f776e206163636f756e742e20536565205b60616461707465723a3a44656c65676174655374616b65605d786d6967726174655f706f6f6c5f746f5f64656c65676174655f7374616b6504011c706f6f6c5f6964100118506f6f6c4964001924f44d69677261746520706f6f6c2066726f6d205b60616461707465723a3a5374616b655374726174656779547970653a3a5472616e73666572605d20746fa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e0025014661696c7320756e6c657373205b6063726174653a3a70616c6c65743a3a436f6e6669673a3a5374616b6541646170746572605d206973206f6620737472617465677920747970653aa45b60616461707465723a3a5374616b655374726174656779547970653a3a44656c6567617465605d2e004101546869732063616c6c2063616e2062652064697370617463686564207065726d697373696f6e6c6573736c792c20616e6420726566756e647320616e7920666565206966207375636365737366756c2e00490149662074686520706f6f6c2068617320616c7265616479206d6967726174656420746f2064656c65676174696f6e206261736564207374616b696e672c20746869732063616c6c2077696c6c206661696c2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e9504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324426f6e644578747261041c42616c616e6365011801082c4672656542616c616e6365040018011c42616c616e63650000001c52657761726473000100009904085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f7665000200009d04085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f766500020000a104085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f766500020000a504085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f766500020000a904085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000ad040c4070616c6c65745f7363686564756c65721870616c6c65741043616c6c040454000128207363686564756c651001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963b10401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00000470416e6f6e796d6f75736c79207363686564756c652061207461736b2e1863616e63656c0801107768656e300144426c6f636b4e756d626572466f723c543e000114696e64657810010c7533320001049443616e63656c20616e20616e6f6e796d6f75736c79207363686564756c6564207461736b2e387363686564756c655f6e616d656414010869640401205461736b4e616d650001107768656e300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963b10401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000204585363686564756c652061206e616d6564207461736b2e3063616e63656c5f6e616d656404010869640401205461736b4e616d650003047843616e63656c2061206e616d6564207363686564756c6564207461736b2e387363686564756c655f61667465721001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963b10401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000404a8416e6f6e796d6f75736c79207363686564756c652061207461736b20616674657220612064656c61792e507363686564756c655f6e616d65645f616674657214010869640401205461736b4e616d650001146166746572300144426c6f636b4e756d626572466f723c543e0001386d617962655f706572696f646963b10401ac4f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d626572466f723c543e3e3e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000504905363686564756c652061206e616d6564207461736b20616674657220612064656c61792e247365745f72657472790c01107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e00011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0006305901536574206120726574727920636f6e66696775726174696f6e20666f722061207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069742077696c6c5501626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c2069742473756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3c7365745f72657472795f6e616d65640c010869640401205461736b4e616d6500011c726574726965730801087538000118706572696f64300144426c6f636b4e756d626572466f723c543e0007305d01536574206120726574727920636f6e66696775726174696f6e20666f722061206e616d6564207461736b20736f20746861742c20696e206361736520697473207363686564756c65642072756e206661696c732c2069745d0177696c6c20626520726574726965642061667465722060706572696f646020626c6f636b732c20666f72206120746f74616c20616d6f756e74206f66206072657472696573602072657472696573206f7220756e74696c3069742073756363656564732e0055015461736b73207768696368206e65656420746f206265207363686564756c656420666f72206120726574727920617265207374696c6c207375626a65637420746f20776569676874206d65746572696e6720616e6451016167656e64612073706163652c2073616d65206173206120726567756c6172207461736b2e204966206120706572696f646963207461736b206661696c732c2069742077696c6c206265207363686564756c6564906e6f726d616c6c79207768696c6520746865207461736b206973207265747279696e672e0051015461736b73207363686564756c6564206173206120726573756c74206f66206120726574727920666f72206120706572696f646963207461736b2061726520756e6e616d65642c206e6f6e2d706572696f6469633d01636c6f6e6573206f6620746865206f726967696e616c207461736b2e20546865697220726574727920636f6e66696775726174696f6e2077696c6c20626520646572697665642066726f6d207468654d016f726967696e616c207461736b277320636f6e66696775726174696f6e2c206275742077696c6c20686176652061206c6f7765722076616c756520666f72206072656d61696e696e6760207468616e20746865646f726967696e616c2060746f74616c5f72657472696573602e3063616e63656c5f72657472790401107461736b390101785461736b416464726573733c426c6f636b4e756d626572466f723c543e3e000804a852656d6f7665732074686520726574727920636f6e66696775726174696f6e206f662061207461736b2e4863616e63656c5f72657472795f6e616d656404010869640401205461736b4e616d65000904bc43616e63656c2074686520726574727920636f6e66696775726174696f6e206f662061206e616d6564207461736b2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb10404184f7074696f6e0404540139010108104e6f6e6500000010536f6d65040039010000010000b5040c3c70616c6c65745f707265696d6167651870616c6c65741043616c6c040454000114346e6f74655f707265696d616765040114627974657338011c5665633c75383e000010745265676973746572206120707265696d616765206f6e2d636861696e2e00550149662074686520707265696d616765207761732070726576696f75736c79207265717565737465642c206e6f2066656573206f72206465706f73697473206172652074616b656e20666f722070726f766964696e67550174686520707265696d6167652e204f74686572776973652c2061206465706f7369742069732074616b656e2070726f706f7274696f6e616c20746f207468652073697a65206f662074686520707265696d6167652e3c756e6e6f74655f707265696d6167650401106861736834011c543a3a48617368000118dc436c65617220616e20756e72657175657374656420707265696d6167652066726f6d207468652072756e74696d652073746f726167652e00fc496620606c656e602069732070726f76696465642c207468656e2069742077696c6c2062652061206d7563682063686561706572206f7065726174696f6e2e0001012d206068617368603a205468652068617368206f662074686520707265696d61676520746f2062652072656d6f7665642066726f6d207468652073746f72652eb82d20606c656e603a20546865206c656e677468206f662074686520707265696d616765206f66206068617368602e40726571756573745f707265696d6167650401106861736834011c543a3a48617368000210410152657175657374206120707265696d6167652062652075706c6f6164656420746f2074686520636861696e20776974686f757420706179696e6720616e792066656573206f72206465706f736974732e00550149662074686520707265696d6167652072657175657374732068617320616c7265616479206265656e2070726f7669646564206f6e2d636861696e2c20776520756e7265736572766520616e79206465706f7369743901612075736572206d6179206861766520706169642c20616e642074616b652074686520636f6e74726f6c206f662074686520707265696d616765206f7574206f662074686569722068616e64732e48756e726571756573745f707265696d6167650401106861736834011c543a3a4861736800030cbc436c65617220612070726576696f75736c79206d616465207265717565737420666f72206120707265696d6167652e002d014e4f54453a2054484953204d555354204e4f542042452043414c4c4544204f4e20606861736860204d4f52452054494d4553205448414e2060726571756573745f707265696d616765602e38656e737572655f75706461746564040118686173686573c10101305665633c543a3a486173683e00040cc4456e7375726520746861742074686520612062756c6b206f66207072652d696d616765732069732075706772616465642e003d015468652063616c6c65722070617973206e6f20666565206966206174206c6561737420393025206f66207072652d696d616765732077657265207375636365737366756c6c7920757064617465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb9040c3c70616c6c65745f74785f70617573651870616c6c65741043616c6c04045400010814706175736504012466756c6c5f6e616d655101015052756e74696d6543616c6c4e616d654f663c543e00001034506175736520612063616c6c2e00b843616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a50617573654f726967696e605d2ec0456d69747320616e205b604576656e743a3a43616c6c506175736564605d206576656e74206f6e20737563636573732e1c756e70617573650401146964656e745101015052756e74696d6543616c6c4e616d654f663c543e00011040556e2d706175736520612063616c6c2e00c043616e206f6e6c792062652063616c6c6564206279205b60436f6e6669673a3a556e70617573654f726967696e605d2ec8456d69747320616e205b604576656e743a3a43616c6c556e706175736564605d206576656e74206f6e20737563636573732e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ebd040c4070616c6c65745f696d5f6f6e6c696e651870616c6c65741043616c6c04045400010424686561727462656174080124686561727462656174c10401704865617274626561743c426c6f636b4e756d626572466f723c543e3e0001247369676e6174757265c50401bc3c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000c38232320436f6d706c65786974793afc2d20604f284b2960207768657265204b206973206c656e677468206f6620604b6579736020286865617274626561742e76616c696461746f72735f6c656e298820202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b60040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec104084070616c6c65745f696d5f6f6e6c696e6524486561727462656174042c426c6f636b4e756d626572013000100130626c6f636b5f6e756d62657230012c426c6f636b4e756d62657200013473657373696f6e5f696e64657810013053657373696f6e496e64657800013c617574686f726974795f696e64657810012441757468496e64657800013876616c696461746f72735f6c656e10010c7533320000c504104070616c6c65745f696d5f6f6e6c696e651c737232353531392c6170705f73723235353139245369676e6174757265000004000d030148737232353531393a3a5369676e61747572650000c9040c3c70616c6c65745f6964656e746974791870616c6c65741043616c6c040454000158346164645f72656769737472617204011c6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e00001c7841646420612072656769737472617220746f207468652073797374656d2e00fc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060543a3a5265676973747261724f726967696e602e00a82d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e0094456d6974732060526567697374726172416464656460206966207375636365737366756c2e307365745f6964656e74697479040110696e666fcd04016c426f783c543a3a4964656e74697479496e666f726d6174696f6e3e000128290153657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e005501496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7450666f7220746865206e6577206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e008c2d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e0088456d69747320604964656e7469747953657460206966207375636365737366756c2e207365745f7375627304011073756273550501645665633c28543a3a4163636f756e7449642c2044617461293e0002248c53657420746865207375622d6163636f756e7473206f66207468652073656e6465722e0055015061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e65642d01616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e00b02d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e38636c6561725f6964656e746974790003203901436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e00ec5061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564246964656e746974792e0098456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e44726571756573745f6a756467656d656e740801247265675f696e64657869020138526567697374726172496e64657800011c6d61785f6665656d01013042616c616e63654f663c543e00044094526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e0055015061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7418676976656e2e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e001d012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e55012d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a00306060606e6f636f6d70696c65b853656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665650c60606000a4456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e3863616e63656c5f726571756573740401247265675f696e646578100138526567697374726172496e6465780005286843616e63656c20612070726576696f757320726571756573742e00f85061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e003501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520615072656769737465726564206964656e746974792e0045012d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e00ac456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e1c7365745f666565080114696e64657869020138526567697374726172496e64657800010c6665656d01013042616c616e63654f663c543e00061c1901536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e542d2060666565603a20746865206e6577206665652e387365745f6163636f756e745f6964080114696e64657869020138526567697374726172496e64657800010c6e6577c50201504163636f756e7449644c6f6f6b75704f663c543e00071cbc4368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e702d20606e6577603a20746865206e6577206163636f756e742049442e287365745f6669656c6473080114696e64657869020138526567697374726172496e6465780001186669656c6473300129013c543a3a4964656e74697479496e666f726d6174696f6e206173204964656e74697479496e666f726d6174696f6e50726f76696465723e3a3a0a4669656c64734964656e74696669657200081ca853657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74a06f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e00f42d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e0d012d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e4470726f766964655f6a756467656d656e741001247265675f696e64657869020138526567697374726172496e646578000118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e0001246a756467656d656e745d05015c4a756467656d656e743c42616c616e63654f663c543e3e0001206964656e7469747934011c543a3a4861736800093cb850726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e005501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74b06f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e0021012d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e55012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e49012d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e5d012d20606964656e74697479603a205468652068617368206f6620746865205b604964656e74697479496e666f726d6174696f6e50726f7669646572605d20666f72207468617420746865206a756467656d656e742069732c202070726f76696465642e00b04e6f74653a204a756467656d656e747320646f206e6f74206170706c7920746f206120757365726e616d652e0094456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e346b696c6c5f6964656e74697479040118746172676574c50201504163636f756e7449644c6f6f6b75704f663c543e000a30410152656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e0061015061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c6564206279450160536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564806d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e00f8546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206d617463682060543a3a466f7263654f726967696e602e0055012d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e747420207769746820612072656769737465726564206964656e746974792e0094456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e1c6164645f73756208010c737562c50201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d904011044617461000b1cac4164642074686520676976656e206163636f756e7420746f207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656e616d655f73756208010c737562c50201504163636f756e7449644c6f6f6b75704f663c543e00011064617461d904011044617461000c10cc416c74657220746865206173736f636961746564206e616d65206f662074686520676976656e207375622d6163636f756e742e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e2872656d6f76655f73756204010c737562c50201504163636f756e7449644c6f6f6b75704f663c543e000d1cc052656d6f76652074686520676976656e206163636f756e742066726f6d207468652073656e646572277320737562732e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c20626520726570617472696174656438746f207468652073656e6465722e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652061207265676973746572656458737562206964656e74697479206f662060737562602e20717569745f737562000e288c52656d6f7665207468652073656e6465722061732061207375622d6163636f756e742e005d015061796d656e743a2042616c616e636520726573657276656420627920612070726576696f757320607365745f73756273602063616c6c20666f72206f6e65207375622077696c6c206265207265706174726961746564b4746f207468652073656e64657220282a6e6f742a20746865206f726967696e616c206465706f7369746f72292e006101546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d7573742068617665206120726567697374657265643c73757065722d6964656e746974792e0045014e4f54453a20546869732073686f756c64206e6f74206e6f726d616c6c7920626520757365642c206275742069732070726f766964656420696e207468652063617365207468617420746865206e6f6e2d1101636f6e74726f6c6c6572206f6620616e206163636f756e74206973206d616c6963696f75736c7920726567697374657265642061732061207375622d6163636f756e742e586164645f757365726e616d655f617574686f726974790c0124617574686f72697479c50201504163636f756e7449644c6f6f6b75704f663c543e00011873756666697838011c5665633c75383e000128616c6c6f636174696f6e10010c753332000f10550141646420616e20604163636f756e744964602077697468207065726d697373696f6e20746f206772616e7420757365726e616d65732077697468206120676976656e20607375666669786020617070656e6465642e00590154686520617574686f726974792063616e206772616e7420757020746f2060616c6c6f636174696f6e6020757365726e616d65732e20546f20746f7020757020746865697220616c6c6f636174696f6e2c2074686579490173686f756c64206a75737420697373756520286f7220726571756573742076696120676f7665726e616e6365292061206e657720606164645f757365726e616d655f617574686f72697479602063616c6c2e6472656d6f76655f757365726e616d655f617574686f72697479040124617574686f72697479c50201504163636f756e7449644c6f6f6b75704f663c543e001004c452656d6f76652060617574686f72697479602066726f6d2074686520757365726e616d6520617574686f7269746965732e407365745f757365726e616d655f666f720c010c77686fc50201504163636f756e7449644c6f6f6b75704f663c543e000120757365726e616d6538011c5665633c75383e0001247369676e6174757265610501704f7074696f6e3c543a3a4f6666636861696e5369676e61747572653e0011240d015365742074686520757365726e616d6520666f72206077686f602e204d7573742062652063616c6c6564206279206120757365726e616d6520617574686f726974792e00550154686520617574686f72697479206d757374206861766520616e2060616c6c6f636174696f6e602e2055736572732063616e20656974686572207072652d7369676e20746865697220757365726e616d6573206f7248616363657074207468656d206c617465722e003c557365726e616d6573206d7573743ad820202d204f6e6c7920636f6e7461696e206c6f776572636173652041534349492063686172616374657273206f72206469676974732e350120202d205768656e20636f6d62696e656420776974682074686520737566666978206f66207468652069737375696e6720617574686f72697479206265205f6c657373207468616e5f207468656020202020604d6178557365726e616d654c656e677468602e3c6163636570745f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0012084d01416363657074206120676976656e20757365726e616d65207468617420616e2060617574686f7269747960206772616e7465642e205468652063616c6c206d75737420696e636c756465207468652066756c6c88757365726e616d652c20617320696e2060757365726e616d652e737566666978602e5c72656d6f76655f657870697265645f617070726f76616c040120757365726e616d657d01012c557365726e616d653c543e00130c610152656d6f766520616e206578706972656420757365726e616d6520617070726f76616c2e2054686520757365726e616d652077617320617070726f76656420627920616e20617574686f7269747920627574206e657665725501616363657074656420627920746865207573657220616e64206d757374206e6f77206265206265796f6e64206974732065787069726174696f6e2e205468652063616c6c206d75737420696e636c756465207468659c66756c6c20757365726e616d652c20617320696e2060757365726e616d652e737566666978602e507365745f7072696d6172795f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e0014043101536574206120676976656e20757365726e616d6520617320746865207072696d6172792e2054686520757365726e616d652073686f756c6420696e636c75646520746865207375666669782e6072656d6f76655f64616e676c696e675f757365726e616d65040120757365726e616d657d01012c557365726e616d653c543e001508550152656d6f7665206120757365726e616d65207468617420636f72726573706f6e647320746f20616e206163636f756e742077697468206e6f206964656e746974792e20457869737473207768656e20612075736572c067657473206120757365726e616d6520627574207468656e2063616c6c732060636c6561725f6964656e74697479602e04704964656e746974792070616c6c6574206465636c61726174696f6e2ecd040c3c70616c6c65745f6964656e74697479186c6567616379304964656e74697479496e666f04284669656c644c696d697400002401286164646974696f6e616cd1040190426f756e6465645665633c28446174612c2044617461292c204669656c644c696d69743e00011c646973706c6179d9040110446174610001146c6567616cd90401104461746100010c776562d90401104461746100011072696f74d904011044617461000114656d61696cd90401104461746100013c7067705f66696e6765727072696e74510501404f7074696f6e3c5b75383b2032305d3e000114696d616765d90401104461746100011c74776974746572d9040110446174610000d1040c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401d5040453000004004d0501185665633c543e0000d50400000408d904d90400d9040c3c70616c6c65745f6964656e746974791474797065731044617461000198104e6f6e6500000010526177300400dd040000010010526177310400e1040000020010526177320400e5040000030010526177330400e9040000040010526177340400480000050010526177350400ed040000060010526177360400f1040000070010526177370400f5040000080010526177380400ad020000090010526177390400f90400000a001452617731300400fd0400000b001452617731310400010500000c001452617731320400050500000d001452617731330400090500000e0014526177313404000d0500000f00145261773135040011050000100014526177313604004901000011001452617731370400150500001200145261773138040019050000130014526177313904001d0500001400145261773230040095010000150014526177323104002105000016001452617732320400250500001700145261773233040029050000180014526177323404002d05000019001452617732350400310500001a001452617732360400350500001b001452617732370400390500001c0014526177323804003d0500001d001452617732390400410500001e001452617733300400450500001f001452617733310400490500002000145261773332040004000021002c426c616b6554776f323536040004000022001853686132353604000400002300244b656363616b323536040004000024002c53686154687265653235360400040000250000dd04000003000000000800e104000003010000000800e504000003020000000800e904000003030000000800ed04000003050000000800f104000003060000000800f504000003070000000800f904000003090000000800fd040000030a000000080001050000030b000000080005050000030c000000080009050000030d00000008000d050000030e000000080011050000030f0000000800150500000311000000080019050000031200000008001d050000031300000008002105000003150000000800250500000316000000080029050000031700000008002d05000003180000000800310500000319000000080035050000031a000000080039050000031b00000008003d050000031c000000080041050000031d000000080045050000031e000000080049050000031f00000008004d05000002d50400510504184f7074696f6e0404540195010108104e6f6e6500000010536f6d65040095010000010000550500000259050059050000040800d904005d050c3c70616c6c65745f6964656e74697479147479706573244a756467656d656e74041c42616c616e63650118011c1c556e6b6e6f776e0000001c46656550616964040018011c42616c616e636500010028526561736f6e61626c65000200244b6e6f776e476f6f64000300244f75744f6644617465000400284c6f775175616c697479000500244572726f6e656f757300060000610504184f7074696f6e0404540165050108104e6f6e6500000010536f6d650400650500000100006505082873705f72756e74696d65384d756c74695369676e617475726500010c1c4564323535313904000d030148656432353531393a3a5369676e61747572650000001c5372323535313904000d030148737232353531393a3a5369676e61747572650001001445636473610400fd01014065636473613a3a5369676e61747572650002000069050c3870616c6c65745f7574696c6974791870616c6c65741043616c6c04045400011814626174636804011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000487c53656e642061206261746368206f662064697370617463682063616c6c732e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e005501546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e31016576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e207468655501604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d6164654d01616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c65746564604c6576656e74206973206465706f73697465642e3461735f64657269766174697665080114696e646578e901010c75313600011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000134dc53656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e00550146696c7465722066726f6d206f726967696e206172652070617373656420616c6f6e672e205468652063616c6c2077696c6c2062652064697370617463686564207769746820616e206f726967696e207768696368bc757365207468652073616d652066696c74657220617320746865206f726967696e206f6620746869732063616c6c2e0045014e4f54453a20496620796f75206e65656420746f20656e73757265207468617420616e79206163636f756e742d62617365642066696c746572696e67206973206e6f7420686f6e6f7265642028692e652e61016265636175736520796f7520657870656374206070726f78796020746f2068617665206265656e2075736564207072696f7220696e207468652063616c6c20737461636b20616e6420796f7520646f206e6f742077616e7451017468652063616c6c207265737472696374696f6e7320746f206170706c7920746f20616e79207375622d6163636f756e7473292c207468656e20757365206061735f6d756c74695f7468726573686f6c645f31607c696e20746865204d756c74697369672070616c6c657420696e73746561642e00f44e4f54453a205072696f7220746f2076657273696f6e202a31322c2074686973207761732063616c6c6564206061735f6c696d697465645f737562602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e2462617463685f616c6c04011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000234ec53656e642061206261746368206f662064697370617463682063616c6c7320616e642061746f6d6963616c6c792065786563757465207468656d2e21015468652077686f6c65207472616e73616374696f6e2077696c6c20726f6c6c6261636b20616e64206661696c20696620616e79206f66207468652063616c6c73206661696c65642e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e0055014966206f726967696e20697320726f6f74207468656e207468652063616c6c7320617265206469737061746368656420776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c64697370617463685f617308012461735f6f726967696e71050154426f783c543a3a50616c6c6574734f726967696e3e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000318c84469737061746368657320612066756e6374696f6e2063616c6c207769746820612070726f7669646564206f726967696e2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e0034232320436f6d706c65786974791c2d204f2831292e2c666f7263655f626174636804011463616c6c736d05017c5665633c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0004347c53656e642061206261746368206f662064697370617463682063616c6c732ed4556e6c696b6520606261746368602c20697420616c6c6f7773206572726f727320616e6420776f6e277420696e746572727570742e00b04d61792062652063616c6c65642066726f6d20616e79206f726967696e2065786365707420604e6f6e65602e005d012d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e20546865206e756d626572206f662063616c6c206d757374206e6f74390120206578636565642074686520636f6e7374616e743a2060626174636865645f63616c6c735f6c696d6974602028617661696c61626c6520696e20636f6e7374616e74206d65746164617461292e004d014966206f726967696e20697320726f6f74207468656e207468652063616c6c732061726520646973706174636820776974686f757420636865636b696e67206f726967696e2066696c7465722e202854686973ec696e636c7564657320627970617373696e6720606672616d655f73797374656d3a3a436f6e6669673a3a4261736543616c6c46696c74657260292e0034232320436f6d706c6578697479d02d204f284329207768657265204320697320746865206e756d626572206f662063616c6c7320746f20626520626174636865642e2c776974685f77656967687408011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e000118776569676874280118576569676874000518c4446973706174636820612066756e6374696f6e2063616c6c2077697468206120737065636966696564207765696768742e002d01546869732066756e6374696f6e20646f6573206e6f7420636865636b2074686520776569676874206f66207468652063616c6c2c20616e6420696e737465616420616c6c6f777320746865b8526f6f74206f726967696e20746f20737065636966792074686520776569676874206f66207468652063616c6c2e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e6d05000002bd02007105085874616e676c655f746573746e65745f72756e74696d65304f726967696e43616c6c65720001101873797374656d0400750501746672616d655f73797374656d3a3a4f726967696e3c52756e74696d653e0001001c436f756e63696c0400790501010170616c6c65745f636f6c6c6563746976653a3a4f726967696e3c52756e74696d652c2070616c6c65745f636f6c6c6563746976653a3a496e7374616e6365313e000d0020457468657265756d04007d05015c70616c6c65745f657468657265756d3a3a4f726967696e00210010566f69640400210301410173656c663a3a73705f6170695f68696464656e5f696e636c756465735f636f6e7374727563745f72756e74696d653a3a68696464656e5f696e636c7564653a3a0a5f5f707269766174653a3a566f69640003000075050c346672616d655f737570706f7274206469737061746368245261774f726967696e04244163636f756e7449640100010c10526f6f74000000185369676e656404000001244163636f756e744964000100104e6f6e65000200007905084470616c6c65745f636f6c6c656374697665245261774f726967696e08244163636f756e7449640100044900010c1c4d656d62657273080010012c4d656d626572436f756e74000010012c4d656d626572436f756e74000000184d656d62657204000001244163636f756e744964000100205f5068616e746f6d000200007d05083c70616c6c65745f657468657265756d245261774f726967696e0001044c457468657265756d5472616e73616374696f6e040091010110483136300000000081050c3c70616c6c65745f6d756c74697369671870616c6c65741043616c6c0404540001105061735f6d756c74695f7468726573686f6c645f310801446f746865725f7369676e61746f72696573350201445665633c543a3a4163636f756e7449643e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000305101496d6d6564696174656c792064697370617463682061206d756c74692d7369676e61747572652063616c6c207573696e6720612073696e676c6520617070726f76616c2066726f6d207468652063616c6c65722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e003d012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f206172652070617274206f662074686501016d756c74692d7369676e61747572652c2062757420646f206e6f7420706172746963697061746520696e2074686520617070726f76616c2070726f636573732e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e00b8526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c742e0034232320436f6d706c657869747919014f285a202b204329207768657265205a20697320746865206c656e677468206f66207468652063616c6c20616e6420432069747320657865637574696f6e207765696768742e2061735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573350201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74850501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0001286d61785f77656967687428011857656967687400019c5501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e00b049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e882d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e001d014e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f20757365190160617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e005901526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f746865727769736555016f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642cdc6d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e0034232320436f6d706c6578697479502d20604f2853202b205a202b2043616c6c29602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e21012d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e6c2d2054686520776569676874206f6620746865206063616c6c602e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e40617070726f76655f61735f6d756c74691401247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573350201445665633c543a3a4163636f756e7449643e00013c6d617962655f74696d65706f696e74850501904f7074696f6e3c54696d65706f696e743c426c6f636b4e756d626572466f723c543e3e3e00012463616c6c5f686173680401205b75383b2033325d0001286d61785f7765696768742801185765696768740002785501526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e74206966f8617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e002d015061796d656e743a20604465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c75733d01607468726573686f6c64602074696d657320604465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f723469732063616e63656c6c65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e59012d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e20496620697420697351016e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64d47472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0035014e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602ed42d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292ef82d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e302d204f6e65206576656e742e4d012d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c20776974682061206465706f7369741901202074616b656e20666f7220697473206c69666574696d65206f6620604465706f73697442617365202b207468726573686f6c64202a204465706f736974466163746f72602e3c63616e63656c5f61735f6d756c74691001247468726573686f6c64e901010c7531360001446f746865725f7369676e61746f72696573350201445665633c543a3a4163636f756e7449643e00012474696d65706f696e748901017054696d65706f696e743c426c6f636b4e756d626572466f723c543e3e00012463616c6c5f686173680401205b75383b2033325d000354550143616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c79c4666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0055012d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e41012d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869736c64697370617463682e204d6179206e6f7420626520656d7074792e5d012d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c787472616e73616374696f6e20666f7220746869732064697370617463682ecc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e0034232320436f6d706c6578697479242d20604f285329602ecc2d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e3d012d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f66450120207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2ebc2d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e302d204f6e65206576656e742e842d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e702d2053746f726167653a2072656d6f766573206f6e65206974656d2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e850504184f7074696f6e0404540189010108104e6f6e6500000010536f6d6504008901000001000089050c3c70616c6c65745f657468657265756d1870616c6c65741043616c6c040454000104207472616e7361637404012c7472616e73616374696f6e8d05012c5472616e73616374696f6e000004845472616e7361637420616e20457468657265756d207472616e73616374696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e8d050c20657468657265756d2c7472616e73616374696f6e345472616e73616374696f6e563200010c184c65676163790400910501444c65676163795472616e73616374696f6e0000001c454950323933300400a1050148454950323933305472616e73616374696f6e0001001c454950313535390400ad050148454950313535395472616e73616374696f6e0002000091050c20657468657265756d2c7472616e73616374696f6e444c65676163795472616e73616374696f6e00001c01146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e70757438011442797465730001247369676e6174757265990501505472616e73616374696f6e5369676e6174757265000095050c20657468657265756d2c7472616e73616374696f6e445472616e73616374696f6e416374696f6e0001081043616c6c04009101011048313630000000184372656174650001000099050c20657468657265756d2c7472616e73616374696f6e505472616e73616374696f6e5369676e617475726500000c0104769d0501545472616e73616374696f6e5265636f7665727949640001047234011048323536000104733401104832353600009d050c20657468657265756d2c7472616e73616374696f6e545472616e73616374696f6e5265636f7665727949640000040030010c7536340000a1050c20657468657265756d2c7472616e73616374696f6e48454950323933305472616e73616374696f6e00002c0120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001246761735f7072696365c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a50501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000a505000002a90500a9050c20657468657265756d2c7472616e73616374696f6e384163636573734c6973744974656d000008011c616464726573739101011c4164647265737300013073746f726167655f6b657973c10101245665633c483235363e0000ad050c20657468657265756d2c7472616e73616374696f6e48454950313535395472616e73616374696f6e0000300120636861696e5f696430010c7536340001146e6f6e6365c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173c90101105532353600013c6d61785f6665655f7065725f676173c9010110553235360001246761735f6c696d6974c901011055323536000118616374696f6e950501445472616e73616374696f6e416374696f6e00011476616c7565c901011055323536000114696e707574380114427974657300012c6163636573735f6c697374a50501284163636573734c6973740001306f64645f795f706172697479200110626f6f6c000104723401104832353600010473340110483235360000b1050c2870616c6c65745f65766d1870616c6c65741043616c6c04045400011020776974686472617708011c61646472657373910101104831363000011476616c756518013042616c616e63654f663c543e000004e057697468647261772062616c616e63652066726f6d2045564d20696e746f2063757272656e63792f62616c616e6365732070616c6c65742e1063616c6c240118736f7572636591010110483136300001187461726765749101011048313630000114696e70757438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0001045d01497373756520616e2045564d2063616c6c206f7065726174696f6e2e20546869732069732073696d696c617220746f2061206d6573736167652063616c6c207472616e73616374696f6e20696e20457468657265756d2e18637265617465200118736f757263659101011048313630000110696e697438011c5665633c75383e00011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0002085101497373756520616e2045564d20637265617465206f7065726174696f6e2e20546869732069732073696d696c617220746f206120636f6e7472616374206372656174696f6e207472616e73616374696f6e20696e24457468657265756d2e1c63726561746532240118736f757263659101011048313630000110696e697438011c5665633c75383e00011073616c743401104832353600011476616c7565c9010110553235360001246761735f6c696d697430010c75363400013c6d61785f6665655f7065725f676173c9010110553235360001606d61785f7072696f726974795f6665655f7065725f676173b50501304f7074696f6e3c553235363e0001146e6f6e6365b50501304f7074696f6e3c553235363e00012c6163636573735f6c697374b90501585665633c28483136302c205665633c483235363e293e0003047c497373756520616e2045564d2063726561746532206f7065726174696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732eb50504184f7074696f6e04045401c9010108104e6f6e6500000010536f6d650400c9010000010000b905000002bd0500bd05000004089101c10100c1050c4870616c6c65745f64796e616d69635f6665651870616c6c65741043616c6c040454000104646e6f74655f6d696e5f6761735f70726963655f746172676574040118746172676574c901011055323536000000040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec5050c3c70616c6c65745f626173655f6665651870616c6c65741043616c6c040454000108507365745f626173655f6665655f7065725f67617304010c666565c901011055323536000000387365745f656c6173746963697479040128656c6173746963697479d101011c5065726d696c6c000100040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ec9050c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c65741043616c6c04045400010478686f746669785f696e635f6163636f756e745f73756666696369656e7473040124616464726573736573cd0501245665633c483136303e0000100502496e6372656d656e74206073756666696369656e74736020666f72206578697374696e67206163636f756e747320686176696e672061206e6f6e7a65726f20606e6f6e63656020627574207a65726f206073756666696369656e7473602c2060636f6e73756d6572736020616e64206070726f766964657273602076616c75652e2d0154686973207374617465207761732063617573656420627920612070726576696f75732062756720696e2045564d20637265617465206163636f756e7420646973706174636861626c652e006501416e79206163636f756e747320696e2074686520696e707574206c697374206e6f742073617469736679696e67207468652061626f766520636f6e646974696f6e2077696c6c2072656d61696e20756e61666665637465642e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ecd05000002910100d1050c5470616c6c65745f61697264726f705f636c61696d731870616c6c65741043616c6c04045400011814636c61696d0c011064657374d50501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d50501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d90501544d756c7469416464726573735369676e6174757265000060904d616b65206120636c61696d20746f20636f6c6c65637420796f757220746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a0501412063616c6c20746f20636c61696d206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653a943e2028636f6e666967757265642070726566697820737472696e672928616464726573732900a4616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732ee057656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d696e745f636c61696d10010c77686fd90101304d756c74694164647265737300011476616c756518013042616c616e63654f663c543e00014076657374696e675f7363686564756c65e5050179014f7074696f6e3c426f756e6465645665633c0a2842616c616e63654f663c543e2c2042616c616e63654f663c543e2c20426c6f636b4e756d626572466f723c543e292c20543a3a0a4d617856657374696e675363686564756c65733e2c3e00012473746174656d656e74f50501544f7074696f6e3c53746174656d656e744b696e643e00013ca84d696e742061206e657720636c61696d20746f20636f6c6c656374206e617469766520746f6b656e732e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e002c506172616d65746572733af02d206077686f603a2054686520457468657265756d206164647265737320616c6c6f77656420746f20636f6c6c656374207468697320636c61696d2ef02d206076616c7565603a20546865206e756d626572206f66206e617469766520746f6b656e7320746861742077696c6c20626520636c61696d65642e2d012d206076657374696e675f7363686564756c65603a20416e206f7074696f6e616c2076657374696e67207363686564756c6520666f72207468657365206e617469766520746f6b656e732e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732e1d01576520617373756d6520776f7273742063617365207468617420626f74682076657374696e6720616e642073746174656d656e74206973206265696e6720696e7365727465642e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e30636c61696d5f61747465737410011064657374d50501504f7074696f6e3c4d756c7469416464726573733e0001187369676e6572d50501504f7074696f6e3c4d756c7469416464726573733e0001247369676e6174757265d90501544d756c7469416464726573735369676e617475726500012473746174656d656e7438011c5665633c75383e00026c09014d616b65206120636c61696d20746f20636f6c6c65637420796f7572206e617469766520746f6b656e73206279207369676e696e6720612073746174656d656e742e00c4546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f4e6f6e655f2e0050556e7369676e65642056616c69646174696f6e3a2901412063616c6c20746f2060636c61696d5f61747465737460206973206465656d65642076616c696420696620746865207369676e61747572652070726f7669646564206d6174636865737c746865206578706563746564207369676e6564206d657373616765206f663a00683e20457468657265756d205369676e6564204d6573736167653ac03e2028636f6e666967757265642070726566697820737472696e67292861646472657373292873746174656d656e7429004901616e6420606164647265737360206d6174636865732074686520606465737460206163636f756e743b20746865206073746174656d656e7460206d757374206d617463682074686174207768696368206973c06578706563746564206163636f7264696e6720746f20796f757220707572636861736520617272616e67656d656e742e002c506172616d65746572733ad82d206064657374603a205468652064657374696e6174696f6e206163636f756e7420746f207061796f75742074686520636c61696d2e5d012d2060657468657265756d5f7369676e6174757265603a20546865207369676e6174757265206f6620616e20657468657265756d207369676e6564206d657373616765206d61746368696e672074686520666f726d61744820206465736372696265642061626f76652e39012d206073746174656d656e74603a20546865206964656e74697479206f66207468652073746174656d656e74207768696368206973206265696e6720617474657374656420746f20696e207468653020207369676e61747572652e00203c7765696768743efc54686520776569676874206f6620746869732063616c6c20697320696e76617269616e74206f7665722074686520696e70757420706172616d65746572732efc57656967687420696e636c75646573206c6f67696320746f2076616c696461746520756e7369676e65642060636c61696d5f617474657374602063616c6c2e0058546f74616c20436f6d706c65786974793a204f283129243c2f7765696768743e286d6f76655f636c61696d08010c6f6c64d90101304d756c74694164647265737300010c6e6577d90101304d756c7469416464726573730004005c666f7263655f7365745f6578706972795f636f6e6669670801306578706972795f626c6f636b300144426c6f636b4e756d626572466f723c543e00011064657374d90101304d756c74694164647265737300050878536574207468652076616c756520666f7220657870697279636f6e6669678443616e206f6e6c792062652063616c6c656420627920466f7263654f726967696e30636c61696d5f7369676e656404011064657374d50501504f7074696f6e3c4d756c7469416464726573733e00060460436c61696d2066726f6d207369676e6564206f726967696e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ed50504184f7074696f6e04045401d9010108104e6f6e6500000010536f6d650400d9010000010000d9050c5470616c6c65745f61697264726f705f636c61696d73147574696c73544d756c7469416464726573735369676e61747572650001080c45564d0400dd05013845636473615369676e6174757265000000184e61746976650400e1050140537232353531395369676e617475726500010000dd05105470616c6c65745f61697264726f705f636c61696d73147574696c7340657468657265756d5f616464726573733845636473615369676e617475726500000400fd0101205b75383b2036355d0000e1050c5470616c6c65745f61697264726f705f636c61696d73147574696c7340537232353531395369676e6174757265000004000d0301245369676e61747572650000e50504184f7074696f6e04045401e9050108104e6f6e6500000010536f6d650400e9050000010000e9050c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ed05045300000400f10501185665633c543e0000ed050000040c18183000f105000002ed0500f50504184f7074696f6e04045401f9050108104e6f6e6500000010536f6d650400f9050000010000f905085470616c6c65745f61697264726f705f636c61696d733453746174656d656e744b696e640001081c526567756c6172000000105361666500010000fd050c3070616c6c65745f70726f78791870616c6c65741043616c6c0404540001281470726f78790c01107265616cc50201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065010601504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e0000244d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f726973656420666f72207468726f75676830606164645f70726f7879602e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e246164645f70726f78790c012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e0001244501526567697374657220612070726f7879206163636f756e7420666f72207468652073656e64657220746861742069732061626c6520746f206d616b652063616c6c73206f6e2069747320626568616c662e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a11012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f206d616b6520612070726f78792efc2d206070726f78795f74797065603a20546865207065726d697373696f6e7320616c6c6f77656420666f7220746869732070726f7879206163636f756e742e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e3072656d6f76655f70726f78790c012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e00021ca8556e726567697374657220612070726f7879206163636f756e7420666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a25012d206070726f7879603a20546865206163636f756e74207468617420746865206063616c6c65726020776f756c64206c696b6520746f2072656d6f766520617320612070726f78792e41012d206070726f78795f74797065603a20546865207065726d697373696f6e732063757272656e746c7920656e61626c656420666f72207468652072656d6f7665642070726f7879206163636f756e742e3872656d6f76655f70726f78696573000318b4556e726567697374657220616c6c2070726f7879206163636f756e747320666f72207468652073656e6465722e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e0041015741524e494e473a2054686973206d61792062652063616c6c6564206f6e206163636f756e74732063726561746564206279206070757265602c20686f776576657220696620646f6e652c207468656e590174686520756e726573657276656420666565732077696c6c20626520696e61636365737369626c652e202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a2c6372656174655f707572650c012870726f78795f74797065e5010130543a3a50726f78795479706500011464656c6179300144426c6f636b4e756d626572466f723c543e000114696e646578e901010c7531360004483901537061776e2061206672657368206e6577206163636f756e7420746861742069732067756172616e7465656420746f206265206f746865727769736520696e61636365737369626c652c20616e64fc696e697469616c697a65206974207769746820612070726f7879206f66206070726f78795f747970656020666f7220606f726967696e602073656e6465722e006c5265717569726573206120605369676e656460206f726967696e2e0051012d206070726f78795f74797065603a205468652074797065206f66207468652070726f78792074686174207468652073656e6465722077696c6c2062652072656769737465726564206173206f766572207468654d016e6577206163636f756e742e20546869732077696c6c20616c6d6f737420616c7761797320626520746865206d6f7374207065726d697373697665206050726f7879547970656020706f737369626c6520746f78616c6c6f7720666f72206d6178696d756d20666c65786962696c6974792e51012d2060696e646578603a204120646973616d626967756174696f6e20696e6465782c20696e206361736520746869732069732063616c6c6564206d756c7469706c652074696d657320696e207468652073616d655d017472616e73616374696f6e2028652e672e207769746820607574696c6974793a3a626174636860292e20556e6c65737320796f75277265207573696e67206062617463686020796f752070726f6261626c79206a7573744077616e7420746f20757365206030602e4d012d206064656c6179603a2054686520616e6e6f756e63656d656e7420706572696f64207265717569726564206f662074686520696e697469616c2070726f78792e2057696c6c2067656e6572616c6c79206265147a65726f2e0051014661696c73207769746820604475706c69636174656020696620746869732068617320616c7265616479206265656e2063616c6c656420696e2074686973207472616e73616374696f6e2c2066726f6d207468659873616d652073656e6465722c2077697468207468652073616d6520706172616d65746572732e00e44661696c732069662074686572652061726520696e73756666696369656e742066756e647320746f2070617920666f72206465706f7369742e246b696c6c5f7075726514011c737061776e6572c50201504163636f756e7449644c6f6f6b75704f663c543e00012870726f78795f74797065e5010130543a3a50726f787954797065000114696e646578e901010c7531360001186865696768742c0144426c6f636b4e756d626572466f723c543e0001246578745f696e6465786902010c753332000540a052656d6f76657320612070726576696f75736c7920737061776e656420707572652070726f78792e0049015741524e494e473a202a2a416c6c2061636365737320746f2074686973206163636f756e742077696c6c206265206c6f73742e2a2a20416e792066756e64732068656c6420696e2069742077696c6c20626534696e61636365737369626c652e0059015265717569726573206120605369676e656460206f726967696e2c20616e64207468652073656e646572206163636f756e74206d7573742068617665206265656e206372656174656420627920612063616c6c20746f94607075726560207769746820636f72726573706f6e64696e6720706172616d65746572732e0039012d2060737061776e6572603a20546865206163636f756e742074686174206f726967696e616c6c792063616c6c65642060707572656020746f206372656174652074686973206163636f756e742e39012d2060696e646578603a2054686520646973616d626967756174696f6e20696e646578206f726967696e616c6c792070617373656420746f206070757265602e2050726f6261626c79206030602eec2d206070726f78795f74797065603a205468652070726f78792074797065206f726967696e616c6c792070617373656420746f206070757265602e29012d2060686569676874603a2054686520686569676874206f662074686520636861696e207768656e207468652063616c6c20746f20607075726560207761732070726f6365737365642e35012d20606578745f696e646578603a205468652065787472696e73696320696e64657820696e207768696368207468652063616c6c20746f20607075726560207761732070726f6365737365642e0035014661696c73207769746820604e6f5065726d697373696f6e6020696e2063617365207468652063616c6c6572206973206e6f7420612070726576696f75736c7920637265617465642070757265dc6163636f756e742077686f7365206070757265602063616c6c2068617320636f72726573706f6e64696e6720706172616d65746572732e20616e6e6f756e63650801107265616cc50201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e00063c05015075626c697368207468652068617368206f6620612070726f78792d63616c6c20746861742077696c6c206265206d61646520696e20746865206675747572652e005d0154686973206d7573742062652063616c6c656420736f6d65206e756d626572206f6620626c6f636b73206265666f72652074686520636f72726573706f6e64696e67206070726f78796020697320617474656d7074656425016966207468652064656c6179206173736f6369617465642077697468207468652070726f78792072656c6174696f6e736869702069732067726561746572207468616e207a65726f2e0011014e6f206d6f7265207468616e20604d617850656e64696e676020616e6e6f756e63656d656e7473206d6179206265206d61646520617420616e79206f6e652074696d652e000901546869732077696c6c2074616b652061206465706f736974206f662060416e6e6f756e63656d656e744465706f736974466163746f72602061732077656c6c206173190160416e6e6f756e63656d656e744465706f736974426173656020696620746865726520617265206e6f206f746865722070656e64696e6720616e6e6f756e63656d656e74732e002501546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420612070726f7879206f6620607265616c602e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656d6f76655f616e6e6f756e63656d656e740801107265616cc50201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e0007287052656d6f7665206120676976656e20616e6e6f756e63656d656e742e0059014d61792062652063616c6c656420627920612070726f7879206163636f756e7420746f2072656d6f766520612063616c6c20746865792070726576696f75736c7920616e6e6f756e63656420616e642072657475726e30746865206465706f7369742e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e15012d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e4c72656a6563745f616e6e6f756e63656d656e7408012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e00012463616c6c5f6861736834013443616c6c486173684f663c543e000828b052656d6f76652074686520676976656e20616e6e6f756e63656d656e74206f6620612064656c65676174652e0061014d61792062652063616c6c6564206279206120746172676574202870726f7869656429206163636f756e7420746f2072656d6f766520612063616c6c2074686174206f6e65206f662074686569722064656c6567617465732501286064656c656761746560292068617320616e6e6f756e63656420746865792077616e7420746f20657865637574652e20546865206465706f7369742069732072657475726e65642e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733af42d206064656c6567617465603a20546865206163636f756e7420746861742070726576696f75736c7920616e6e6f756e636564207468652063616c6c2ebc2d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f206265206d6164652e3c70726f78795f616e6e6f756e63656410012064656c6567617465c50201504163636f756e7449644c6f6f6b75704f663c543e0001107265616cc50201504163636f756e7449644c6f6f6b75704f663c543e000140666f7263655f70726f78795f74797065010601504f7074696f6e3c543a3a50726f7879547970653e00011063616c6cbd02017c426f783c3c5420617320436f6e6669673e3a3a52756e74696d6543616c6c3e00092c4d0144697370617463682074686520676976656e206063616c6c602066726f6d20616e206163636f756e742074686174207468652073656e64657220697320617574686f72697a656420666f72207468726f75676830606164645f70726f7879602e00a852656d6f76657320616e7920636f72726573706f6e64696e6720616e6e6f756e63656d656e742873292e00cc546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e002c506172616d65746572733a0d012d20607265616c603a20546865206163636f756e742074686174207468652070726f78792077696c6c206d616b6520612063616c6c206f6e20626568616c66206f662e61012d2060666f7263655f70726f78795f74797065603a2053706563696679207468652065786163742070726f7879207479706520746f206265207573656420616e6420636865636b656420666f7220746869732063616c6c2ed02d206063616c6c603a205468652063616c6c20746f206265206d6164652062792074686520607265616c60206163636f756e742e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e010604184f7074696f6e04045401e5010108104e6f6e6500000010536f6d650400e501000001000005060c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c65741043616c6c040454000150386a6f696e5f6f70657261746f727304012c626f6e645f616d6f756e7418013042616c616e63654f663c543e00003c3501416c6c6f777320616e206163636f756e7420746f206a6f696e20617320616e206f70657261746f72206279207374616b696e672074686520726571756972656420626f6e6420616d6f756e742e003423205065726d697373696f6e7300cc2a204d757374206265207369676e656420627920746865206163636f756e74206a6f696e696e67206173206f70657261746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cc82a2060626f6e645f616d6f756e7460202d20416d6f756e7420746f207374616b65206173206f70657261746f7220626f6e64002023204572726f72730029012a205b604572726f723a3a4465706f7369744f766572666c6f77605d202d20426f6e6420616d6f756e7420776f756c64206f766572666c6f77206465706f73697420747261636b696e6719012a205b604572726f723a3a5374616b654f766572666c6f77605d202d20426f6e6420616d6f756e7420776f756c64206f766572666c6f77207374616b6520747261636b696e67607363686564756c655f6c656176655f6f70657261746f7273000138a85363686564756c657320616e206f70657261746f7220746f206c65617665207468652073797374656d2e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7265012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d204f70657261746f7220616c72656164792068617320612070656e64696e6720756e7374616b6520726571756573745863616e63656c5f6c656176655f6f70657261746f7273000238a843616e63656c732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b652072657175657374206578697374735c657865637574655f6c656176655f6f70657261746f727300033cac45786563757465732061207363686564756c6564206c6561766520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747325012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c617073656420796574486f70657261746f725f626f6e645f6d6f726504013c6164646974696f6e616c5f626f6e6418013042616c616e63654f663c543e00043cac416c6c6f777320616e206f70657261746f7220746f20696e637265617365207468656972207374616b652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cc02a20606164646974696f6e616c5f626f6e6460202d204164646974696f6e616c20616d6f756e7420746f207374616b65002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7229012a205b604572726f723a3a5374616b654f766572666c6f77605d202d204164646974696f6e616c20626f6e6420776f756c64206f766572666c6f77207374616b6520747261636b696e67647363686564756c655f6f70657261746f725f756e7374616b65040138756e7374616b655f616d6f756e7418013042616c616e63654f663c543e000540b85363686564756c657320616e206f70657261746f7220746f206465637265617365207468656972207374616b652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a2060756e7374616b655f616d6f756e7460202d20416d6f756e7420746f20756e7374616b65002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f7265012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d204f70657261746f7220616c72656164792068617320612070656e64696e6720756e7374616b65207265717565737435012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d204f70657261746f722068617320696e73756666696369656e74207374616b6520746f20756e7374616b6560657865637574655f6f70657261746f725f756e7374616b6500063cd045786563757465732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747325012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c6170736564207965745c63616e63656c5f6f70657261746f725f756e7374616b65000738cc43616e63656c732061207363686564756c6564207374616b6520646563726561736520666f7220616e206f70657261746f722e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747328676f5f6f66666c696e6500083884416c6c6f777320616e206f70657261746f7220746f20676f206f66666c696e652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f72e42a205b604572726f723a3a416c72656164794f66666c696e65605d202d204f70657261746f7220697320616c7265616479206f66666c696e6524676f5f6f6e6c696e6500093880416c6c6f777320616e206f70657261746f7220746f20676f206f6e6c696e652e003423205065726d697373696f6e7300a02a204d757374206265207369676e656420627920746865206f70657261746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f7273000d012a205b604572726f723a3a4e6f744f70657261746f72605d202d204163636f756e74206973206e6f74207265676973746572656420617320616e206f70657261746f72dc2a205b604572726f723a3a416c72656164794f6e6c696e65605d202d204f70657261746f7220697320616c7265616479206f6e6c696e651c6465706f73697410012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00012c65766d5f61646472657373090601304f7074696f6e3c483136303e00013c6c6f636b5f6d756c7469706c6965720d0601584f7074696f6e3c4c6f636b4d756c7469706c6965723e000a4488416c6c6f77732061207573657220746f206465706f73697420616e2061737365742e003423205065726d697373696f6e7300a42a204d757374206265207369676e656420627920746865206465706f7369746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca42a206061737365745f696460202d204944206f662074686520617373657420746f206465706f736974782a2060616d6f756e7460202d20416d6f756e7420746f206465706f736974982a206065766d5f6164647265737360202d204f7074696f6e616c2045564d2061646472657373002023204572726f727300f82a205b604572726f723a3a4465706f7369744f766572666c6f77605d202d204465706f73697420776f756c64206f766572666c6f7720747261636b696e67c82a205b604572726f723a3a496e76616c69644173736574605d202d204173736574206973206e6f7420737570706f72746564447363686564756c655f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000b40745363686564756c6573206120776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca82a206061737365745f696460202d204944206f662074686520617373657420746f2077697468647261777c2a2060616d6f756e7460202d20416d6f756e7420746f207769746864726177002023204572726f7273000d012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d20496e73756666696369656e742062616c616e636520746f2077697468647261772d012a205b604572726f723a3a50656e64696e67576974686472617752657175657374457869737473605d202d2050656e64696e6720776974686472617720726571756573742065786973747340657865637574655f776974686472617704012c65766d5f61646472657373090601304f7074696f6e3c483136303e000c3c9845786563757465732061207363686564756c656420776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a206065766d5f6164647265737360202d204f7074696f6e616c2045564d2061646472657373002023204572726f72730025012a205b604572726f723a3a4e6f576974686472617752657175657374457869737473605d202d204e6f2070656e64696e672077697468647261772072657175657374206578697374731d012a205b604572726f723a3a5769746864726177506572696f644e6f74456c6170736564605d202d20576974686472617720706572696f6420686173206e6f7420656c61707365643c63616e63656c5f776974686472617708012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000d3c9443616e63656c732061207363686564756c656420776974686472617720726571756573742e003423205065726d697373696f6e7300a82a204d757374206265207369676e6564206279207468652077697468647261776572206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ccc2a206061737365745f696460202d204944206f6620746865206173736574207769746864726177616c20746f2063616e63656cbc2a2060616d6f756e7460202d20416d6f756e74206f6620746865207769746864726177616c20746f2063616e63656c002023204572726f72730025012a205b604572726f723a3a4e6f576974686472617752657175657374457869737473605d202d204e6f2070656e64696e672077697468647261772072657175657374206578697374732064656c65676174651001206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e00014c626c75657072696e745f73656c656374696f6e150601d844656c656761746f72426c75657072696e7453656c656374696f6e3c543a3a4d617844656c656761746f72426c75657072696e74733e000e4cfc416c6c6f77732061207573657220746f2064656c656761746520616e20616d6f756e74206f6620616e20617373657420746f20616e206f70657261746f722e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c982a20606f70657261746f7260202d204f70657261746f7220746f2064656c656761746520746f982a206061737365745f696460202d204944206f6620617373657420746f2064656c65676174657c2a2060616d6f756e7460202d20416d6f756e7420746f2064656c6567617465d82a2060626c75657072696e745f73656c656374696f6e60202d20426c75657072696e742073656c656374696f6e207374726174656779002023204572726f727300f02a205b604572726f723a3a4e6f744f70657261746f72605d202d20546172676574206163636f756e74206973206e6f7420616e206f70657261746f720d012a205b604572726f723a3a496e73756666696369656e7442616c616e6365605d202d20496e73756666696369656e742062616c616e636520746f2064656c656761746509012a205b604572726f723a3a4d617844656c65676174696f6e734578636565646564605d202d20576f756c6420657863656564206d61782064656c65676174696f6e73687363686564756c655f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e000f48c85363686564756c65732061207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c9c2a20606f70657261746f7260202d204f70657261746f7220746f20756e7374616b652066726f6d942a206061737365745f696460202d204944206f6620617373657420746f20756e7374616b65782a2060616d6f756e7460202d20416d6f756e7420746f20756e7374616b65002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f7221012a205b604572726f723a3a496e73756666696369656e7444656c65676174696f6e605d202d20496e73756666696369656e742064656c65676174696f6e20746f20756e7374616b6525012a205b604572726f723a3a50656e64696e67556e7374616b6552657175657374457869737473605d202d2050656e64696e6720756e7374616b6520726571756573742065786973747364657865637574655f64656c656761746f725f756e7374616b6500103cec45786563757465732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b6520726571756573742065786973747315012a205b604572726f723a3a556e7374616b65506572696f644e6f74456c6170736564605d202d20556e7374616b6520706572696f6420686173206e6f7420656c61707365646063616e63656c5f64656c656761746f725f756e7374616b650c01206f70657261746f72000130543a3a4163636f756e74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616d6f756e7418013042616c616e63654f663c543e001144e843616e63656c732061207363686564756c6564207265717565737420746f2072656475636520612064656c656761746f722773207374616b652e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb82a20606f70657261746f7260202d204f70657261746f7220746f2063616e63656c20756e7374616b652066726f6db02a206061737365745f696460202d204944206f6620617373657420756e7374616b6520746f2063616e63656ca02a2060616d6f756e7460202d20416d6f756e74206f6620756e7374616b6520746f2063616e63656c002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f721d012a205b604572726f723a3a4e6f556e7374616b6552657175657374457869737473605d202d204e6f2070656e64696e6720756e7374616b65207265717565737420657869737473406164645f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001644bc41646473206120626c75657072696e7420494420746f20612064656c656761746f7227732073656c656374696f6e2e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca42a2060626c75657072696e745f696460202d204944206f6620626c75657072696e7420746f20616464002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f72fc2a205b604572726f723a3a4475706c6963617465426c75657072696e744964605d202d20426c75657072696e7420494420616c72656164792065786973747301012a205b604572726f723a3a4d6178426c75657072696e74734578636565646564605d202d20576f756c6420657863656564206d617820626c75657072696e74730d012a205b604572726f723a3a4e6f74496e46697865644d6f6465605d202d204e6f7420696e20666978656420626c75657072696e742073656c656374696f6e206d6f64654c72656d6f76655f626c75657072696e745f6964040130626c75657072696e745f696430012c426c75657072696e744964001740d052656d6f766573206120626c75657072696e742049442066726f6d20612064656c656761746f7227732073656c656374696f6e2e003423205065726d697373696f6e7300a42a204d757374206265207369676e6564206279207468652064656c656761746f72206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb02a2060626c75657072696e745f696460202d204944206f6620626c75657072696e7420746f2072656d6f7665002023204572726f727300d82a205b604572726f723a3a4e6f7444656c656761746f72605d202d204163636f756e74206973206e6f7420612064656c656761746f72e42a205b604572726f723a3a426c75657072696e7449644e6f74466f756e64605d202d20426c75657072696e74204944206e6f7420666f756e640d012a205b604572726f723a3a4e6f74496e46697865644d6f6465605d202d204e6f7420696e20666978656420626c75657072696e742073656c656374696f6e206d6f646504c85468652063616c6c61626c652066756e6374696f6e73202865787472696e7369637329206f66207468652070616c6c65742e090604184f7074696f6e0404540191010108104e6f6e6500000010536f6d650400910100000100000d0604184f7074696f6e0404540111060108104e6f6e6500000010536f6d650400110600000100001106104474616e676c655f7072696d6974697665731474797065731c72657761726473384c6f636b4d756c7469706c696572000110204f6e654d6f6e74680001002454776f4d6f6e7468730002002c54687265654d6f6e746873000300245369784d6f6e746873000600001506107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f726c44656c656761746f72426c75657072696e7453656c656374696f6e04344d6178426c75657072696e7473011906010814466978656404001d060198426f756e6465645665633c426c75657072696e7449642c204d6178426c75657072696e74733e0000000c416c6c000100001906085874616e676c655f746573746e65745f72756e74696d65584d617844656c656761746f72426c75657072696e7473000000001d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540130045300000400210601185665633c543e00002106000002300025060c3c70616c6c65745f7365727669636573186d6f64756c651043616c6c040454000138406372656174655f626c75657072696e74040124626c75657072696e742906018053657276696365426c75657072696e743c543a3a436f6e73747261696e74733e0000707c4372656174652061206e6577207365727669636520626c75657072696e742e00810141205365727669636520426c75657072696e7420697320612074656d706c61746520666f722061207365727669636520746861742063616e20626520696e7374616e7469617465642062792075736572732e2054686520626c75657072696e749101646566696e6573207468652073657276696365277320636f6e73747261696e74732c20726571756972656d656e747320616e64206265686176696f722c20696e636c7564696e6720746865206d617374657220626c75657072696e742073657276696365606d616e61676572207265766973696f6e20746f207573652e003423205065726d697373696f6e730019012a20546865206f726967696e206d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206f776e2074686520626c75657072696e74002c2320417267756d656e74730065012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d757374206265207369676e656420627920746865206163636f756e74206372656174696e672074686520626c75657072696e74c42a2060626c75657072696e7460202d20546865207365727669636520626c75657072696e7420636f6e7461696e696e673aa020202d205365727669636520636f6e73747261696e747320616e6420726571756972656d656e7473090120202d204d617374657220626c75657072696e742073657276696365206d616e61676572207265766973696f6e20284c6174657374206f7220537065636966696329d020202d2054656d706c61746520636f6e66696775726174696f6e20666f72207365727669636520696e7374616e74696174696f6e002023204572726f727300b42a205b604572726f723a3a4261644f726967696e605d202d204f726967696e206973206e6f74207369676e65648d012a205b604572726f723a3a4d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64605d202d20537065636966696564204d42534d207265766973696f6e20646f6573206e6f7420657869737459012a205b604572726f723a3a426c75657072696e744372656174696f6e496e746572727570746564605d202d20426c75657072696e74206372656174696f6e20697320696e74657272757074656420627920686f6f6b730024232052657475726e7300850152657475726e73206120604469737061746368526573756c7457697468506f7374496e666f60207768696368206f6e207375636365737320656d6974732061205b604576656e743a3a426c75657072696e7443726561746564605d206576656e7498636f6e7461696e696e6720746865206f776e657220616e6420626c75657072696e742049442e307072655f7265676973746572040130626c75657072696e745f69642c010c75363400017801015072652d7265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e008901546869732066756e6374696f6e20616c6c6f777320616e206163636f756e7420746f207369676e616c20696e74656e7420746f206265636f6d6520616e206f70657261746f7220666f72206120626c75657072696e7420627920656d697474696e677101612060507265526567697374726174696f6e60206576656e742e20546865206f70657261746f72206e6f64652063616e206c697374656e20666f722074686973206576656e7420746f206578656375746520616e7920637573746f6db0726567697374726174696f6e206c6f67696320646566696e656420696e2074686520626c75657072696e742e0071015072652d726567697374726174696f6e20697320746865206669727374207374657020696e20746865206f70657261746f7220726567697374726174696f6e20666c6f772e204166746572207072652d7265676973746572696e672c91016f70657261746f7273206d75737420636f6d706c657465207468652066756c6c20726567697374726174696f6e2070726f636573732062792063616c6c696e6720607265676973746572282960207769746820746865697220707265666572656e6365736c616e6420726567697374726174696f6e20617267756d656e74732e002c2320417267756d656e74730079012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920746865206163636f756e7420746861742077616e747320746f5420206265636f6d6520616e206f70657261746f722e7d012a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f207072652d726567697374657220666f722e204d7573742072656665726c2020746f20616e206578697374696e6720626c75657072696e742e003423205065726d697373696f6e7300982a205468652063616c6c6572206d7573742062652061207369676e6564206163636f756e742e002023204576656e7473005d012a205b604576656e743a3a507265526567697374726174696f6e605d202d20456d6974746564207768656e207072652d726567697374726174696f6e206973207375636365737366756c2c20636f6e7461696e696e673a350120202d20606f70657261746f723a20543a3a4163636f756e74496460202d20546865206163636f756e74204944206f6620746865207072652d7265676973746572696e67206f70657261746f72290120202d2060626c75657072696e745f69643a2075363460202d20546865204944206f662074686520626c75657072696e74206265696e67207072652d7265676973746572656420666f72002023204572726f727300cc2a205b604572726f723a3a4261644f726967696e605d202d20546865206f726967696e20776173206e6f74207369676e65642e207265676973746572100130626c75657072696e745f69642c010c75363400012c707265666572656e636573f901014c4f70657261746f72507265666572656e636573000144726567697374726174696f6e5f61726773050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e00011476616c75656d01013042616c616e63654f663c543e00026cf05265676973746572207468652063616c6c657220617320616e206f70657261746f7220666f72206120737065636966696320626c75657072696e742e007501546869732066756e6374696f6e20616c6c6f777320616e206163636f756e7420746f20726567697374657220617320616e206f70657261746f7220666f72206120626c75657072696e742062792070726f766964696e672074686569727d017365727669636520707265666572656e6365732c20726567697374726174696f6e20617267756d656e74732c20616e64207374616b696e672074686520726571756972656420746f6b656e732e20546865206f70657261746f72206d757374790162652061637469766520696e207468652064656c65676174696f6e2073797374656d20616e64206d6179207265717569726520617070726f76616c206265666f726520616363657074696e6720736572766963652072657175657374732e003423205065726d697373696f6e7300942a205468652063616c6c6572206d7573742062652061207369676e6564206163636f756e7401012a205468652063616c6c6572206d75737420626520616e20616374697665206f70657261746f7220696e207468652064656c65676174696f6e2073797374656df82a205468652063616c6c6572206d757374206e6f7420616c7265616479206265207265676973746572656420666f72207468697320626c75657072696e74002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e29012a2060626c75657072696e745f696460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f20726567697374657220666f7219012a2060707265666572656e63657360202d20546865206f70657261746f722773207365727669636520707265666572656e63657320616e6420636f6e66696775726174696f6e21012a2060726567697374726174696f6e5f6172677360202d20526567697374726174696f6e20617267756d656e74732072657175697265642062792074686520626c75657072696e74d82a206076616c756560202d20416d6f756e74206f6620746f6b656e7320746f207374616b6520666f7220726567697374726174696f6e002023204572726f72730069012a205b604572726f723a3a4f70657261746f724e6f74416374697665605d202d2043616c6c6572206973206e6f7420616e20616374697665206f70657261746f7220696e207468652064656c65676174696f6e2073797374656d41012a205b604572726f723a3a416c726561647952656769737465726564605d202d2043616c6c657220697320616c7265616479207265676973746572656420666f72207468697320626c75657072696e7411012a205b604572726f723a3a54797065436865636b605d202d20526567697374726174696f6e20617267756d656e7473206661696c6564207479706520636865636b696e674d012a205b604572726f723a3a496e76616c6964526567697374726174696f6e496e707574605d202d20526567697374726174696f6e20686f6f6b2072656a65637465642074686520726567697374726174696f6e65012a205b604572726f723a3a4d6178536572766963657350657250726f76696465724578636565646564605d202d204f70657261746f72206861732072656163686564206d6178696d756d207365727669636573206c696d697428756e7265676973746572040130626c75657072696e745f69642c010c75363400034c0501556e726567697374657273206120736572766963652070726f76696465722066726f6d2061207370656369666963207365727669636520626c75657072696e742e009101416674657220756e7265676973746572696e672c207468652070726f76696465722077696c6c206e6f206c6f6e6765722072656365697665206e657720736572766963652061737369676e6d656e747320666f72207468697320626c75657072696e742e8501486f77657665722c2074686579206d75737420636f6e74696e756520736572766963696e6720616e79206163746976652061737369676e6d656e747320756e74696c20636f6d706c6574696f6e20746f2061766f69642070656e616c746965732e002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e39012a2060626c75657072696e745f696460202d20546865206964656e746966696572206f6620746865207365727669636520626c75657072696e7420746f20756e72656769737465722066726f6d2e003423205065726d697373696f6e7300c42a204d757374206265207369676e65642062792061207265676973746572656420736572766963652070726f7669646572002023204572726f72730031012a205b604572726f723a3a4e6f7452656769737465726564605d202d205468652063616c6c6572206973206e6f74207265676973746572656420666f72207468697320626c75657072696e7431012a205b604572726f723a3a4e6f74416c6c6f776564546f556e7265676973746572605d202d20556e726567697374726174696f6e2069732063757272656e746c79207265737472696374656401012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f74206578697374507570646174655f70726963655f74617267657473080130626c75657072696e745f69642c010c75363400013470726963655f746172676574730102013050726963655461726765747300045021015570646174657320746865207072696365207461726765747320666f7220612072656769737465726564206f70657261746f722773207365727669636520626c75657072696e742e008901416c6c6f777320616e206f70657261746f7220746f206d6f64696679207468656972207072696365207461726765747320666f72206120737065636966696320626c75657072696e74207468657920617265207265676973746572656420666f722e2d01546865206f70657261746f72206d75737420616c7265616479206265207265676973746572656420666f722074686520626c75657072696e7420746f20757064617465207072696365732e002c2320417267756d656e74730049012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920746865206f70657261746f722e51012a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f662074686520626c75657072696e7420746f20757064617465207072696365207461726765747320666f722e45012a206070726963655f746172676574733a2050726963655461726765747360202d20546865206e6577207072696365207461726765747320746f2073657420666f722074686520626c75657072696e742e003423205065726d697373696f6e7300f42a204d757374206265207369676e656420627920612072656769737465726564206f70657261746f7220666f72207468697320626c75657072696e742e002023204572726f72730035012a205b604572726f723a3a4e6f7452656769737465726564605d202d205468652063616c6c6572206973206e6f74207265676973746572656420666f72207468697320626c75657072696e742e71012a205b604572726f723a3a4e6f74416c6c6f776564546f557064617465507269636554617267657473605d202d205072696365207461726765742075706461746573206172652063757272656e746c7920726573747269637465642e05012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f742065786973742e1c7265717565737424012865766d5f6f726967696e090601304f7074696f6e3c483136303e000130626c75657072696e745f69642c010c7536340001447065726d69747465645f63616c6c657273350201445665633c543a3a4163636f756e7449643e0001246f70657261746f7273350201445665633c543a3a4163636f756e7449643e000130726571756573745f61726773050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e0001186173736574733902013c5665633c543a3a417373657449643e00010c74746c2c0144426c6f636b4e756d626572466f723c543e0001347061796d656e745f6173736574f101014441737365743c543a3a417373657449643e00011476616c75656d01013042616c616e63654f663c543e0005700101526571756573742061206e65772073657276696365207573696e67206120626c75657072696e7420616e6420737065636966696564206f70657261746f72732e002c2320417267756d656e74730009012a20606f726967696e3a204f726967696e466f723c543e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e1d012a206065766d5f6f726967696e3a204f7074696f6e3c483136303e60202d204f7074696f6e616c2045564d206164647265737320666f72204552433230207061796d656e74732efc2a2060626c75657072696e745f69643a2075363460202d20546865206964656e746966696572206f662074686520626c75657072696e7420746f207573652ebd012a20607065726d69747465645f63616c6c6572733a205665633c543a3a4163636f756e7449643e60202d204163636f756e747320616c6c6f77656420746f2063616c6c2074686520736572766963652e20496620656d7074792c206f6e6c79206f776e65722063616e2063616c6c2e3d012a20606f70657261746f72733a205665633c543a3a4163636f756e7449643e60202d204c697374206f66206f70657261746f727320746861742077696c6c2072756e2074686520736572766963652e81012a2060726571756573745f617267733a205665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e60202d20426c75657072696e7420696e697469616c697a6174696f6e20617267756d656e74732ef82a20606173736574733a205665633c543a3a417373657449643e60202d2052657175697265642061737365747320666f722074686520736572766963652e31012a206074746c3a20426c6f636b4e756d626572466f723c543e60202d2054696d652d746f2d6c69766520696e20626c6f636b7320666f7220746865207365727669636520726571756573742e61012a20607061796d656e745f61737365743a2041737365743c543a3a417373657449643e60202d204173736574207573656420666f72207061796d656e7420286e61746976652c20637573746f6d206f72204552433230292ee42a206076616c75653a2042616c616e63654f663c543e60202d205061796d656e7420616d6f756e7420666f722074686520736572766963652e003423205065726d697373696f6e730039012a204d757374206265207369676e656420627920616e206163636f756e7420776974682073756666696369656e742062616c616e636520746f2070617920666f722074686520736572766963652e31012a20466f72204552433230207061796d656e74732c207468652045564d206f726967696e206d757374206d61746368207468652063616c6c65722773206d6170706564206163636f756e742e002023204572726f72730021012a205b604572726f723a3a54797065436865636b605d202d205265717565737420617267756d656e7473206661696c20626c75657072696e74207479706520636865636b696e672ee42a205b604572726f723a3a4e6f41737365747350726f7669646564605d202d204e6f206173736574732077657265207370656369666965642e5d012a205b604572726f723a3a4d697373696e6745564d4f726967696e605d202d2045564d206f726967696e20726571756972656420627574206e6f742070726f766964656420666f72204552433230207061796d656e742efc2a205b604572726f723a3a45524332305472616e736665724661696c6564605d202d20455243323020746f6b656e207472616e73666572206661696c65642e41012a205b604572726f723a3a4e6f7452656769737465726564605d202d204f6e65206f72206d6f7265206f70657261746f7273206e6f74207265676973746572656420666f7220626c75657072696e742e05012a205b604572726f723a3a426c75657072696e744e6f74466f756e64605d202d2054686520626c75657072696e745f696420646f6573206e6f742065786973742e1c617070726f7665080128726571756573745f69642c010c75363400014472657374616b696e675f70657263656e74ed06011c50657263656e740006448101417070726f76652061207365727669636520726571756573742c20616c6c6f77696e6720697420746f20626520696e69746961746564206f6e636520616c6c20726571756972656420617070726f76616c73206172652072656365697665642e003423205065726d697373696f6e730001012a2043616c6c6572206d75737420626520612072656769737465726564206f70657261746f7220666f7220746865207365727669636520626c75657072696e74fc2a2043616c6c6572206d75737420626520696e207468652070656e64696e6720617070726f76616c73206c69737420666f7220746869732072657175657374002c2320417267756d656e747300f42a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d7573742062652061207369676e6564206163636f756e74e42a2060726571756573745f696460202d20546865204944206f66207468652073657276696365207265717565737420746f20617070726f766555012a206072657374616b696e675f70657263656e7460202d2050657263656e74616765206f66207374616b656420746f6b656e7320746f206578706f736520746f207468697320736572766963652028302d31303029002023204572726f7273003d012a205b604572726f723a3a417070726f76616c4e6f74526571756573746564605d202d2043616c6c6572206973206e6f7420696e207468652070656e64696e6720617070726f76616c73206c69737429012a205b604572726f723a3a417070726f76616c496e746572727570746564605d202d20417070726f76616c207761732072656a656374656420627920626c75657072696e7420686f6f6b1872656a656374040128726571756573745f69642c010c753634000750d052656a6563742061207365727669636520726571756573742c2070726576656e74696e672069747320696e6974696174696f6e2e006101546865207365727669636520726571756573742077696c6c2072656d61696e20696e207468652073797374656d20627574206d61726b65642061732072656a65637465642e20546865207265717565737465722077696c6cb86e65656420746f20757064617465207468652073657276696365207265717565737420746f2070726f636565642e003423205065726d697373696f6e730055012a2043616c6c6572206d75737420626520612072656769737465726564206f70657261746f7220666f722074686520626c75657072696e74206173736f63696174656420776974682074686973207265717565737419012a2043616c6c6572206d757374206265206f6e65206f6620746865206f70657261746f727320726571756972656420746f20617070726f766520746869732072657175657374002c2320417267756d656e747300f42a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2c206d7573742062652061207369676e6564206163636f756e74e02a2060726571756573745f696460202d20546865204944206f66207468652073657276696365207265717565737420746f2072656a656374002023204572726f7273009d012a205b604572726f723a3a417070726f76616c4e6f74526571756573746564605d202d2043616c6c6572206973206e6f74206f6e65206f6620746865206f70657261746f727320726571756972656420746f20617070726f76652074686973207265717565737499012a205b604572726f723a3a45787065637465644163636f756e744964605d202d204661696c656420746f20636f6e7665727420726566756e64206164647265737320746f206163636f756e74204944207768656e20726566756e64696e67207061796d656e743d012a205b604572726f723a3a52656a656374696f6e496e746572727570746564605d202d2052656a656374696f6e2077617320696e74657272757074656420627920626c75657072696e7420686f6f6b247465726d696e617465040128736572766963655f69642c010c753634000844985465726d696e6174657320612072756e6e696e67207365727669636520696e7374616e63652e003423205065726d697373696f6e7300942a204d757374206265207369676e6564206279207468652073657276696365206f776e6572002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6cec2a2060736572766963655f696460202d20546865206964656e746966696572206f6620746865207365727669636520746f207465726d696e617465002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374f02a205b604572726f723a3a4e6f7452656769737465726564605d202d2053657276696365206f70657261746f72206e6f74207265676973746572656449012a205b604572726f723a3a5465726d696e6174696f6e496e746572727570746564605d202d2053657276696365207465726d696e6174696f6e2077617320696e74657272757074656420627920686f6f6b7301012a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f74207468652073657276696365206f776e65721063616c6c0c0128736572766963655f69642c010c75363400010c6a6f62f1060108753800011061726773050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000954d843616c6c2061206a6f6220696e2074686520736572766963652077697468207468652070726f766964656420617267756d656e74732e003423205065726d697373696f6e7300ec2a204d757374206265207369676e6564206279207468652073657276696365206f776e6572206f722061207065726d69747465642063616c6c6572002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c9c2a2060736572766963655f696460202d205468652073657276696365206964656e7469666965727c2a20606a6f6260202d20546865206a6f6220696e64657820746f2063616c6cac2a20606172677360202d2054686520617267756d656e747320746f207061737320746f20746865206a6f62002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374f42a205b604572726f723a3a4a6f62446566696e6974696f6e4e6f74466f756e64605d202d20546865206a6f6220696e64657820697320696e76616c6964f02a205b604572726f723a3a4d61784669656c64734578636565646564605d202d20546f6f206d616e7920617267756d656e74732070726f7669646564d42a205b604572726f723a3a54797065436865636b605d202d20417267756d656e7473206661696c207479706520636865636b696e6705012a205b604572726f723a3a496e76616c69644a6f6243616c6c496e707574605d202d204a6f622063616c6c207761732072656a656374656420627920686f6f6b7321012a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f74206f776e6572206f72207065726d69747465642063616c6c6572347375626d69745f726573756c740c0128736572766963655f69642c010c75363400011c63616c6c5f69642c010c753634000118726573756c74050201a05665633c4669656c643c543a3a436f6e73747261696e74732c20543a3a4163636f756e7449643e3e000a54b05375626d6974206120726573756c7420666f7220612070726576696f75736c792063616c6c6564206a6f622e002c2320417267756d656e747300882a2060736572766963655f696460202d204944206f66207468652073657276696365802a206063616c6c5f696460202d204944206f6620746865206a6f622063616c6c902a2060726573756c7460202d20566563746f72206f6620726573756c74206669656c6473003423205065726d697373696f6e7300ac2a2043616c6c6572206d75737420626520616e206f70657261746f72206f66207468652073657276696365002023204572726f727300f02a205b604572726f723a3a536572766963654e6f74466f756e64605d202d2054686520736572766963655f696420646f6573206e6f74206578697374e42a205b604572726f723a3a4a6f6243616c6c4e6f74466f756e64605d202d205468652063616c6c5f696420646f6573206e6f74206578697374f42a205b604572726f723a3a4a6f62446566696e6974696f6e4e6f74466f756e64605d202d20546865206a6f6220696e64657820697320696e76616c696401012a205b604572726f723a3a4d61784669656c64734578636565646564605d202d20546f6f206d616e7920726573756c74206669656c64732070726f7669646564e42a205b604572726f723a3a54797065436865636b605d202d20526573756c74206669656c6473206661696c207479706520636865636b696e6701012a205b604572726f723a3a496e76616c69644a6f62526573756c74605d202d204a6f6220726573756c74207761732072656a656374656420627920686f6f6b73e82a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f7420616e206f70657261746f7214736c6173680c01206f6666656e646572000130543a3a4163636f756e744964000128736572766963655f69642c010c75363400011c70657263656e74ed06011c50657263656e74000b604501536c61736820616e206f70657261746f722773207374616b6520666f7220612073657276696365206279207363686564756c696e67206120646566657272656420736c617368696e6720616374696f6e2e009901546869732066756e6374696f6e207363686564756c6573206120646566657272656420736c617368696e6720616374696f6e20616761696e737420616e206f70657261746f722773207374616b6520666f72206120737065636966696320736572766963652e7d0154686520736c617368206973206e6f74206170706c69656420696d6d6564696174656c792c20627574207261746865722071756575656420746f20626520657865637574656420627920616e6f7468657220656e74697479206c617465722e003423205065726d697373696f6e730061012a205468652063616c6c6572206d75737420626520616e20617574686f72697a656420536c617368204f726967696e20666f72207468652074617267657420736572766963652c2061732064657465726d696e65642062797d0120206071756572795f736c617368696e675f6f726967696e602e204966206e6f20736c617368696e67206f726967696e206973207365742c206f72207468652063616c6c657220646f6573206e6f74206d617463682c207468652063616c6c30202077696c6c206661696c2e002c2320417267756d656e74730049012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e20617574686f72697a656420536c617368204f726967696e2ef02a20606f6666656e64657260202d20546865206163636f756e74204944206f6620746865206f70657261746f7220746f20626520736c61736865642e1d012a2060736572766963655f696460202d20546865204944206f6620746865207365727669636520666f7220776869636820746f20736c61736820746865206f70657261746f722e71012a206070657263656e7460202d205468652070657263656e74616765206f6620746865206f70657261746f722773206578706f736564207374616b6520746f20736c6173682c2061732061206050657263656e74602076616c75652e002023204572726f72730001012a20604e6f536c617368696e674f726967696e60202d204e6f20736c617368696e67206f726967696e2069732073657420666f72207468652073657276696365f02a20604261644f726967696e60202d2043616c6c6572206973206e6f742074686520617574686f72697a656420736c617368696e67206f726967696e31012a20604f6666656e6465724e6f744f70657261746f7260202d20546172676574206163636f756e74206973206e6f7420616e206f70657261746f7220666f72207468697320736572766963651d012a20604f6666656e6465724e6f744163746976654f70657261746f7260202d20546172676574206f70657261746f72206973206e6f742063757272656e746c79206163746976651c6469737075746508010c6572616902010c753332000114696e6465786902010c753332000c4cd8446973707574657320616e642072656d6f76657320616e205b556e6170706c696564536c6173685d2066726f6d2073746f726167652e001d0154686520736c6173682077696c6c206e6f74206265206170706c696564206f6e636520646973707574656420616e64206973207065726d616e656e746c792072656d6f7665642e003423205065726d697373696f6e7300f82a2043616c6c6572206d7573742062652074686520617574686f72697a65642064697370757465206f726967696e20666f72207468652073657276696365002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cbc2a206065726160202d2045726120636f6e7461696e696e672074686520736c61736820746f20646973707574652020b42a2060696e64657860202d20496e646578206f662074686520736c6173682077697468696e2074686520657261002023204572726f72730015012a205b4572726f723a3a4e6f446973707574654f726967696e5d202d205365727669636520686173206e6f2064697370757465206f726967696e20636f6e6669677572656429012a205b44697370617463684572726f723a3a4261644f726967696e5d202d2043616c6c6572206973206e6f742074686520617574686f72697a65642064697370757465206f726967696e009c7570646174655f6d61737465725f626c75657072696e745f736572766963655f6d616e6167657204011c616464726573739101011048313630000d3819015570646174657320746865204d617374657220426c75657072696e742053657276696365204d616e6167657220627920616464696e672061206e6577207265766973696f6e2e003423205065726d697373696f6e730035012a2043616c6c6572206d75737420626520616e20617574686f72697a6564204d617374657220426c75657072696e742053657276696365204d616e6167657220557064617465204f726967696e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6ca02a20606164647265737360202d204e6577206d616e61676572206164647265737320746f20616464002023204572726f72730085012a205b4572726f723a3a4d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e7345786365656465645d202d204d6178696d756d206e756d626572206f66207265766973696f6e732072656163686564040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e29060c4474616e676c655f7072696d6974697665732073657276696365734053657276696365426c75657072696e7404044300001c01206d657461646174612d060148536572766963654d657461646174613c433e0001106a6f62733d0601c8426f756e6465645665633c4a6f62446566696e6974696f6e3c433e2c20433a3a4d61784a6f6273506572536572766963653e00014c726567697374726174696f6e5f706172616d734906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000138726571756573745f706172616d734906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e00011c6d616e616765726506015c426c75657072696e74536572766963654d616e6167657200015c6d61737465725f6d616e616765725f7265766973696f6e690601944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e0001186761646765746d0601244761646765743c433e00002d060c4474616e676c655f7072696d6974697665732073657276696365733c536572766963654d6574616461746104044300002001106e616d653106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000118617574686f72390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00012063617465676f7279390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00013c636f64655f7265706f7369746f7279390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e0001106c6f676f390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c77656273697465390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00011c6c6963656e7365390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e00003106104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040035060144426f756e6465645665633c75382c20533e000035060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000390604184f7074696f6e0404540131060108104e6f6e6500000010536f6d650400310600000100003d060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014106045300000400610601185665633c543e000041060c4474616e676c655f7072696d697469766573207365727669636573344a6f62446566696e6974696f6e04044300000c01206d65746164617461450601384a6f624d657461646174613c433e000118706172616d734906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000118726573756c744906018c426f756e6465645665633c4669656c64547970652c20433a3a4d61784669656c64733e000045060c4474616e676c655f7072696d6974697665732073657276696365732c4a6f624d6574616461746104044300000801106e616d653106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e00012c6465736372697074696f6e390601ac4f7074696f6e3c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e3e000049060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014d060453000004005d0601185665633c543e00004d06104474616e676c655f7072696d697469766573207365727669636573146669656c64244669656c645479706500014410566f696400000010426f6f6c0001001455696e743800020010496e74380003001855696e74313600040014496e7431360005001855696e74333200060014496e7433320007001855696e74363400080014496e74363400090018537472696e67000a00144279746573000b00204f7074696f6e616c04004d060138426f783c4669656c64547970653e000c00144172726179080030010c75363400004d060138426f783c4669656c64547970653e000d00104c69737404004d060138426f783c4669656c64547970653e000e001853747275637408004d060138426f783c4669656c64547970653e0000510601e8426f756e6465645665633c28426f783c4669656c64547970653e2c20426f783c4669656c64547970653e292c20436f6e73745533323c33323e3e000f00244163636f756e7449640064000051060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454015506045300000400590601185665633c543e00005506000004084d064d060059060000025506005d060000024d0600610600000241060065060c4474616e676c655f7072696d6974697665732073657276696365735c426c75657072696e74536572766963654d616e616765720001040c45766d04009101013473705f636f72653a3a483136300000000069060c4474616e676c655f7072696d697469766573207365727669636573944d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e000108184c6174657374000000205370656369666963040010010c753332000100006d060c4474616e676c655f7072696d6974697665732073657276696365731847616467657404044300010c105761736d0400710601345761736d4761646765743c433e000000184e61746976650400e506013c4e61746976654761646765743c433e00010024436f6e7461696e65720400e9060148436f6e7461696e65724761646765743c433e0002000071060c4474616e676c655f7072696d697469766573207365727669636573285761736d476164676574040443000008011c72756e74696d657506012c5761736d52756e74696d6500011c736f7572636573790601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e000075060c4474616e676c655f7072696d6974697665732073657276696365732c5761736d52756e74696d65000108205761736d74696d65000000185761736d65720001000079060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017d06045300000400e10601185665633c543e00007d060c4474616e676c655f7072696d69746976657320736572766963657330476164676574536f75726365040443000004011c6665746368657281060158476164676574536f75726365466574636865723c433e000081060c4474616e676c655f7072696d6974697665732073657276696365734c476164676574536f75726365466574636865720404430001101049504653040085060190426f756e6465645665633c75382c20433a3a4d617849706673486173684c656e6774683e00000018476974687562040089060140476974687562466574636865723c433e00010038436f6e7461696e6572496d6167650400c106015c496d6167655265676973747279466574636865723c433e0002001c54657374696e670400dd06013854657374466574636865723c433e0003000085060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000089060c4474616e676c655f7072696d697469766573207365727669636573344769746875624665746368657204044300001001146f776e65728d06018c426f756e646564537472696e673c433a3a4d61784769744f776e65724c656e6774683e0001107265706f95060188426f756e646564537472696e673c433a3a4d61784769745265706f4c656e6774683e00010c7461679d060184426f756e646564537472696e673c433a3a4d61784769745461674c656e6774683e00012062696e6172696573a50601d0426f756e6465645665633c47616467657442696e6172793c433e2c20433a3a4d617842696e61726965735065724761646765743e00008d06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040091060144426f756e6465645665633c75382c20533e000091060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00009506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e670404530000040099060144426f756e6465645665633c75382c20533e000099060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00009d06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400a1060144426f756e6465645665633c75382c20533e0000a1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000a5060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401a906045300000400bd0601185665633c543e0000a9060c4474616e676c655f7072696d6974697665732073657276696365733047616467657442696e617279040443000010011061726368ad0601304172636869746563747572650001086f73b106013c4f7065726174696e6753797374656d0001106e616d65b5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e0001187368613235360401205b75383b2033325d0000ad060c4474616e676c655f7072696d69746976657320736572766963657330417263686974656374757265000128105761736d000000185761736d36340001001057617369000200185761736936340003000c416d6400040014416d6436340005000c41726d0006001441726d36340007001452697363560008001c5269736356363400090000b1060c4474616e676c655f7072696d6974697665732073657276696365733c4f7065726174696e6753797374656d0001141c556e6b6e6f776e000000144c696e75780001001c57696e646f7773000200144d61634f530003000c42534400040000b506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400b9060144426f756e6465645665633c75382c20533e0000b9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000bd06000002a90600c1060c4474616e676c655f7072696d69746976657320736572766963657350496d61676552656769737472794665746368657204044300000c01207265676973747279c50601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e657252656769737472794c656e6774683e000114696d616765cd0601b4426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167654e616d654c656e6774683e00010c746167d50601b0426f756e646564537472696e673c433a3a4d6178436f6e7461696e6572496d6167655461674c656e6774683e0000c506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400c9060144426f756e6465645665633c75382c20533e0000c9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000cd06104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400d1060144426f756e6465645665633c75382c20533e0000d1060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000d506104474616e676c655f7072696d697469766573207365727669636573146669656c6434426f756e646564537472696e6704045300000400d9060144426f756e6465645665633c75382c20533e0000d9060c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000dd060c4474616e676c655f7072696d6974697665732073657276696365732c546573744665746368657204044300000c0134636172676f5f7061636b616765b5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124636172676f5f62696eb5060194426f756e646564537472696e673c433a3a4d617842696e6172794e616d654c656e6774683e000124626173655f706174683106018c426f756e646564537472696e673c433a3a4d61784d657461646174614c656e6774683e0000e1060000027d0600e5060c4474616e676c655f7072696d697469766573207365727669636573304e6174697665476164676574040443000004011c736f7572636573790601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000e9060c4474616e676c655f7072696d6974697665732073657276696365733c436f6e7461696e6572476164676574040443000004011c736f7572636573790601cc426f756e6465645665633c476164676574536f757263653c433e2c20433a3a4d6178536f75726365735065724761646765743e0000ed06000006550200f1060000060800f5060c4470616c6c65745f74616e676c655f6c73741870616c6c65741043616c6c040454000150106a6f696e080118616d6f756e746d01013042616c616e63654f663c543e00011c706f6f6c5f6964100118506f6f6c49640000585d015374616b65732066756e64732077697468206120706f6f6c206279207472616e7366657272696e672074686520626f6e64656420616d6f756e742066726f6d206d656d62657220746f20706f6f6c206163636f756e742e003423205065726d697373696f6e7300402a204d757374206265207369676e6564002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c702a2060616d6f756e7460202d20416d6f756e7420746f207374616b65702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944002023204572726f727300e82a205b604572726f723a3a4d696e696d756d426f6e644e6f744d6574605d202d20416d6f756e742062656c6f77206d696e696d756d20626f6e64bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374cc2a205b604572726f723a3a446566656e736976654572726f72605d202d2052657761726420706f6f6c206e6f7420666f756e64001823204e6f746500f02a204d656d626572206d757374206861766520606578697374656e7469616c206465706f736974202b20616d6f756e746020696e206163636f756e74ac2a20506f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a4f70656e605d20737461746528626f6e645f657874726108011c706f6f6c5f6964100118506f6f6c49640001146578747261f906015c426f6e6445787472613c42616c616e63654f663c543e3e00016cd4426f6e64206164646974696f6e616c2066756e647320696e746f20616e206578697374696e6720706f6f6c20706f736974696f6e2e0029014164646974696f6e616c2066756e64732063616e20636f6d652066726f6d2065697468657220667265652062616c616e6365206f7220616363756d756c6174656420726577617264732eac4175746f6d61746963616c6c792070617973206f757420616c6c2070656e64696e6720726577617264732e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944c42a2060657874726160202d20536f7572636520616e6420616d6f756e74206f66206164646974696f6e616c2066756e6473003423205065726d697373696f6e7300402a204d757374206265207369676e6564c02a204d7573742068617665207065726d697373696f6e20746f20626f6e64206578747261206966206e6f742073656c66002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f02a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b73207065726d697373696f6ecc2a205b604572726f723a3a446566656e736976654572726f72605d202d2052657761726420706f6f6c206e6f7420666f756e64001823204e6f74650031012a2054686973207472616e73616374696f6e207072696f726974697a657320726561646162696c69747920616e6420636f72726563746e657373206f766572206f7074696d697a6174696f6eec2a204d756c7469706c652073746f726167652072656164732f7772697465732061726520706572666f726d656420746f20726575736520636f646505012a205365652060626f6e645f65787472615f6f746865726020746f20626f6e642070656e64696e672072657761726473206f66206f74686572206d656d6265727318756e626f6e640c01386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c4964000140756e626f6e64696e675f706f696e74736d01013042616c616e63654f663c543e0003743101556e626f6e6420706f696e74732066726f6d2061206d656d626572277320706f6f6c20706f736974696f6e2c20636f6c6c656374696e6720616e792070656e64696e6720726577617264732e002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a20606d656d6265725f6163636f756e7460202d204163636f756e7420746f20756e626f6e642066726f6d702a2060706f6f6c5f696460202d2054617267657420706f6f6c204944c42a2060756e626f6e64696e675f706f696e747360202d20416d6f756e74206f6620706f696e747320746f20756e626f6e64003423205065726d697373696f6e7300502a205065726d697373696f6e6c6573732069663ad420202d20506f6f6c20697320626c6f636b656420616e642063616c6c657220697320726f6f742f626f756e63657220286b69636b29c820202d20506f6f6c2069732064657374726f79696e6720616e64206d656d626572206973206e6f74206465706f7369746f72f820202d20506f6f6c2069732064657374726f79696e672c206d656d626572206973206465706f7369746f722c20616e6420706f6f6c20697320656d707479a82a205065726d697373696f6e6564202863616c6c6572206d757374206265206d656d626572292069663a6c20202d2043616c6c6572206973206e6f74206465706f7369746f72f820202d2043616c6c6572206973206465706f7369746f722c20706f6f6c2069732064657374726f79696e672c20616e6420706f6f6c20697320656d707479002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374fc2a205b604572726f723a3a4e6f42616c616e6365546f556e626f6e64605d202d204d656d6265722068617320696e73756666696369656e7420706f696e7473f42a205b604572726f723a3a446566656e736976654572726f72605d202d204e6f7420656e6f75676820737061636520696e20756e626f6e6420706f6f6c001823204e6f74656d014966206e6f20756e6c6f636b696e67206368756e6b732061726520617661696c61626c652c205b6043616c6c3a3a706f6f6c5f77697468647261775f756e626f6e646564605d2063616e2062652063616c6c65642066697273742e6501546865207374616b696e6720696e746572666163652077696c6c20617474656d70742074686973206175746f6d61746963616c6c7920627574206d6179207374696c6c2072657475726e20604e6f4d6f72654368756e6b7360746966206368756e6b732063616e6e6f742062652072656c65617365642e58706f6f6c5f77697468647261775f756e626f6e64656408011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c75333200044ce457697468647261777320756e626f6e6465642066756e64732066726f6d2074686520706f6f6c2773207374616b696e67206163636f756e742e00390155736566756c20666f7220636c656172696e6720756e6c6f636b696e67206368756e6b73207768656e2074686572652061726520746f6f206d616e7920746f2063616c6c2060756e626f6e64602edc50726576656e747320604e6f4d6f72654368756e6b7360206572726f72732066726f6d20746865207374616b696e672073797374656d2e003423205065726d697373696f6e7300782a2043616e206265207369676e656420627920616e79206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572e82a20606e756d5f736c617368696e675f7370616e7360202d204e756d626572206f6620736c617368696e67207370616e7320746f20636865636b002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374e02a205b604572726f723a3a4e6f7444657374726f79696e67605d202d20506f6f6c20697320696e2064657374726f79696e672073746174654477697468647261775f756e626f6e6465640c01386d656d6265725f6163636f756e74c50201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001486e756d5f736c617368696e675f7370616e7310010c753332000564b8576974686472617720756e626f6e6465642066756e64732066726f6d2061206d656d626572206163636f756e742e003423205065726d697373696f6e7300502a205065726d697373696f6e6c6573732069663adc20202d20506f6f6c20697320696e2064657374726f79206d6f646520616e6420746172676574206973206e6f74206465706f7369746f72d020202d20546172676574206973206465706f7369746f7220616e64206f6e6c79206d656d62657220696e2073756220706f6f6c73b820202d20506f6f6c20697320626c6f636b656420616e642063616c6c657220697320726f6f742f626f756e636572d02a205065726d697373696f6e65642069662063616c6c65722069732074617267657420616e64206e6f74206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cb42a20606d656d6265725f6163636f756e7460202d204163636f756e7420746f2077697468647261772066726f6d742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572c42a20606e756d5f736c617368696e675f7370616e7360202d204e756d626572206f6620736c617368696e67207370616e73002023204572726f727300e82a205b604572726f723a3a506f6f6c4d656d6265724e6f74466f756e64605d202d204d656d626572206163636f756e74206e6f7420666f756e64bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374cc2a205b604572726f723a3a537562506f6f6c734e6f74466f756e64605d202d2053756220706f6f6c73206e6f7420666f756e64f02a205b604572726f723a3a43616e6e6f745769746864726177416e79605d202d204e6f20756e626f6e6465642066756e647320617661696c61626c6500bc496620746172676574206973206465706f7369746f722c20706f6f6c2077696c6c2062652064657374726f7965642e18637265617465180118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c50201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c50201504163636f756e7449644c6f6f6b75704f663c543e0001106e616d65fd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6e050701a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e00065c744372656174652061206e65772064656c65676174696f6e20706f6f6c2e003423205065726d697373696f6e730019012a204d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206265636f6d652074686520696e697469616c206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a2060616d6f756e7460202d20416d6f756e7420746f2064656c656761746520746f2074686520706f6f6c982a2060726f6f7460202d204163636f756e7420746f2073657420617320706f6f6c20726f6f74c02a20606e6f6d696e61746f7260202d204163636f756e7420746f2073657420617320706f6f6c206e6f6d696e61746f72b02a2060626f756e63657260202d204163636f756e7420746f2073657420617320706f6f6c20626f756e636572ec2a20606e616d6560202d204f7074696f6e616c20706f6f6c206e616d6520626f756e6465642062792060543a3a4d61784e616d654c656e67746860ec2a206069636f6e60202d204f7074696f6e616c20706f6f6c2069636f6e20626f756e6465642062792060543a3a4d617849636f6e4c656e67746860002023204572726f727300f02a205b604572726f723a3a4f766572666c6f775269736b605d202d20506f6f6c20494420696e6372656d656e7420776f756c64206f766572666c6f77001823204e6f7465000d0143616c6c6572206d75737420686176652060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652066756e64732e4c6372656174655f776974685f706f6f6c5f69641c0118616d6f756e746d01013042616c616e63654f663c543e000110726f6f74c50201504163636f756e7449644c6f6f6b75704f663c543e0001246e6f6d696e61746f72c50201504163636f756e7449644c6f6f6b75704f663c543e00011c626f756e636572c50201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001106e616d65fd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6e050701a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e000764f04372656174652061206e65772064656c65676174696f6e20706f6f6c207769746820612070726576696f75736c79207573656420706f6f6c2049442e003423205065726d697373696f6e7300f82a204d757374206265207369676e656420627920746865206163636f756e7420746861742077696c6c206265636f6d6520746865206465706f7369746f72002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6cac2a2060616d6f756e7460202d20416d6f756e7420746f2064656c656761746520746f2074686520706f6f6c982a2060726f6f7460202d204163636f756e7420746f2073657420617320706f6f6c20726f6f74c02a20606e6f6d696e61746f7260202d204163636f756e7420746f2073657420617320706f6f6c206e6f6d696e61746f72b02a2060626f756e63657260202d204163636f756e7420746f2073657420617320706f6f6c20626f756e636572782a2060706f6f6c5f696460202d20506f6f6c20494420746f207265757365742a20606e616d6560202d204f7074696f6e616c20706f6f6c206e616d65742a206069636f6e60202d204f7074696f6e616c20706f6f6c2069636f6e002023204572726f727300d02a205b604572726f723a3a506f6f6c4964496e557365605d202d20506f6f6c20494420697320616c726561647920696e2075736505012a205b604572726f723a3a496e76616c6964506f6f6c4964605d202d20506f6f6c2049442069732067726561746572207468616e206c61737420706f6f6c204944001823204e6f7465000d0143616c6c6572206d75737420686176652060616d6f756e74202b206578697374656e7469616c5f6465706f73697460207472616e7366657261626c652066756e64732e206e6f6d696e61746508011c706f6f6c5f6964100118506f6f6c496400012876616c696461746f7273350201445665633c543a3a4163636f756e7449643e000850a84e6f6d696e6174652076616c696461746f7273206f6e20626568616c66206f662074686520706f6f6c2e003423205065726d697373696f6e7300d42a20506f6f6c206e6f6d696e61746f72206f7220726f6f7420726f6c652063616e206e6f6d696e6174652076616c696461746f7273002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572dc2a206076616c696461746f727360202d204c697374206f662076616c696461746f72206163636f756e747320746f206e6f6d696e617465002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f82a205b604572726f723a3a4e6f744e6f6d696e61746f72605d202d2043616c6c6572206c61636b73206e6f6d696e61746f72207065726d697373696f6e73001823204e6f7465001d01466f727761726473206e6f6d696e6174696f6e2063616c6c20746f207374616b696e672070616c6c6574207573696e6720706f6f6c277320626f6e646564206163636f756e742e247365745f737461746508011c706f6f6c5f6964100118506f6f6c4964000114737461746541020124506f6f6c537461746500095c59015570646174657320746865207374617465206f66206120706f6f6c2e204f6e6365206120706f6f6c20697320696e206044657374726f79696e67602073746174652c206974732073746174652063616e6e6f74206265986368616e67656420616761696e20756e64657220616e792063697263756d7374616e6365732e003423205065726d697373696f6e7300b42a20506f6f6c20626f756e636572206f7220726f6f7420726f6c652063616e2073657420616e7920737461746551012a20416e79206163636f756e742063616e2073657420737461746520746f206044657374726f79696e676020696620706f6f6c206661696c7320606f6b5f746f5f62655f6f70656e6020636f6e646974696f6e73002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572702a2060737461746560202d204e657720737461746520746f20736574002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737461012a205b604572726f723a3a43616e4e6f744368616e67655374617465605d202d20506f6f6c20697320696e2064657374726f79696e67207374617465206f722063616c6c6572206c61636b73207065726d697373696f6e73001823204e6f74650055015374617465206368616e676573206172652076616c696461746564207468726f75676820606f6b5f746f5f62655f6f70656e6020776869636820636865636b7320706f6f6c2070726f70657274696573206c696b658c636f6d6d697373696f6e2c206d656d62657220636f756e7420616e6420726f6c65732e307365745f6d6574616461746108011c706f6f6c5f6964100118506f6f6c49640001206d6574616461746138011c5665633c75383e000a44985570646174657320746865206d6574616461746120666f72206120676976656e20706f6f6c2e003423205065726d697373696f6e7300c42a204d7573742062652063616c6c65642062792074686520706f6f6c20626f756e636572206f7220726f6f7420726f6c65002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572882a20606d6574616461746160202d204e6577206d6574616461746120746f20736574002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737431012a205b604572726f723a3a4d65746164617461457863656564734d61784c656e605d202d204d65746164617461206c656e6774682065786365656473206d6178696d756d20616c6c6f77656419012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b73207265717569726564207065726d697373696f6e732c7365745f636f6e666967731001346d696e5f6a6f696e5f626f6e640d070158436f6e6669674f703c42616c616e63654f663c543e3e00013c6d696e5f6372656174655f626f6e640d070158436f6e6669674f703c42616c616e63654f663c543e3e0001246d61785f706f6f6c7311070134436f6e6669674f703c7533323e000154676c6f62616c5f6d61785f636f6d6d697373696f6e15070144436f6e6669674f703c50657262696c6c3e000b440501557064617465732074686520676c6f62616c20636f6e66696775726174696f6e20706172616d657465727320666f72206e6f6d696e6174696f6e20706f6f6c732e003423205065726d697373696f6e7300602a204d7573742062652063616c6c656420627920526f6f74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c11012a20606d696e5f6a6f696e5f626f6e6460202d20436f6e666967206f7065726174696f6e20666f72206d696e696d756d20626f6e6420746f206a6f696e206120706f6f6c29012a20606d696e5f6372656174655f626f6e6460202d20436f6e666967206f7065726174696f6e20666f72206d696e696d756d20626f6e6420746f20637265617465206120706f6f6c2020f02a20606d61785f706f6f6c7360202d20436f6e666967206f7065726174696f6e20666f72206d6178696d756d206e756d626572206f6620706f6f6c7329012a2060676c6f62616c5f6d61785f636f6d6d697373696f6e60202d20436f6e666967206f7065726174696f6e20666f72206d6178696d756d20676c6f62616c20636f6d6d697373696f6e002023204572726f727300cc2a205b6044697370617463684572726f723a3a4261644f726967696e605d202d2043616c6c6572206973206e6f7420526f6f74307570646174655f726f6c657310011c706f6f6c5f6964100118506f6f6c49640001206e65775f726f6f7419070158436f6e6669674f703c543a3a4163636f756e7449643e0001346e65775f6e6f6d696e61746f7219070158436f6e6669674f703c543a3a4163636f756e7449643e00012c6e65775f626f756e63657219070158436f6e6669674f703c543a3a4163636f756e7449643e000c546c5570646174652074686520726f6c6573206f66206120706f6f6c2e0085015570646174657320726f6f742c206e6f6d696e61746f7220616e6420626f756e63657220726f6c657320666f72206120676976656e20706f6f6c2e20546865206465706f7369746f7220726f6c652063616e6e6f74206265206368616e6765642ec8456d69747320612060526f6c65735570646174656460206576656e74206f6e207375636365737366756c207570646174652e003423205065726d697373696f6e7300882a204f726967696e206d75737420626520526f6f74206f7220706f6f6c20726f6f74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572a82a20606e65775f726f6f7460202d204e657720726f6f7420726f6c6520636f6e66696775726174696f6ed82a20606e65775f6e6f6d696e61746f7260202d204e6577206e6f6d696e61746f7220726f6c6520636f6e66696775726174696f6e2020c02a20606e65775f626f756e63657260202d204e657720626f756e63657220726f6c6520636f6e66696775726174696f6e002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737411012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d204f726967696e20646f6573206e6f742068617665207065726d697373696f6e146368696c6c04011c706f6f6c5f6964100118506f6f6c4964000d3c25014368696c6c206f6e20626568616c66206f662074686520706f6f6c20627920666f7277617264696e67207468652063616c6c20746f20746865207374616b696e672070616c6c65742e003423205065726d697373696f6e7300d82a204f726967696e206d757374206265207369676e656420627920706f6f6c206e6f6d696e61746f72206f7220726f6f7420726f6c65002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f74206578697374f82a205b604572726f723a3a4e6f744e6f6d696e61746f72605d202d204f726967696e206c61636b73206e6f6d696e6174696f6e207065726d697373696f6e40626f6e645f65787472615f6f746865720c01186d656d626572c50201504163636f756e7449644c6f6f6b75704f663c543e00011c706f6f6c5f6964100118506f6f6c49640001146578747261f906015c426f6e6445787472613c42616c616e63654f663c543e3e000e500d01426f6e64206164646974696f6e616c2066756e647320666f72206120706f6f6c206d656d62657220696e746f207468656972207265737065637469766520706f6f6c2e003423205065726d697373696f6e730041012a204f726967696e206d757374206d61746368206d656d626572206163636f756e7420666f7220626f6e64696e672066726f6d20667265652062616c616e63652f70656e64696e6720726577617264733d012a20416e79206f726967696e2063616e20626f6e642066726f6d2070656e64696e672072657761726473206966206d656d6265722068617320605065726d697373696f6e6c657373416c6c60206f72b02020605065726d697373696f6e6c657373436f6d706f756e646020636c61696d207065726d697373696f6e73002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6cb02a20606d656d62657260202d20506f6f6c206d656d626572206163636f756e7420746f20626f6e6420666f72742a2060706f6f6c5f696460202d20506f6f6c206964656e746966696572fc2a2060657874726160202d20416d6f756e7420746f20626f6e642066726f6d20667265652062616c616e6365206f722070656e64696e672072657761726473002023204572726f727300bc2a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d20506f6f6c20646f6573206e6f7420657869737405012a205b604572726f723a3a506f6f6c4d656d6265724e6f74466f756e64605d202d204163636f756e74206973206e6f742061206d656d626572206f6620706f6f6c19012a205b604572726f723a3a4e6f5065726d697373696f6e605d202d204f726967696e206c61636b73207065726d697373696f6e20746f20626f6e6420666f72206d656d626572387365745f636f6d6d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001386e65775f636f6d6d697373696f6e2101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e001140dc536574206f722072656d6f76652074686520636f6d6d697373696f6e207261746520616e6420706179656520666f72206120706f6f6c2e003423205065726d697373696f6e730001012a2043616c6c6572206d757374206861766520636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e20666f722074686520706f6f6c002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c842a2060706f6f6c5f696460202d2054686520706f6f6c206964656e74696669657265012a20606e65775f636f6d6d697373696f6e60202d204f7074696f6e616c20636f6d6d697373696f6e207261746520616e642070617965652e204e6f6e652072656d6f766573206578697374696e6720636f6d6d697373696f6e002023204572726f727300d82a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d2054686520706f6f6c5f696420646f6573206e6f7420657869737449012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b7320636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e487365745f636f6d6d697373696f6e5f6d617808011c706f6f6c5f6964100118506f6f6c49640001386d61785f636f6d6d697373696f6ef4011c50657262696c6c001244690153657420746865206d6178696d756d20636f6d6d697373696f6e207261746520666f72206120706f6f6c2e20496e697469616c206d61782063616e2062652073657420746f20616e792076616c75652c2077697468206f6e6c7955016c6f7765722076616c75657320616c6c6f77656420746865726561667465722e2043757272656e7420636f6d6d697373696f6e2077696c6c20626520726564756365642069662061626f7665206e6577206d61782e003423205065726d697373696f6e730001012a2043616c6c6572206d757374206861766520636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e20666f722074686520706f6f6c002c2320417267756d656e7473008c2a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c842a2060706f6f6c5f696460202d2054686520706f6f6c206964656e746966696572d02a20606d61785f636f6d6d697373696f6e60202d20546865206e6577206d6178696d756d20636f6d6d697373696f6e2072617465002023204572726f727300d82a205b604572726f723a3a506f6f6c4e6f74466f756e64605d202d2054686520706f6f6c5f696420646f6573206e6f7420657869737449012a205b604572726f723a3a446f65734e6f74486176655065726d697373696f6e605d202d2043616c6c6572206c61636b7320636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e687365745f636f6d6d697373696f6e5f6368616e67655f7261746508011c706f6f6c5f6964100118506f6f6c496400012c6368616e67655f726174654502019c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e001328a85365742074686520636f6d6d697373696f6e206368616e6765207261746520666f72206120706f6f6c2e003d01496e697469616c206368616e67652072617465206973206e6f7420626f756e6465642c20776865726561732073756273657175656e7420757064617465732063616e206f6e6c79206265206d6f7265747265737472696374697665207468616e207468652063757272656e742e002c2320417267756d656e747300a1012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e206d616e6167656d656e74207065726d697373696f6e2e2d012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f2073657420636f6d6d697373696f6e206368616e6765207261746520666f722efc2a20606368616e67655f7261746560202d20546865206e657720636f6d6d697373696f6e206368616e6765207261746520636f6e66696775726174696f6e2e40636c61696d5f636f6d6d697373696f6e04011c706f6f6c5f6964100118506f6f6c496400142890436c61696d2070656e64696e6720636f6d6d697373696f6e20666f72206120706f6f6c2e007d01546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e790150656e64696e6720636f6d6d697373696f6e2069732070616964206f757420616e6420616464656420746f20746f74616c20636c61696d656420636f6d6d697373696f6e2e20546f74616c2070656e64696e6720636f6d6d697373696f6e44697320726573657420746f207a65726f2e002c2320417267756d656e7473008d012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e656420627920616e206163636f756e74207769746820636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e09012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f20636c61696d20636f6d6d697373696f6e2066726f6d2e4c61646a7573745f706f6f6c5f6465706f73697404011c706f6f6c5f6964100118506f6f6c4964001530ec546f70207570207468652064656669636974206f7220776974686472617720746865206578636573732045442066726f6d2074686520706f6f6c2e0051015768656e206120706f6f6c20697320637265617465642c2074686520706f6f6c206465706f7369746f72207472616e736665727320454420746f2074686520726577617264206163636f756e74206f66207468655501706f6f6c2e204544206973207375626a65637420746f206368616e676520616e64206f7665722074696d652c20746865206465706f73697420696e2074686520726577617264206163636f756e74206d61792062655101696e73756666696369656e7420746f20636f766572207468652045442064656669636974206f662074686520706f6f6c206f7220766963652d76657273612077686572652074686572652069732065786365737331016465706f73697420746f2074686520706f6f6c2e20546869732063616c6c20616c6c6f777320616e796f6e6520746f2061646a75737420746865204544206465706f736974206f6620746865f4706f6f6c2062792065697468657220746f7070696e67207570207468652064656669636974206f7220636c61696d696e6720746865206578636573732e002c2320417267756d656e747300d02a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642e0d012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f2061646a75737420746865206465706f73697420666f722e7c7365745f636f6d6d697373696f6e5f636c61696d5f7065726d697373696f6e08011c706f6f6c5f6964100118506f6f6c49640001287065726d697373696f6e490201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e001628cc536574206f722072656d6f7665206120706f6f6c277320636f6d6d697373696f6e20636c61696d207065726d697373696f6e2e004d014f6e6c79207468652060526f6f746020726f6c65206f662074686520706f6f6c2069732061626c6520746f20636f6e66696775726520636f6d6d697373696f6e20636c61696d207065726d697373696f6e732e4901546869732064657465726d696e6573207768696368206163636f756e74732061726520616c6c6f77656420746f20636c61696d2074686520706f6f6c27732070656e64696e6720636f6d6d697373696f6e2e002c2320417267756d656e7473003d012a20606f726967696e60202d20546865206f726967696e206f66207468652063616c6c2e204d757374206265207369676e65642062792074686520706f6f6c277320726f6f74206163636f756e742e01012a2060706f6f6c5f696460202d20546865206964656e746966696572206f662074686520706f6f6c20746f20736574207065726d697373696f6e7320666f722eb9012a20607065726d697373696f6e60202d204f7074696f6e616c20636f6d6d697373696f6e20636c61696d207065726d697373696f6e20636f6e66696775726174696f6e2e204966204e6f6e652c2072656d6f76657320616e79206578697374696e67207065726d697373696f6e2e040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732ef9060c4470616c6c65745f74616e676c655f6c737414747970657324426f6e644578747261041c42616c616e6365011801042c4672656542616c616e6365040018011c42616c616e636500000000fd0604184f7074696f6e0404540101070108104e6f6e6500000010536f6d6504000107000001000001070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000050704184f7074696f6e0404540109070108104e6f6e6500000010536f6d6504000907000001000009070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e00000d070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540118010c104e6f6f700000000c5365740400180104540001001852656d6f76650002000011070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540110010c104e6f6f700000000c5365740400100104540001001852656d6f76650002000015070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f7004045401f4010c104e6f6f700000000c5365740400f40104540001001852656d6f76650002000019070c4470616c6c65745f74616e676c655f6c737414747970657320436f6e6669674f700404540100010c104e6f6f700000000c5365740400000104540001001852656d6f7665000200001d070c3870616c6c65745f726577617264731870616c6c65741043616c6c04045400010c34636c61696d5f726577617264730401146173736574f101014441737365743c543a3a417373657449643e000104c8436c61696d207265776172647320666f72206120737065636966696320617373657420616e64207265776172642074797065646d616e6167655f61737365745f7265776172645f7661756c740c01207661756c745f6964100128543a3a5661756c74496400012061737365745f6964f101014441737365743c543a3a417373657449643e000118616374696f6e5902012c4173736574416374696f6e000244844d616e61676520617373657420696420746f207661756c7420726577617264732e003423205065726d697373696f6e7300a42a204d757374206265207369676e656420627920616e20617574686f72697a6564206163636f756e74002c2320417267756d656e7473007c2a20606f726967696e60202d204f726967696e206f66207468652063616c6c782a20607661756c745f696460202d204944206f6620746865207661756c74782a206061737365745f696460202d204944206f6620746865206173736574ac2a2060616374696f6e60202d20416374696f6e20746f20706572666f726d20284164642f52656d6f766529002023204572726f72730001012a205b604572726f723a3a4173736574416c7265616479496e5661756c74605d202d20417373657420616c72656164792065786973747320696e207661756c74f02a205b604572726f723a3a41737365744e6f74496e5661756c74605d202d20417373657420646f6573206e6f7420657869737420696e207661756c74687570646174655f7661756c745f7265776172645f636f6e6669670801207661756c745f6964100128543a3a5661756c7449640001286e65775f636f6e6669672107019c526577617264436f6e666967466f7241737365745661756c743c42616c616e63654f663c543e3e000340d855706461746573207468652072657761726420636f6e66696775726174696f6e20666f722061207370656369666963207661756c742e002c2320417267756d656e7473f82a20606f726967696e60202d204f726967696e206f66207468652063616c6c2c206d75737420706173732060466f7263654f726967696e6020636865636bb02a20607661756c745f696460202d20546865204944206f6620746865207661756c7420746f20757064617465e42a20606e65775f636f6e66696760202d20546865206e65772072657761726420636f6e66696775726174696f6e20636f6e7461696e696e673ac420202a206061707960202d20416e6e75616c2050657263656e74616765205969656c6420666f7220746865207661756c74e020202a20606465706f7369745f63617060202d204d6178696d756d20616d6f756e7420746861742063616e206265206465706f7369746564290120202a2060696e63656e746976655f63617060202d204d6178696d756d20616d6f756e74206f6620696e63656e746976657320746861742063616e206265206469737472696275746564f420202a2060626f6f73745f6d756c7469706c69657260202d204f7074696f6e616c206d756c7469706c69657220746f20626f6f73742072657761726473002023204576656e747329012a20605661756c74526577617264436f6e6669675570646174656460202d20456d6974746564207768656e207661756c742072657761726420636f6e6669672069732075706461746564002023204572726f727305012a20604261644f726967696e60202d2049662063616c6c6572206973206e6f7420617574686f72697a6564207468726f7567682060466f7263654f726967696e60040d01436f6e7461696e7320612076617269616e742070657220646973706174636861626c652065787472696e736963207468617420746869732070616c6c6574206861732e21070c3870616c6c65745f7265776172647314747970657364526577617264436f6e666967466f7241737365745661756c74041c42616c616e636501180010010c6170795502011c50657263656e74000134696e63656e746976655f63617018011c42616c616e636500012c6465706f7369745f63617018011c42616c616e6365000140626f6f73745f6d756c7469706c6965723d03012c4f7074696f6e3c7533323e000025070c2c70616c6c65745f7375646f1870616c6c6574144572726f720404540001042c526571756972655375646f0000048053656e646572206d75737420626520746865205375646f206163636f756e742e04684572726f7220666f7220746865205375646f2070616c6c65742e29070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00002d070c3470616c6c65745f61737365747314747970657330417373657444657461696c730c1c42616c616e63650118244163636f756e7449640100384465706f73697442616c616e63650118003001146f776e65720001244163636f756e7449640001186973737565720001244163636f756e74496400011461646d696e0001244163636f756e74496400011c667265657a65720001244163636f756e744964000118737570706c7918011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500012c6d696e5f62616c616e636518011c42616c616e636500013469735f73756666696369656e74200110626f6f6c0001206163636f756e747310010c75333200012c73756666696369656e747310010c753332000124617070726f76616c7310010c7533320001187374617475733107012c4173736574537461747573000031070c3470616c6c65745f6173736574731474797065732c417373657453746174757300010c104c6976650000001846726f7a656e0001002844657374726f79696e670002000035070000040818000039070c3470616c6c65745f6173736574731474797065733041737365744163636f756e74101c42616c616e63650118384465706f73697442616c616e636501181445787472610184244163636f756e74496401000010011c62616c616e636518011c42616c616e63650001187374617475733d0701344163636f756e74537461747573000118726561736f6e410701a84578697374656e6365526561736f6e3c4465706f73697442616c616e63652c204163636f756e7449643e0001146578747261840114457874726100003d070c3470616c6c65745f617373657473147479706573344163636f756e7453746174757300010c184c69717569640000001846726f7a656e0001001c426c6f636b65640002000041070c3470616c6c65745f6173736574731474797065733c4578697374656e6365526561736f6e081c42616c616e63650118244163636f756e7449640100011420436f6e73756d65720000002853756666696369656e740001002c4465706f73697448656c64040018011c42616c616e63650002003c4465706f736974526566756e6465640003002c4465706f73697446726f6d08000001244163636f756e744964000018011c42616c616e63650004000045070000040c1800000049070c3470616c6c65745f61737365747314747970657320417070726f76616c081c42616c616e63650118384465706f73697442616c616e6365011800080118616d6f756e7418011c42616c616e636500011c6465706f7369741801384465706f73697442616c616e636500004d070c3470616c6c65745f6173736574731474797065733441737365744d6574616461746108384465706f73697442616c616e6365011834426f756e646564537472696e670151070014011c6465706f7369741801384465706f73697442616c616e63650001106e616d6551070134426f756e646564537472696e6700011873796d626f6c51070134426f756e646564537472696e67000120646563696d616c73080108753800012469735f66726f7a656e200110626f6f6c000051070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000055070c3470616c6c65745f6173736574731870616c6c6574144572726f720804540004490001542842616c616e63654c6f7700000415014163636f756e742062616c616e6365206d7573742062652067726561746572207468616e206f7220657175616c20746f20746865207472616e7366657220616d6f756e742e244e6f4163636f756e7400010490546865206163636f756e7420746f20616c74657220646f6573206e6f742065786973742e304e6f5065726d697373696f6e000204e8546865207369676e696e67206163636f756e7420686173206e6f207065726d697373696f6e20746f20646f20746865206f7065726174696f6e2e1c556e6b6e6f776e0003047854686520676976656e20617373657420494420697320756e6b6e6f776e2e1846726f7a656e00040474546865206f726967696e206163636f756e742069732066726f7a656e2e14496e5573650005047854686520617373657420494420697320616c72656164792074616b656e2e284261645769746e6573730006046c496e76616c6964207769746e657373206461746120676976656e2e384d696e42616c616e63655a65726f0007048c4d696e696d756d2062616c616e63652073686f756c64206265206e6f6e2d7a65726f2e4c556e617661696c61626c65436f6e73756d657200080c5901556e61626c6520746f20696e6372656d656e742074686520636f6e73756d6572207265666572656e636520636f756e74657273206f6e20746865206163636f756e742e20456974686572206e6f2070726f76696465724d017265666572656e63652065786973747320746f20616c6c6f772061206e6f6e2d7a65726f2062616c616e6365206f662061206e6f6e2d73656c662d73756666696369656e742061737365742c206f72206f6e65f06665776572207468656e20746865206d6178696d756d206e756d626572206f6620636f6e73756d65727320686173206265656e20726561636865642e2c4261644d657461646174610009045c496e76616c6964206d6574616461746120676976656e2e28556e617070726f766564000a04c44e6f20617070726f76616c20657869737473207468617420776f756c6420616c6c6f7720746865207472616e736665722e20576f756c64446965000b04350154686520736f75726365206163636f756e7420776f756c64206e6f74207375727669766520746865207472616e7366657220616e64206974206e6565647320746f207374617920616c6976652e34416c7265616479457869737473000c04845468652061737365742d6163636f756e7420616c7265616479206578697374732e244e6f4465706f736974000d04d45468652061737365742d6163636f756e7420646f65736e2774206861766520616e206173736f636961746564206465706f7369742e24576f756c644275726e000e04c4546865206f7065726174696f6e20776f756c6420726573756c7420696e2066756e6473206265696e67206275726e65642e244c6976654173736574000f0859015468652061737365742069732061206c69766520617373657420616e64206973206163746976656c79206265696e6720757365642e20557375616c6c7920656d697420666f72206f7065726174696f6e7320737563681d016173206073746172745f64657374726f796020776869636820726571756972652074686520617373657420746f20626520696e20612064657374726f79696e672073746174652e3041737365744e6f744c697665001004c8546865206173736574206973206e6f74206c6976652c20616e64206c696b656c79206265696e672064657374726f7965642e3c496e636f7272656374537461747573001104b054686520617373657420737461747573206973206e6f7420746865206578706563746564207374617475732e244e6f7446726f7a656e001204d85468652061737365742073686f756c642062652066726f7a656e206265666f72652074686520676976656e206f7065726174696f6e2e3843616c6c6261636b4661696c65640013048443616c6c6261636b20616374696f6e20726573756c74656420696e206572726f722842616441737365744964001404c8546865206173736574204944206d75737420626520657175616c20746f20746865205b604e65787441737365744964605d2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e59070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454015d07045300000400650701185665633c543e00005d070c3c70616c6c65745f62616c616e6365731474797065732c42616c616e63654c6f636b041c42616c616e63650118000c01086964ad0201384c6f636b4964656e746966696572000118616d6f756e7418011c42616c616e636500011c726561736f6e736107011c526561736f6e73000061070c3c70616c6c65745f62616c616e6365731474797065731c526561736f6e7300010c0c466565000000104d6973630001000c416c6c0002000065070000025d070069070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454016d07045300000400710701185665633c543e00006d070c3c70616c6c65745f62616c616e6365731474797065732c52657365727665446174610844526573657276654964656e74696669657201ad021c42616c616e63650118000801086964ad020144526573657276654964656e746966696572000118616d6f756e7418011c42616c616e6365000071070000026d070075070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454017907045300000400850701185665633c543e0000790714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e7408084964017d071c42616c616e636501180008010869647d0701084964000118616d6f756e7418011c42616c616e636500007d07085874616e676c655f746573746e65745f72756e74696d654452756e74696d65486f6c64526561736f6e00010420507265696d61676504008107016c70616c6c65745f707265696d6167653a3a486f6c64526561736f6e001a000081070c3c70616c6c65745f707265696d6167651870616c6c657428486f6c64526561736f6e00010420507265696d61676500000000850700000279070089070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454018d070453000004009d0701185665633c543e00008d0714346672616d655f737570706f72741874726169747318746f6b656e73106d697363204964416d6f756e74080849640191071c42616c616e63650118000801086964910701084964000118616d6f756e7418011c42616c616e636500009107085874616e676c655f746573746e65745f72756e74696d654c52756e74696d65467265657a65526561736f6e0001083c4e6f6d696e6174696f6e506f6f6c7304009507019470616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733a3a467265657a65526561736f6e0018000c4c737404009907017c70616c6c65745f74616e676c655f6c73743a3a467265657a65526561736f6e0034000095070c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e63650000000099070c4470616c6c65745f74616e676c655f6c73741870616c6c657430467265657a65526561736f6e00010438506f6f6c4d696e42616c616e6365000000009d070000028d0700a1070c3c70616c6c65745f62616c616e6365731870616c6c6574144572726f720804540004490001303856657374696e6742616c616e63650000049c56657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c75652e544c69717569646974795265737472696374696f6e73000104c84163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2e4c496e73756666696369656e7442616c616e63650002047842616c616e636520746f6f206c6f7720746f2073656e642076616c75652e484578697374656e7469616c4465706f736974000304ec56616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742e34457870656e646162696c697479000404905472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742e5c4578697374696e6756657374696e675363686564756c65000504cc412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e742e2c446561644163636f756e740006048c42656e6566696369617279206163636f756e74206d757374207072652d65786973742e3c546f6f4d616e795265736572766573000704b84e756d626572206f66206e616d65642072657365727665732065786365656420604d61785265736572766573602e30546f6f4d616e79486f6c6473000804f84e756d626572206f6620686f6c647320657863656564206056617269616e74436f756e744f663c543a3a52756e74696d65486f6c64526561736f6e3e602e38546f6f4d616e79467265657a6573000904984e756d626572206f6620667265657a65732065786365656420604d6178467265657a6573602e4c49737375616e63654465616374697661746564000a0401015468652069737375616e63652063616e6e6f74206265206d6f6469666965642073696e636520697420697320616c72656164792064656163746976617465642e2444656c74615a65726f000b04645468652064656c74612063616e6e6f74206265207a65726f2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ea5070c3473705f61726974686d657469632c66697865645f706f696e742446697865645531323800000400180110753132380000a907086870616c6c65745f7472616e73616374696f6e5f7061796d656e742052656c6561736573000108245631416e6369656e7400000008563200010000ad070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401b107045300000400b50701185665633c543e0000b10700000408dd023000b507000002b10700b9070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540104045300000400bd0701185665633c543e0000bd070000020400c10704184f7074696f6e04045401c5070108104e6f6e6500000010536f6d650400c5070000010000c5070c4473705f636f6e73656e7375735f626162651c646967657374732450726544696765737400010c1c5072696d6172790400c90701405072696d617279507265446967657374000100385365636f6e64617279506c61696e0400d107015c5365636f6e64617279506c61696e507265446967657374000200305365636f6e646172795652460400d50701545365636f6e6461727956524650726544696765737400030000c9070c4473705f636f6e73656e7375735f626162651c64696765737473405072696d61727950726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74e1020110536c6f740001347672665f7369676e6174757265cd0701305672665369676e61747572650000cd07101c73705f636f72651c737232353531390c767266305672665369676e617475726500000801287072655f6f75747075740401305672665072654f757470757400011470726f6f660d03012056726650726f6f660000d1070c4473705f636f6e73656e7375735f626162651c646967657374735c5365636f6e64617279506c61696e507265446967657374000008013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74e1020110536c6f740000d5070c4473705f636f6e73656e7375735f626162651c64696765737473545365636f6e6461727956524650726544696765737400000c013c617574686f726974795f696e64657810015473757065723a3a417574686f72697479496e646578000110736c6f74e1020110536c6f740001347672665f7369676e6174757265cd0701305672665369676e61747572650000d907084473705f636f6e73656e7375735f62616265584261626545706f6368436f6e66696775726174696f6e000008010463ed020128287536342c2075363429000134616c6c6f7765645f736c6f7473f1020130416c6c6f776564536c6f74730000dd070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013901045300000400610201185665633c543e0000e1070c2c70616c6c65745f626162651870616c6c6574144572726f7204045400011060496e76616c696445717569766f636174696f6e50726f6f660000043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c69644b65794f776e65727368697050726f6f66000104310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400020415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e50496e76616c6964436f6e66696775726174696f6e0003048c5375626d697474656420636f6e66696775726174696f6e20697320696e76616c69642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee507083870616c6c65745f6772616e6470612c53746f726564537461746504044e01300110104c6976650000003050656e64696e6750617573650801307363686564756c65645f61743001044e00011464656c61793001044e000100185061757365640002003450656e64696e67526573756d650801307363686564756c65645f61743001044e00011464656c61793001044e00030000e907083870616c6c65745f6772616e6470614c53746f72656450656e64696e674368616e676508044e0130144c696d697400001001307363686564756c65645f61743001044e00011464656c61793001044e0001406e6578745f617574686f726974696573ed07016c426f756e646564417574686f726974794c6973743c4c696d69743e000118666f72636564810401244f7074696f6e3c4e3e0000ed070c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e64656456656308045401a4045300000400a001185665633c543e0000f1070c3870616c6c65745f6772616e6470611870616c6c6574144572726f7204045400011c2c50617573654661696c65640000080501417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665a42865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e30526573756d654661696c65640001081101417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e277420706175736564a028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e344368616e676550656e64696e67000204e8417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e1c546f6f536f6f6e000304bc43616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e60496e76616c69644b65794f776e65727368697050726f6f66000404310141206b6579206f776e6572736869702070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e60496e76616c696445717569766f636174696f6e50726f6f660005043101416e2065717569766f636174696f6e2070726f6f662070726f76696465642061732070617274206f6620616e2065717569766f636174696f6e207265706f727420697320696e76616c69642e584475706c69636174654f6666656e63655265706f727400060415014120676976656e2065717569766f636174696f6e207265706f72742069732076616c69642062757420616c72656164792070726576696f75736c79207265706f727465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ef5070000040c00182000f9070c3870616c6c65745f696e64696365731870616c6c6574144572726f720404540001142c4e6f7441737369676e65640000048c54686520696e64657820776173206e6f7420616c72656164792061737369676e65642e204e6f744f776e6572000104a454686520696e6465782069732061737369676e656420746f20616e6f74686572206163636f756e742e14496e5573650002047054686520696e64657820776173206e6f7420617661696c61626c652e2c4e6f745472616e73666572000304c854686520736f7572636520616e642064657374696e6174696f6e206163636f756e747320617265206964656e746963616c2e245065726d616e656e74000404d054686520696e646578206973207065726d616e656e7420616e64206d6179206e6f742062652066726565642f6368616e6765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742efd070c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010108045300000400050801185665633c543e000001080000040c102d03000005080000020108000908000004085d0418000d080c4070616c6c65745f64656d6f6372616379147479706573385265666572656e64756d496e666f0c2c426c6f636b4e756d62657201302050726f706f73616c012d031c42616c616e6365011801081c4f6e676f696e670400110801c05265666572656e64756d5374617475733c426c6f636b4e756d6265722c2050726f706f73616c2c2042616c616e63653e0000002046696e6973686564080120617070726f766564200110626f6f6c00010c656e6430012c426c6f636b4e756d6265720001000011080c4070616c6c65745f64656d6f6372616379147479706573405265666572656e64756d5374617475730c2c426c6f636b4e756d62657201302050726f706f73616c012d031c42616c616e636501180014010c656e6430012c426c6f636b4e756d62657200012070726f706f73616c2d03012050726f706f73616c0001247468726573686f6c64b40134566f74655468726573686f6c6400011464656c617930012c426c6f636b4e756d62657200011474616c6c791508013854616c6c793c42616c616e63653e000015080c4070616c6c65745f64656d6f63726163791474797065731454616c6c79041c42616c616e63650118000c01106179657318011c42616c616e63650001106e61797318011c42616c616e636500011c7475726e6f757418011c42616c616e6365000019080c4070616c6c65745f64656d6f637261637910766f746518566f74696e67101c42616c616e63650118244163636f756e74496401002c426c6f636b4e756d6265720130204d6178566f746573000108184469726563740c0114766f7465731d0801f4426f756e6465645665633c285265666572656e64756d496e6465782c204163636f756e74566f74653c42616c616e63653e292c204d6178566f7465733e00012c64656c65676174696f6e732908015044656c65676174696f6e733c42616c616e63653e0001147072696f722d08017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e0000002844656c65676174696e6714011c62616c616e636518011c42616c616e63650001187461726765740001244163636f756e744964000128636f6e76696374696f6e39030128436f6e76696374696f6e00012c64656c65676174696f6e732908015044656c65676174696f6e733c42616c616e63653e0001147072696f722d08017c5072696f724c6f636b3c426c6f636b4e756d6265722c2042616c616e63653e000100001d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454012108045300000400250801185665633c543e000021080000040810b800250800000221080029080c4070616c6c65745f64656d6f63726163791474797065732c44656c65676174696f6e73041c42616c616e6365011800080114766f74657318011c42616c616e636500011c6361706974616c18011c42616c616e636500002d080c4070616c6c65745f64656d6f637261637910766f7465245072696f724c6f636b082c426c6f636b4e756d62657201301c42616c616e6365011800080030012c426c6f636b4e756d626572000018011c42616c616e636500003108000004082d03b400350800000408305d040039080c4070616c6c65745f64656d6f63726163791870616c6c6574144572726f720404540001602056616c75654c6f770000043456616c756520746f6f206c6f773c50726f706f73616c4d697373696e670001045c50726f706f73616c20646f6573206e6f742065786973743c416c726561647943616e63656c65640002049443616e6e6f742063616e63656c207468652073616d652070726f706f73616c207477696365444475706c696361746550726f706f73616c0003045450726f706f73616c20616c7265616479206d6164654c50726f706f73616c426c61636b6c69737465640004046850726f706f73616c207374696c6c20626c61636b6c6973746564444e6f7453696d706c654d616a6f72697479000504a84e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792c496e76616c69644861736800060430496e76616c69642068617368284e6f50726f706f73616c000704504e6f2065787465726e616c2070726f706f73616c34416c72656164795665746f6564000804984964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365445265666572656e64756d496e76616c696400090484566f746520676976656e20666f7220696e76616c6964207265666572656e64756d2c4e6f6e6557616974696e67000a04504e6f2070726f706f73616c732077616974696e67204e6f74566f746572000b04c454686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e304e6f5065726d697373696f6e000c04c8546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e44416c726561647944656c65676174696e67000d0488546865206163636f756e7420697320616c72656164792064656c65676174696e672e44496e73756666696369656e7446756e6473000e04fc546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e344e6f7444656c65676174696e67000f04a0546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e28566f74657345786973740010085501546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696ce87468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e44496e7374616e744e6f74416c6c6f776564001104d854686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e204e6f6e73656e73650012049444656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e3c57726f6e675570706572426f756e6400130450496e76616c696420757070657220626f756e642e3c4d6178566f74657352656163686564001404804d6178696d756d206e756d626572206f6620766f74657320726561636865642e1c546f6f4d616e79001504804d6178696d756d206e756d626572206f66206974656d7320726561636865642e3c566f74696e67506572696f644c6f7700160454566f74696e6720706572696f6420746f6f206c6f7740507265696d6167654e6f7445786973740017047054686520707265696d61676520646f6573206e6f742065786973742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e3d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540134045300000400c10101185665633c543e00004108084470616c6c65745f636f6c6c65637469766514566f74657308244163636f756e74496401002c426c6f636b4e756d626572013000140114696e64657810013450726f706f73616c496e6465780001247468726573686f6c6410012c4d656d626572436f756e7400011061796573350201385665633c4163636f756e7449643e0001106e617973350201385665633c4163636f756e7449643e00010c656e6430012c426c6f636b4e756d626572000045080c4470616c6c65745f636f6c6c6563746976651870616c6c6574144572726f7208045400044900012c244e6f744d656d6265720000045c4163636f756e74206973206e6f742061206d656d626572444475706c696361746550726f706f73616c0001047c4475706c69636174652070726f706f73616c73206e6f7420616c6c6f7765643c50726f706f73616c4d697373696e670002044c50726f706f73616c206d7573742065786973742857726f6e67496e646578000304404d69736d61746368656420696e646578344475706c6963617465566f7465000404584475706c696361746520766f74652069676e6f72656448416c7265616479496e697469616c697a6564000504804d656d626572732061726520616c726561647920696e697469616c697a65642120546f6f4561726c79000604010154686520636c6f73652063616c6c20776173206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e40546f6f4d616e7950726f706f73616c73000704fc54686572652063616e206f6e6c792062652061206d6178696d756d206f6620604d617850726f706f73616c7360206163746976652070726f706f73616c732e4c57726f6e6750726f706f73616c576569676874000804d054686520676976656e2077656967687420626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e4c57726f6e6750726f706f73616c4c656e677468000904d054686520676976656e206c656e67746820626f756e6420666f72207468652070726f706f73616c2077617320746f6f206c6f772e545072696d654163636f756e744e6f744d656d626572000a04745072696d65206163636f756e74206973206e6f742061206d656d626572048054686520604572726f726020656e756d206f6620746869732070616c6c65742e49080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454014d030453000004004d0801185665633c543e00004d080000024d03005108083870616c6c65745f76657374696e672052656c65617365730001080856300000000856310001000055080c3870616c6c65745f76657374696e671870616c6c6574144572726f72040454000114284e6f7456657374696e6700000484546865206163636f756e7420676976656e206973206e6f742076657374696e672e5441744d617856657374696e675363686564756c65730001082501546865206163636f756e7420616c72656164792068617320604d617856657374696e675363686564756c65736020636f756e74206f66207363686564756c657320616e642074687573510163616e6e6f742061646420616e6f74686572206f6e652e20436f6e7369646572206d657267696e67206578697374696e67207363686564756c657320696e206f7264657220746f2061646420616e6f746865722e24416d6f756e744c6f770002040501416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e605363686564756c65496e6465784f75744f66426f756e6473000304d0416e20696e64657820776173206f7574206f6620626f756e6473206f66207468652076657374696e67207363686564756c65732e54496e76616c69645363686564756c65506172616d730004040d014661696c656420746f206372656174652061206e6577207363686564756c65206265636175736520736f6d6520706172616d657465722077617320696e76616c69642e04744572726f7220666f72207468652076657374696e672070616c6c65742e59080000025d08005d08086470616c6c65745f656c656374696f6e735f70687261676d656e2853656174486f6c64657208244163636f756e74496401001c42616c616e63650118000c010c77686f0001244163636f756e7449640001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e636500006108086470616c6c65745f656c656374696f6e735f70687261676d656e14566f74657208244163636f756e74496401001c42616c616e63650118000c0114766f746573350201385665633c4163636f756e7449643e0001147374616b6518011c42616c616e636500011c6465706f73697418011c42616c616e6365000065080c6470616c6c65745f656c656374696f6e735f70687261676d656e1870616c6c6574144572726f7204045400014430556e61626c65546f566f7465000004c043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e1c4e6f566f746573000104944d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e30546f6f4d616e79566f7465730002048443616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e504d6178696d756d566f74657345786365656465640003049843616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e284c6f7742616c616e6365000404c443616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e3c556e61626c65546f506179426f6e6400050478566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2c4d7573744265566f746572000604404d757374206265206120766f7465722e4c4475706c69636174656443616e646964617465000704804475706c6963617465642063616e646964617465207375626d697373696f6e2e44546f6f4d616e7943616e6469646174657300080498546f6f206d616e792063616e646964617465732068617665206265656e20637265617465642e304d656d6265725375626d6974000904884d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e3852756e6e657255705375626d6974000a048852756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e68496e73756666696369656e7443616e64696461746546756e6473000b049443616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e244e6f744d656d626572000c04344e6f742061206d656d6265722e48496e76616c69645769746e65737344617461000d04e05468652070726f766964656420636f756e74206f66206e756d626572206f662063616e6469646174657320697320696e636f72726563742e40496e76616c6964566f7465436f756e74000e04cc5468652070726f766964656420636f756e74206f66206e756d626572206f6620766f74657320697320696e636f72726563742e44496e76616c696452656e6f756e63696e67000f04fc5468652072656e6f756e63696e67206f726967696e2070726573656e74656420612077726f6e67206052656e6f756e63696e676020706172616d657465722e48496e76616c69645265706c6163656d656e74001004fc50726564696374696f6e20726567617264696e67207265706c6163656d656e74206166746572206d656d6265722072656d6f76616c2069732077726f6e672e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e6908089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365345265616479536f6c7574696f6e08244163636f756e74496400284d617857696e6e65727300000c0120737570706f7274736d080198426f756e646564537570706f7274733c4163636f756e7449642c204d617857696e6e6572733e00011473636f7265e00134456c656374696f6e53636f726500011c636f6d70757465dc013c456c656374696f6e436f6d7075746500006d080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454013904045300000400350401185665633c543e00007108089070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f706861736534526f756e64536e617073686f7408244163636f756e7449640100304461746150726f766964657201750800080118766f746572737d0801445665633c4461746150726f76696465723e00011c74617267657473350201385665633c4163636f756e7449643e000075080000040c003079080079080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400350201185665633c543e00007d0800000275080081080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454018508045300000400890801185665633c543e000085080000040ce030100089080000028508008d080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f7068617365187369676e6564405369676e65645375626d697373696f6e0c244163636f756e74496401001c42616c616e6365011820536f6c7574696f6e0161030010010c77686f0001244163636f756e74496400011c6465706f73697418011c42616c616e63650001307261775f736f6c7574696f6e5d030154526177536f6c7574696f6e3c536f6c7574696f6e3e00012063616c6c5f66656518011c42616c616e6365000091080c9070616c6c65745f656c656374696f6e5f70726f76696465725f6d756c74695f70686173651870616c6c6574144572726f7204045400013c6850726544697370617463684561726c795375626d697373696f6e000004645375626d697373696f6e2077617320746f6f206561726c792e6c507265446973706174636857726f6e6757696e6e6572436f756e740001048857726f6e67206e756d626572206f662077696e6e6572732070726573656e7465642e6450726544697370617463685765616b5375626d697373696f6e000204905375626d697373696f6e2077617320746f6f207765616b2c2073636f72652d776973652e3c5369676e6564517565756546756c6c0003044901546865207175657565207761732066756c6c2c20616e642074686520736f6c7574696f6e20776173206e6f7420626574746572207468616e20616e79206f6620746865206578697374696e67206f6e65732e585369676e656443616e6e6f745061794465706f73697400040494546865206f726967696e206661696c656420746f2070617920746865206465706f7369742e505369676e6564496e76616c69645769746e657373000504a05769746e657373206461746120746f20646973706174636861626c6520697320696e76616c69642e4c5369676e6564546f6f4d756368576569676874000604b8546865207369676e6564207375626d697373696f6e20636f6e73756d657320746f6f206d756368207765696768743c4f637743616c6c57726f6e67457261000704984f4357207375626d697474656420736f6c7574696f6e20666f722077726f6e6720726f756e645c4d697373696e67536e617073686f744d65746164617461000804a8536e617073686f74206d657461646174612073686f756c6420657869737420627574206469646e27742e58496e76616c69645375626d697373696f6e496e646578000904d06053656c663a3a696e736572745f7375626d697373696f6e602072657475726e656420616e20696e76616c696420696e6465782e3843616c6c4e6f74416c6c6f776564000a04985468652063616c6c206973206e6f7420616c6c6f776564206174207468697320706f696e742e3846616c6c6261636b4661696c6564000b044c5468652066616c6c6261636b206661696c65642c426f756e644e6f744d6574000c0448536f6d6520626f756e64206e6f74206d657438546f6f4d616e7957696e6e657273000d049c5375626d697474656420736f6c7574696f6e2068617320746f6f206d616e792077696e6e657273645072654469737061746368446966666572656e74526f756e64000e04b85375626d697373696f6e2077617320707265706172656420666f72206120646966666572656e7420726f756e642e040d014572726f72206f66207468652070616c6c657420746861742063616e2062652072657475726e656420696e20726573706f6e736520746f20646973706174636865732e9508083870616c6c65745f7374616b696e67345374616b696e674c656467657204045400001401147374617368000130543a3a4163636f756e744964000114746f74616c6d01013042616c616e63654f663c543e0001186163746976656d01013042616c616e63654f663c543e000124756e6c6f636b696e67690401f0426f756e6465645665633c556e6c6f636b4368756e6b3c42616c616e63654f663c543e3e2c20543a3a4d6178556e6c6f636b696e674368756e6b733e0001586c65676163795f636c61696d65645f7265776172647399080194426f756e6465645665633c457261496e6465782c20543a3a486973746f727944657074683e000099080c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400490401185665633c543e00009d08083870616c6c65745f7374616b696e672c4e6f6d696e6174696f6e7304045400000c011c74617267657473790801b4426f756e6465645665633c543a3a4163636f756e7449642c204d61784e6f6d696e6174696f6e734f663c543e3e0001307375626d69747465645f696e100120457261496e64657800012873757070726573736564200110626f6f6c0000a108083870616c6c65745f7374616b696e6734416374697665457261496e666f0000080114696e646578100120457261496e64657800011473746172748104012c4f7074696f6e3c7536343e0000a50800000408100000a908082873705f7374616b696e675450616765644578706f737572654d65746164617461041c42616c616e6365011800100114746f74616c6d01011c42616c616e636500010c6f776e6d01011c42616c616e636500013c6e6f6d696e61746f725f636f756e7410010c753332000128706167655f636f756e74100110506167650000ad080000040c10001000b108082873705f7374616b696e67304578706f737572655061676508244163636f756e74496401001c42616c616e6365011800080128706167655f746f74616c6d01011c42616c616e63650001186f7468657273710101ac5665633c496e646976696475616c4578706f737572653c4163636f756e7449642c2042616c616e63653e3e0000b508083870616c6c65745f7374616b696e673c457261526577617264506f696e747304244163636f756e744964010000080114746f74616c10012c526577617264506f696e74000128696e646976696475616cb908018042547265654d61703c4163636f756e7449642c20526577617264506f696e743e0000b908042042547265654d617008044b010004560110000400bd08000000bd08000002c10800c10800000408001000c508000002c90800c908083870616c6c65745f7374616b696e6738556e6170706c696564536c61736808244163636f756e74496401001c42616c616e636501180014012476616c696461746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f7274657273350201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000cd08000002d10800d10800000408101000d50800000408f41800d9080c3870616c6c65745f7374616b696e6720736c617368696e6734536c617368696e675370616e7300001001287370616e5f696e6465781001245370616e496e6465780001286c6173745f7374617274100120457261496e6465780001486c6173745f6e6f6e7a65726f5f736c617368100120457261496e6465780001147072696f72490401345665633c457261496e6465783e0000dd080c3870616c6c65745f7374616b696e6720736c617368696e67285370616e5265636f7264041c42616c616e636501180008011c736c617368656418011c42616c616e6365000120706169645f6f757418011c42616c616e63650000e108103870616c6c65745f7374616b696e671870616c6c65741870616c6c6574144572726f7204045400017c344e6f74436f6e74726f6c6c6572000004644e6f74206120636f6e74726f6c6c6572206163636f756e742e204e6f745374617368000104504e6f742061207374617368206163636f756e742e34416c7265616479426f6e64656400020460537461736820697320616c726561647920626f6e6465642e34416c726561647950616972656400030474436f6e74726f6c6c657220697320616c7265616479207061697265642e30456d7074795461726765747300040460546172676574732063616e6e6f7420626520656d7074792e384475706c6963617465496e646578000504404475706c696361746520696e6465782e44496e76616c6964536c617368496e64657800060484536c617368207265636f726420696e646578206f7574206f6620626f756e64732e40496e73756666696369656e74426f6e6400070c590143616e6e6f74206861766520612076616c696461746f72206f72206e6f6d696e61746f7220726f6c652c20776974682076616c7565206c657373207468616e20746865206d696e696d756d20646566696e65642062793d01676f7665726e616e6365202873656520604d696e56616c696461746f72426f6e646020616e6420604d696e4e6f6d696e61746f72426f6e6460292e20496620756e626f6e64696e67206973207468651501696e74656e74696f6e2c20606368696c6c6020666972737420746f2072656d6f7665206f6e65277320726f6c652061732076616c696461746f722f6e6f6d696e61746f722e304e6f4d6f72654368756e6b730008049043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e344e6f556e6c6f636b4368756e6b000904a043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e3046756e646564546172676574000a04c8417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e48496e76616c6964457261546f526577617264000b0458496e76616c69642065726120746f207265776172642e68496e76616c69644e756d6265724f664e6f6d696e6174696f6e73000c0478496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e484e6f74536f72746564416e64556e69717565000d04804974656d7320617265206e6f7420736f7274656420616e6420756e697175652e38416c7265616479436c61696d6564000e0409015265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e2c496e76616c696450616765000f04844e6f206e6f6d696e61746f7273206578697374206f6e207468697320706167652e54496e636f7272656374486973746f72794465707468001004c0496e636f72726563742070726576696f757320686973746f727920646570746820696e7075742070726f76696465642e58496e636f7272656374536c617368696e675370616e73001104b0496e636f7272656374206e756d626572206f6620736c617368696e67207370616e732070726f76696465642e2042616453746174650012043901496e7465726e616c20737461746520686173206265636f6d6520736f6d65686f7720636f7272757074656420616e6420746865206f7065726174696f6e2063616e6e6f7420636f6e74696e75652e38546f6f4d616e795461726765747300130494546f6f206d616e79206e6f6d696e6174696f6e207461726765747320737570706c6965642e244261645461726765740014043d0141206e6f6d696e6174696f6e207461726765742077617320737570706c69656420746861742077617320626c6f636b6564206f72206f7468657277697365206e6f7420612076616c696461746f722e4043616e6e6f744368696c6c4f74686572001504550154686520757365722068617320656e6f75676820626f6e6420616e6420746875732063616e6e6f74206265206368696c6c656420666f72636566756c6c7920627920616e2065787465726e616c20706572736f6e2e44546f6f4d616e794e6f6d696e61746f72730016084d0154686572652061726520746f6f206d616e79206e6f6d696e61746f727320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865207374616b696e67b473657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e44546f6f4d616e7956616c696461746f7273001708550154686572652061726520746f6f206d616e792076616c696461746f722063616e6469646174657320696e207468652073797374656d2e20476f7665726e616e6365206e6565647320746f2061646a75737420746865d47374616b696e672073657474696e677320746f206b656570207468696e6773207361666520666f72207468652072756e74696d652e40436f6d6d697373696f6e546f6f4c6f77001804e0436f6d6d697373696f6e20697320746f6f206c6f772e204d757374206265206174206c6561737420604d696e436f6d6d697373696f6e602e2c426f756e644e6f744d657400190458536f6d6520626f756e64206973206e6f74206d65742e50436f6e74726f6c6c657244657072656361746564001a04010155736564207768656e20617474656d7074696e6720746f20757365206465707265636174656420636f6e74726f6c6c6572206163636f756e74206c6f6769632e4c43616e6e6f74526573746f72654c6564676572001b045843616e6e6f742072657365742061206c65646765722e6c52657761726444657374696e6174696f6e52657374726963746564001c04ac50726f7669646564207265776172642064657374696e6174696f6e206973206e6f7420616c6c6f7765642e384e6f74456e6f75676846756e6473001d049c4e6f7420656e6f7567682066756e647320617661696c61626c6520746f2077697468647261772e5c5669727475616c5374616b65724e6f74416c6c6f776564001e04a84f7065726174696f6e206e6f7420616c6c6f77656420666f72207669727475616c207374616b6572732e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee508000002e90800e9080000040800790400ed0800000408f1083800f1080c1c73705f636f72651863727970746f244b65795479706549640000040048011c5b75383b20345d0000f5080c3870616c6c65745f73657373696f6e1870616c6c6574144572726f7204045400011430496e76616c696450726f6f6600000460496e76616c6964206f776e6572736869702070726f6f662e5c4e6f4173736f63696174656456616c696461746f7249640001049c4e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e344475706c6963617465644b65790002046452656769737465726564206475706c6963617465206b65792e184e6f4b657973000304a44e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e244e6f4163636f756e7400040419014b65792073657474696e67206163636f756e74206973206e6f74206c6976652c20736f206974277320696d706f737369626c6520746f206173736f6369617465206b6579732e04744572726f7220666f72207468652073657373696f6e2070616c6c65742ef90800000408341000fd08083c70616c6c65745f74726561737572792050726f706f73616c08244163636f756e74496401001c42616c616e636501180010012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500012c62656e65666963696172790001244163636f756e744964000110626f6e6418011c42616c616e6365000001090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400490401185665633c543e00000509083c70616c6c65745f74726561737572792c5370656e64537461747573142441737365744b696e64018430417373657442616c616e636501182c42656e656669636961727901002c426c6f636b4e756d6265720130245061796d656e74496401840018012861737365745f6b696e6484012441737365744b696e64000118616d6f756e74180130417373657442616c616e636500012c62656e656669636961727900012c42656e656669636961727900012876616c69645f66726f6d30012c426c6f636b4e756d6265720001246578706972655f617430012c426c6f636b4e756d6265720001187374617475730909015c5061796d656e7453746174653c5061796d656e7449643e00000909083c70616c6c65745f7472656173757279305061796d656e745374617465040849640184010c1c50656e64696e6700000024417474656d7074656404010869648401084964000100184661696c6564000200000d0908346672616d655f737570706f72742050616c6c6574496400000400ad02011c5b75383b20385d000011090c3c70616c6c65745f74726561737572791870616c6c6574144572726f7208045400044900012c30496e76616c6964496e646578000004ac4e6f2070726f706f73616c2c20626f756e7479206f72207370656e64206174207468617420696e6465782e40546f6f4d616e79417070726f76616c7300010480546f6f206d616e7920617070726f76616c7320696e207468652071756575652e58496e73756666696369656e745065726d697373696f6e0002084501546865207370656e64206f726967696e2069732076616c6964206275742074686520616d6f756e7420697420697320616c6c6f77656420746f207370656e64206973206c6f776572207468616e207468654c616d6f756e7420746f206265207370656e742e4c50726f706f73616c4e6f74417070726f7665640003047c50726f706f73616c20686173206e6f74206265656e20617070726f7665642e584661696c6564546f436f6e7665727442616c616e636500040451015468652062616c616e6365206f6620746865206173736574206b696e64206973206e6f7420636f6e7665727469626c6520746f207468652062616c616e6365206f6620746865206e61746976652061737365742e305370656e6445787069726564000504b0546865207370656e6420686173206578706972656420616e642063616e6e6f7420626520636c61696d65642e2c4561726c795061796f7574000604a4546865207370656e64206973206e6f742079657420656c696769626c6520666f72207061796f75742e40416c7265616479417474656d707465640007049c546865207061796d656e742068617320616c7265616479206265656e20617474656d707465642e2c5061796f75744572726f72000804cc54686572652077617320736f6d65206973737565207769746820746865206d656368616e69736d206f66207061796d656e742e304e6f74417474656d70746564000904a4546865207061796f757420776173206e6f742079657420617474656d707465642f636c61696d65642e30496e636f6e636c7573697665000a04c4546865207061796d656e7420686173206e656974686572206661696c6564206e6f7220737563636565646564207965742e04784572726f7220666f72207468652074726561737572792070616c6c65742e1509083c70616c6c65745f626f756e7469657318426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d62657201300018012070726f706f7365720001244163636f756e74496400011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000110626f6e6418011c42616c616e636500011873746174757319090190426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00001909083c70616c6c65745f626f756e7469657330426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001182050726f706f73656400000020417070726f7665640001001846756e6465640002003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640003001841637469766508011c63757261746f720001244163636f756e7449640001287570646174655f64756530012c426c6f636b4e756d6265720004003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d626572000500001d090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e000021090c3c70616c6c65745f626f756e746965731870616c6c6574144572726f7208045400044900012c70496e73756666696369656e7450726f706f7365727342616c616e63650000047850726f706f73657227732062616c616e636520697320746f6f206c6f772e30496e76616c6964496e646578000104904e6f2070726f706f73616c206f7220626f756e7479206174207468617420696e6465782e30526561736f6e546f6f4269670002048454686520726561736f6e20676976656e206973206a75737420746f6f206269672e40556e65787065637465645374617475730003048054686520626f756e74792073746174757320697320756e65787065637465642e385265717569726543757261746f720004045c5265717569726520626f756e74792063757261746f722e30496e76616c696456616c756500050454496e76616c696420626f756e74792076616c75652e28496e76616c69644665650006044c496e76616c696420626f756e7479206665652e3450656e64696e675061796f75740007086c4120626f756e7479207061796f75742069732070656e64696e672ef8546f2063616e63656c2074686520626f756e74792c20796f75206d75737420756e61737369676e20616e6420736c617368207468652063757261746f722e245072656d6174757265000804450154686520626f756e746965732063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e504861734163746976654368696c64426f756e7479000904050154686520626f756e74792063616e6e6f7420626520636c6f73656420626563617573652069742068617320616374697665206368696c6420626f756e746965732e34546f6f4d616e79517565756564000a0498546f6f206d616e7920617070726f76616c732061726520616c7265616479207175657565642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e2509085470616c6c65745f6368696c645f626f756e746965732c4368696c64426f756e74790c244163636f756e74496401001c42616c616e636501182c426c6f636b4e756d626572013000140134706172656e745f626f756e747910012c426f756e7479496e64657800011476616c756518011c42616c616e636500010c66656518011c42616c616e636500013c63757261746f725f6465706f73697418011c42616c616e6365000118737461747573290901a44368696c64426f756e74795374617475733c4163636f756e7449642c20426c6f636b4e756d6265723e00002909085470616c6c65745f6368696c645f626f756e74696573444368696c64426f756e747953746174757308244163636f756e74496401002c426c6f636b4e756d626572013001101441646465640000003c43757261746f7250726f706f73656404011c63757261746f720001244163636f756e7449640001001841637469766504011c63757261746f720001244163636f756e7449640002003450656e64696e675061796f75740c011c63757261746f720001244163636f756e74496400012c62656e65666963696172790001244163636f756e744964000124756e6c6f636b5f617430012c426c6f636b4e756d626572000300002d090c5470616c6c65745f6368696c645f626f756e746965731870616c6c6574144572726f7204045400010c54506172656e74426f756e74794e6f74416374697665000004a454686520706172656e7420626f756e7479206973206e6f7420696e206163746976652073746174652e64496e73756666696369656e74426f756e747942616c616e6365000104e454686520626f756e74792062616c616e6365206973206e6f7420656e6f75676820746f20616464206e6577206368696c642d626f756e74792e50546f6f4d616e794368696c64426f756e746965730002040d014e756d626572206f66206368696c6420626f756e746965732065786365656473206c696d697420604d61784163746976654368696c64426f756e7479436f756e74602e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e31090c4070616c6c65745f626167735f6c697374106c697374104e6f646508045400044900001401086964000130543a3a4163636f756e744964000110707265768801504f7074696f6e3c543a3a4163636f756e7449643e0001106e6578748801504f7074696f6e3c543a3a4163636f756e7449643e0001246261675f7570706572300120543a3a53636f726500011473636f7265300120543a3a53636f7265000035090c4070616c6c65745f626167735f6c697374106c6973740c4261670804540004490000080110686561648801504f7074696f6e3c543a3a4163636f756e7449643e0001107461696c8801504f7074696f6e3c543a3a4163636f756e7449643e000039090c4070616c6c65745f626167735f6c6973741870616c6c6574144572726f72080454000449000104104c69737404003d0901244c6973744572726f72000004b441206572726f7220696e20746865206c69737420696e7465726661636520696d706c656d656e746174696f6e2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e3d090c4070616c6c65745f626167735f6c697374106c697374244c6973744572726f72000110244475706c6963617465000000284e6f7448656176696572000100304e6f74496e53616d65426167000200304e6f64654e6f74466f756e64000300004109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328506f6f6c4d656d626572040454000010011c706f6f6c5f6964100118506f6f6c4964000118706f696e747318013042616c616e63654f663c543e0001706c6173745f7265636f726465645f7265776172645f636f756e746572a5070140543a3a526577617264436f756e746572000138756e626f6e64696e675f65726173450901e0426f756e64656442547265654d61703c457261496e6465782c2042616c616e63654f663c543e2c20543a3a4d6178556e626f6e64696e673e000045090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601180453000004004909013842547265654d61703c4b2c20563e00004909042042547265654d617008044b0110045601180004004d090000004d090000025109005109000004081018005509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c733c426f6e646564506f6f6c496e6e65720404540000140128636f6d6d697373696f6e59090134436f6d6d697373696f6e3c543e0001386d656d6265725f636f756e74657210010c753332000118706f696e747318013042616c616e63654f663c543e000114726f6c65736509015c506f6f6c526f6c65733c543a3a4163636f756e7449643e00011473746174651d010124506f6f6c537461746500005909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61785d09013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f72617465610901bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d810401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e2d0101bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e00005d0904184f7074696f6e04045401f40108104e6f6e6500000010536f6d650400f40000010000610904184f7074696f6e0404540129010108104e6f6e6500000010536f6d650400290100000100006509085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e00006909085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e746572a5070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e00006d09085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7320537562506f6f6c7304045400000801186e6f5f65726171090134556e626f6e64506f6f6c3c543e000120776974685f6572617509010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e00007109085c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e000075090c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b011004560171090453000004007909013842547265654d61703c4b2c20563e00007909042042547265654d617008044b011004560171090004007d090000007d090000028109008109000004081071090085090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c6574144572726f7204045400019430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e644163636f756e7442656c6f6e6773546f4f74686572506f6f6c0004084d01416e206163636f756e7420697320616c72656164792064656c65676174696e6720696e20616e6f7468657220706f6f6c2e20416e206163636f756e74206d6179206f6e6c792062656c6f6e6720746f206f6e653c706f6f6c20617420612074696d652e3846756c6c79556e626f6e64696e670005083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740006040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790007044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000814290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0009042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e67000a085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000b04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000c043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000d047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000e04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000f049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e676553746174650010048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001104b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001204ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e73697665040089090138446566656e736976654572726f720013083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001404bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640015041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001604ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001704e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400180409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640019040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001a04a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001b048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001c0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001d049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001e04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001f04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e384e6f7468696e67546f536c617368002004cc4e6f20736c6173682070656e64696e6720746861742063616e206265206170706c69656420746f20746865206d656d6265722e2c536c617368546f6f4c6f77002104a854686520736c61736820616d6f756e7420697320746f6f206c6f7720746f206265206170706c6965642e3c416c72656164794d69677261746564002204150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e2068617320616c7265616479206d6967726174656420746f2064656c6567617465207374616b652e2c4e6f744d69677261746564002304150154686520706f6f6c206f72206d656d6265722064656c65676174696f6e20686173206e6f74206d696772617465642079657420746f2064656c6567617465207374616b652e304e6f74537570706f72746564002404f0546869732063616c6c206973206e6f7420616c6c6f77656420696e207468652063757272656e74207374617465206f66207468652070616c6c65742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e89090c5c70616c6c65745f6e6f6d696e6174696f6e5f706f6f6c731870616c6c657438446566656e736976654572726f7200011c684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c790004005444656c65676174696f6e556e737570706f727465640005003c536c6173684e6f744170706c696564000600008d090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019109045300000400990901185665633c543e0000910904184f7074696f6e0404540195090108104e6f6e6500000010536f6d650400950900000100009509084070616c6c65745f7363686564756c6572245363686564756c656414104e616d6501041043616c6c012d032c426c6f636b4e756d62657201303450616c6c6574734f726967696e017105244163636f756e7449640100001401206d617962655f69643d0101304f7074696f6e3c4e616d653e0001207072696f726974790801487363686564756c653a3a5072696f7269747900011063616c6c2d03011043616c6c0001386d617962655f706572696f646963b10401944f7074696f6e3c7363686564756c653a3a506572696f643c426c6f636b4e756d6265723e3e0001186f726967696e7105013450616c6c6574734f726967696e000099090000029109009d09084070616c6c65745f7363686564756c65722c5265747279436f6e6669670418506572696f640130000c0134746f74616c5f72657472696573080108753800012472656d61696e696e670801087538000118706572696f64300118506572696f640000a1090c4070616c6c65745f7363686564756c65721870616c6c6574144572726f72040454000114404661696c6564546f5363686564756c65000004644661696c656420746f207363686564756c6520612063616c6c204e6f74466f756e640001047c43616e6e6f742066696e6420746865207363686564756c65642063616c6c2e5c546172676574426c6f636b4e756d626572496e50617374000204a4476976656e2074617267657420626c6f636b206e756d62657220697320696e2074686520706173742e4852657363686564756c654e6f4368616e6765000304f052657363686564756c65206661696c6564206265636175736520697420646f6573206e6f74206368616e6765207363686564756c65642074696d652e144e616d6564000404d0417474656d707420746f207573652061206e6f6e2d6e616d65642066756e6374696f6e206f6e2061206e616d6564207461736b2e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ea509083c70616c6c65745f707265696d616765404f6c645265717565737453746174757308244163636f756e74496401001c42616c616e6365011801082c556e72657175657374656408011c6465706f736974d40150284163636f756e7449642c2042616c616e63652900010c6c656e10010c753332000000245265717565737465640c011c6465706f736974a90901704f7074696f6e3c284163636f756e7449642c2042616c616e6365293e000114636f756e7410010c75333200010c6c656e3d03012c4f7074696f6e3c7533323e00010000a90904184f7074696f6e04045401d40108104e6f6e6500000010536f6d650400d40000010000ad09083c70616c6c65745f707265696d616765345265717565737453746174757308244163636f756e7449640100185469636b6574018401082c556e7265717565737465640801187469636b6574b109014c284163636f756e7449642c205469636b65742900010c6c656e10010c753332000000245265717565737465640c01306d617962655f7469636b6574b509016c4f7074696f6e3c284163636f756e7449642c205469636b6574293e000114636f756e7410010c7533320001246d617962655f6c656e3d03012c4f7074696f6e3c7533323e00010000b10900000408008400b50904184f7074696f6e04045401b1090108104e6f6e6500000010536f6d650400b1090000010000b9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000bd090c3c70616c6c65745f707265696d6167651870616c6c6574144572726f7204045400012418546f6f426967000004a0507265696d61676520697320746f6f206c6172676520746f2073746f7265206f6e2d636861696e2e30416c72656164794e6f746564000104a4507265696d6167652068617320616c7265616479206265656e206e6f746564206f6e2d636861696e2e344e6f74417574686f72697a6564000204c85468652075736572206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e2e204e6f744e6f746564000304fc54686520707265696d6167652063616e6e6f742062652072656d6f7665642073696e636520697420686173206e6f7420796574206265656e206e6f7465642e2452657175657374656400040409014120707265696d616765206d6179206e6f742062652072656d6f766564207768656e20746865726520617265206f75747374616e64696e672072657175657374732e304e6f745265717565737465640005042d0154686520707265696d61676520726571756573742063616e6e6f742062652072656d6f7665642073696e6365206e6f206f75747374616e64696e672072657175657374732065786973742e1c546f6f4d616e7900060455014d6f7265207468616e20604d41585f484153485f555047524144455f42554c4b5f434f554e54602068617368657320776572652072657175657374656420746f206265207570677261646564206174206f6e63652e18546f6f466577000704e4546f6f206665772068617368657320776572652072657175657374656420746f2062652075706772616465642028692e652e207a65726f292e184e6f436f737400080459014e6f207469636b65742077697468206120636f7374207761732072657475726e6564206279205b60436f6e6669673a3a436f6e73696465726174696f6e605d20746f2073746f72652074686520707265696d6167652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ec1090c2873705f7374616b696e671c6f6666656e6365384f6666656e636544657461696c7308205265706f727465720100204f6666656e646572016501000801206f6666656e646572650101204f6666656e6465720001247265706f7274657273350201345665633c5265706f727465723e0000c5090000040849013800c9090c3c70616c6c65745f74785f70617573651870616c6c6574144572726f720404540001102049735061757365640000044c5468652063616c6c206973207061757365642e284973556e706175736564000104545468652063616c6c20697320756e7061757365642e28556e7061757361626c65000204b45468652063616c6c2069732077686974656c697374656420616e642063616e6e6f74206265207061757365642e204e6f74466f756e64000300048054686520604572726f726020656e756d206f6620746869732070616c6c65742ecd090c4c626f756e6465645f636f6c6c656374696f6e73407765616b5f626f756e6465645f766563385765616b426f756e646564566563080454015d01045300000400d10901185665633c543e0000d1090000025d0100d5090c4070616c6c65745f696d5f6f6e6c696e651870616c6c6574144572726f7204045400010828496e76616c69644b6579000004604e6f6e206578697374656e74207075626c6963206b65792e4c4475706c696361746564486561727462656174000104544475706c696361746564206865617274626561742e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ed90900000408dd09ed0900dd090c3c70616c6c65745f6964656e7469747914747970657330526567697374726174696f6e0c1c42616c616e63650118344d61784a756467656d656e747300304964656e74697479496e666f01cd04000c01286a756467656d656e7473e10901fc426f756e6465645665633c28526567697374726172496e6465782c204a756467656d656e743c42616c616e63653e292c204d61784a756467656d656e74733e00011c6465706f73697418011c42616c616e6365000110696e666fcd0401304964656e74697479496e666f0000e1090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401e509045300000400e90901185665633c543e0000e50900000408105d0500e909000002e50900ed0904184f7074696f6e040454017d010108104e6f6e6500000010536f6d6504007d010000010000f1090000040818f50900f5090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400350201185665633c543e0000f9090c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401fd09045300000400050a01185665633c543e0000fd0904184f7074696f6e04045401010a0108104e6f6e6500000010536f6d650400010a0000010000010a0c3c70616c6c65745f6964656e7469747914747970657334526567697374726172496e666f0c1c42616c616e63650118244163636f756e74496401001c49644669656c640130000c011c6163636f756e740001244163636f756e74496400010c66656518011c42616c616e63650001186669656c647330011c49644669656c640000050a000002fd0900090a0c3c70616c6c65745f6964656e746974791474797065734c417574686f7269747950726f706572746965730418537566666978010d0a000801187375666669780d0a0118537566666978000128616c6c6f636174696f6e100128416c6c6f636174696f6e00000d0a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000110a00000408003000150a0c3c70616c6c65745f6964656e746974791870616c6c6574144572726f7204045400016848546f6f4d616e795375624163636f756e74730000045c546f6f206d616e7920737562732d6163636f756e74732e204e6f74466f756e64000104504163636f756e742069736e277420666f756e642e204e6f744e616d6564000204504163636f756e742069736e2774206e616d65642e28456d707479496e64657800030430456d70747920696e6465782e284665654368616e6765640004043c466565206973206368616e6765642e284e6f4964656e74697479000504484e6f206964656e7469747920666f756e642e3c537469636b794a756467656d656e7400060444537469636b79206a756467656d656e742e384a756467656d656e74476976656e000704404a756467656d656e7420676976656e2e40496e76616c69644a756467656d656e7400080448496e76616c6964206a756467656d656e742e30496e76616c6964496e6465780009045454686520696e64657820697320696e76616c69642e34496e76616c6964546172676574000a04585468652074617267657420697320696e76616c69642e44546f6f4d616e7952656769737472617273000b04e84d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e38416c7265616479436c61696d6564000c04704163636f756e7420494420697320616c7265616479206e616d65642e184e6f74537562000d047053656e646572206973206e6f742061207375622d6163636f756e742e204e6f744f776e6564000e04885375622d6163636f756e742069736e2774206f776e65642062792073656e6465722e744a756467656d656e74466f72446966666572656e744964656e74697479000f04d05468652070726f7669646564206a756467656d656e742077617320666f72206120646966666572656e74206964656e746974792e584a756467656d656e745061796d656e744661696c6564001004f84572726f722074686174206f6363757273207768656e20746865726520697320616e20697373756520706179696e6720666f72206a756467656d656e742e34496e76616c6964537566666978001104805468652070726f76696465642073756666697820697320746f6f206c6f6e672e504e6f74557365726e616d65417574686f72697479001204e05468652073656e64657220646f6573206e6f742068617665207065726d697373696f6e20746f206973737565206120757365726e616d652e304e6f416c6c6f636174696f6e001304c454686520617574686f726974792063616e6e6f7420616c6c6f6361746520616e79206d6f726520757365726e616d65732e40496e76616c69645369676e6174757265001404a8546865207369676e6174757265206f6e206120757365726e616d6520776173206e6f742076616c69642e4452657175697265735369676e6174757265001504090153657474696e67207468697320757365726e616d652072657175697265732061207369676e61747572652c20627574206e6f6e65207761732070726f76696465642e3c496e76616c6964557365726e616d65001604b054686520757365726e616d6520646f6573206e6f74206d6565742074686520726571756972656d656e74732e34557365726e616d6554616b656e0017047854686520757365726e616d6520697320616c72656164792074616b656e2e284e6f557365726e616d65001804985468652072657175657374656420757365726e616d6520646f6573206e6f742065786973742e284e6f74457870697265640019042d0154686520757365726e616d652063616e6e6f7420626520666f72636566756c6c792072656d6f76656420626563617573652069742063616e207374696c6c2062652061636365707465642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e190a0c3870616c6c65745f7574696c6974791870616c6c6574144572726f7204045400010430546f6f4d616e7943616c6c730000045c546f6f206d616e792063616c6c7320626174636865642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e1d0a00000408000400210a083c70616c6c65745f6d756c7469736967204d756c7469736967102c426c6f636b4e756d62657201301c42616c616e63650118244163636f756e7449640100304d6178417070726f76616c7300001001107768656e8901015854696d65706f696e743c426c6f636b4e756d6265723e00011c6465706f73697418011c42616c616e63650001246465706f7369746f720001244163636f756e744964000124617070726f76616c735d04018c426f756e6465645665633c4163636f756e7449642c204d6178417070726f76616c733e0000250a0c3c70616c6c65745f6d756c74697369671870616c6c6574144572726f72040454000138404d696e696d756d5468726573686f6c640000047c5468726573686f6c64206d7573742062652032206f7220677265617465722e3c416c7265616479417070726f766564000104ac43616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e444e6f417070726f76616c734e65656465640002049c43616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e44546f6f4665775369676e61746f72696573000304a854686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e48546f6f4d616e795369676e61746f72696573000404ac54686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e545369676e61746f726965734f75744f664f726465720005040d01546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e4c53656e646572496e5369676e61746f726965730006040d015468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e204e6f74466f756e64000704dc4d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e204e6f744f776e65720008042d014f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e2c4e6f54696d65706f696e740009041d014e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e3857726f6e6754696d65706f696e74000a042d014120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e4c556e657870656374656454696d65706f696e74000b04f4412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e3c4d6178576569676874546f6f4c6f77000c04d0546865206d6178696d756d2077656967687420696e666f726d6174696f6e2070726f76696465642077617320746f6f206c6f772e34416c726561647953746f726564000d04a0546865206461746120746f2062652073746f72656420697320616c72656164792073746f7265642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e290a0000022d0a002d0a0000040c8d05310a410a00310a081866705f727063445472616e73616374696f6e53746174757300001c01407472616e73616374696f6e5f68617368340110483235360001447472616e73616374696f6e5f696e64657810010c75333200011066726f6d9101011c41646472657373000108746f0906013c4f7074696f6e3c416464726573733e000140636f6e74726163745f616464726573730906013c4f7074696f6e3c416464726573733e0001106c6f6773350a01205665633c4c6f673e0001286c6f67735f626c6f6f6d390a0114426c6f6f6d0000350a000002bd0100390a0820657468626c6f6f6d14426c6f6f6d000004003d0a01405b75383b20424c4f4f4d5f53495a455d00003d0a000003000100000800410a0c20657468657265756d1c726563656970742452656365697074563300010c184c65676163790400450a014445495036353852656365697074446174610000001c454950323933300400450a01484549503239333052656365697074446174610001001c454950313535390400450a014845495031353539526563656970744461746100020000450a0c20657468657265756d1c72656365697074444549503635385265636569707444617461000010012c7374617475735f636f64650801087538000120757365645f676173c9010110553235360001286c6f67735f626c6f6f6d390a0114426c6f6f6d0001106c6f6773350a01205665633c4c6f673e0000490a0c20657468657265756d14626c6f636b14426c6f636b040454018d05000c01186865616465724d0a01184865616465720001307472616e73616374696f6e73550a01185665633c543e0001186f6d6d657273590a012c5665633c4865616465723e00004d0a0c20657468657265756d186865616465721848656164657200003c012c706172656e745f686173683401104832353600012c6f6d6d6572735f686173683401104832353600012c62656e6566696369617279910101104831363000012873746174655f726f6f74340110483235360001447472616e73616374696f6e735f726f6f743401104832353600013472656365697074735f726f6f74340110483235360001286c6f67735f626c6f6f6d390a0114426c6f6f6d000128646966666963756c7479c9010110553235360001186e756d626572c9010110553235360001246761735f6c696d6974c9010110553235360001206761735f75736564c90101105532353600012474696d657374616d7030010c75363400012865787472615f6461746138011442797465730001206d69785f68617368340110483235360001146e6f6e6365510a010c4836340000510a0c38657468657265756d5f747970657310686173680c48363400000400ad02011c5b75383b20385d0000550a0000028d0500590a0000024d0a005d0a000002410a00610a000002310a00650a0c3c70616c6c65745f657468657265756d1870616c6c6574144572726f7204045400010840496e76616c69645369676e6174757265000004545369676e617475726520697320696e76616c69642e305072654c6f67457869737473000104d85072652d6c6f672069732070726573656e742c207468657265666f7265207472616e73616374206973206e6f7420616c6c6f7765642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e690a082870616c6c65745f65766d30436f64654d65746164617461000008011073697a6530010c753634000110686173683401104832353600006d0a0000040891013400710a0c2870616c6c65745f65766d1870616c6c6574144572726f720404540001342842616c616e63654c6f77000004904e6f7420656e6f7567682062616c616e636520746f20706572666f726d20616374696f6e2c4665654f766572666c6f770001048043616c63756c6174696e6720746f74616c20666565206f766572666c6f7765643c5061796d656e744f766572666c6f770002049043616c63756c6174696e6720746f74616c207061796d656e74206f766572666c6f7765643857697468647261774661696c65640003044c576974686472617720666565206661696c6564384761735072696365546f6f4c6f770004045447617320707269636520697320746f6f206c6f772e30496e76616c69644e6f6e6365000504404e6f6e636520697320696e76616c6964384761734c696d6974546f6f4c6f7700060454476173206c696d697420697320746f6f206c6f772e3c4761734c696d6974546f6f4869676800070458476173206c696d697420697320746f6f20686967682e38496e76616c6964436861696e49640008046054686520636861696e20696420697320696e76616c69642e40496e76616c69645369676e617475726500090464746865207369676e617475726520697320696e76616c69642e285265656e7472616e6379000a043845564d207265656e7472616e6379685472616e73616374696f6e4d757374436f6d6546726f6d454f41000b04244549502d333630372c24556e646566696e6564000c0440556e646566696e6564206572726f722e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e750a0c6470616c6c65745f686f746669785f73756666696369656e74731870616c6c6574144572726f720404540001045c4d617841646472657373436f756e744578636565646564000004784d6178696d756d206164647265737320636f756e74206578636565646564048054686520604572726f726020656e756d206f6620746869732070616c6c65742e790a0000040830d901007d0a0c5470616c6c65745f61697264726f705f636c61696d731870616c6c6574144572726f7204045400012060496e76616c6964457468657265756d5369676e61747572650000046c496e76616c696420457468657265756d207369676e61747572652e58496e76616c69644e61746976655369676e617475726500010488496e76616c6964204e617469766520287372323535313929207369676e617475726550496e76616c69644e61746976654163636f756e740002047c496e76616c6964204e6174697665206163636f756e74206465636f64696e67405369676e65724861734e6f436c61696d00030478457468657265756d206164647265737320686173206e6f20636c61696d2e4053656e6465724861734e6f436c61696d000404b04163636f756e742049442073656e64696e67207472616e73616374696f6e20686173206e6f20636c61696d2e30506f74556e646572666c6f77000508490154686572652773206e6f7420656e6f75676820696e2074686520706f7420746f20706179206f757420736f6d6520756e76657374656420616d6f756e742e2047656e6572616c6c7920696d706c6965732061306c6f676963206572726f722e40496e76616c696453746174656d656e740006049041206e65656465642073746174656d656e7420776173206e6f7420696e636c756465642e4c56657374656442616c616e6365457869737473000704a4546865206163636f756e7420616c7265616479206861732061207665737465642062616c616e63652e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e810a00000408850a1800850a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401890a0453000004008d0a01185665633c543e0000890a083070616c6c65745f70726f78793c50726f7879446566696e6974696f6e0c244163636f756e74496401002450726f78795479706501e5012c426c6f636b4e756d6265720130000c012064656c65676174650001244163636f756e74496400012870726f78795f74797065e501012450726f78795479706500011464656c617930012c426c6f636b4e756d62657200008d0a000002890a00910a00000408950a1800950a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401990a0453000004009d0a01185665633c543e0000990a083070616c6c65745f70726f787930416e6e6f756e63656d656e740c244163636f756e7449640100104861736801342c426c6f636b4e756d6265720130000c01107265616c0001244163636f756e74496400012463616c6c5f686173683401104861736800011868656967687430012c426c6f636b4e756d62657200009d0a000002990a00a10a0c3070616c6c65745f70726f78791870616c6c6574144572726f720404540001201c546f6f4d616e79000004210154686572652061726520746f6f206d616e792070726f786965732072656769737465726564206f7220746f6f206d616e7920616e6e6f756e63656d656e74732070656e64696e672e204e6f74466f756e640001047450726f787920726567697374726174696f6e206e6f7420666f756e642e204e6f7450726f7879000204cc53656e646572206973206e6f7420612070726f7879206f6620746865206163636f756e7420746f2062652070726f786965642e2c556e70726f787961626c650003042101412063616c6c20776869636820697320696e636f6d70617469626c652077697468207468652070726f7879207479706527732066696c7465722077617320617474656d707465642e244475706c69636174650004046c4163636f756e7420697320616c726561647920612070726f78792e304e6f5065726d697373696f6e000504150143616c6c206d6179206e6f74206265206d6164652062792070726f78792062656361757365206974206d617920657363616c617465206974732070726976696c656765732e2c556e616e6e6f756e636564000604d0416e6e6f756e63656d656e742c206966206d61646520617420616c6c2c20776173206d61646520746f6f20726563656e746c792e2c4e6f53656c6650726f78790007046443616e6e6f74206164642073656c662061732070726f78792e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ea50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f724d6574616461746114244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301a90a344d6178426c75657072696e747301ad0a001801147374616b6518011c42616c616e636500014064656c65676174696f6e5f636f756e7410010c75333200011c72657175657374b10a01a04f7074696f6e3c4f70657261746f72426f6e644c657373526571756573743c42616c616e63653e3e00012c64656c65676174696f6e73b90a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e000118737461747573c50a01384f70657261746f72537461747573000134626c75657072696e745f696473c90a0178426f756e6465645665633c7533322c204d6178426c75657072696e74733e0000a90a085874616e676c655f746573746e65745f72756e74696d65384d617844656c65676174696f6e7300000000ad0a085874616e676c655f746573746e65745f72756e74696d65544d61784f70657261746f72426c75657072696e747300000000b10a04184f7074696f6e04045401b50a0108104e6f6e6500000010536f6d650400b50a0000010000b50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f725c4f70657261746f72426f6e644c65737352657175657374041c42616c616e6365011800080118616d6f756e7418011c42616c616e6365000130726571756573745f74696d65100128526f756e64496e6465780000b90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401bd0a045300000400c10a01185665633c543e0000bd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f723444656c656761746f72426f6e640c244163636f756e74496401001c42616c616e636501181c417373657449640118000c012464656c656761746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e0000c10a000002bd0a00c50a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72384f70657261746f7253746174757300010c1841637469766500000020496e6163746976650001001c4c656176696e670400100128526f756e64496e64657800020000c90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540110045300000400490401185665633c543e0000cd0a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e147479706573206f70657261746f72404f70657261746f72536e617073686f7410244163636f756e74496401001c42616c616e636501181c417373657449640118384d617844656c65676174696f6e7301a90a000801147374616b6518011c42616c616e636500012c64656c65676174696f6e73b90a011901426f756e6465645665633c44656c656761746f72426f6e643c4163636f756e7449642c2042616c616e63652c20417373657449643e2c204d617844656c65676174696f6e733e0000d10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f724444656c656761746f724d6574616461746124244163636f756e74496401001c42616c616e636501181c4173736574496401184c4d61785769746864726177526571756573747301d50a384d617844656c65676174696f6e7301a90a484d6178556e7374616b65526571756573747301d90a344d6178426c75657072696e74730119062c426c6f636b4e756d6265720130204d61784c6f636b7301a90a001401206465706f73697473dd0a01050142547265654d61703c41737365743c417373657449643e2c204465706f7369743c42616c616e63652c20426c6f636b4e756d6265722c204d61784c6f636b733e3e00014477697468647261775f7265717565737473fd0a010901426f756e6465645665633c5769746864726177526571756573743c417373657449642c2042616c616e63653e2c204d6178576974686472617752657175657374733e00012c64656c65676174696f6e73090b016901426f756e6465645665633c426f6e64496e666f44656c656761746f723c4163636f756e7449642c2042616c616e63652c20417373657449642c204d6178426c75657072696e74733e0a2c204d617844656c65676174696f6e733e00016864656c656761746f725f756e7374616b655f7265717565737473150b016d01426f756e6465645665633c426f6e644c657373526571756573743c4163636f756e7449642c20417373657449642c2042616c616e63652c204d6178426c75657072696e74733e2c0a4d6178556e7374616b6552657175657374733e000118737461747573210b013c44656c656761746f725374617475730000d50a085874616e676c655f746573746e65745f72756e74696d654c4d61785769746864726177526571756573747300000000d90a085874616e676c655f746573746e65745f72756e74696d65484d6178556e7374616b65526571756573747300000000dd0a042042547265654d617008044b01f101045601e10a000400f50a000000e10a107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f721c4465706f7369740c1c42616c616e636501182c426c6f636b4e756d6265720130204d61784c6f636b7301a90a000c0118616d6f756e7418011c42616c616e636500014064656c6567617465645f616d6f756e7418011c42616c616e63650001146c6f636b73e50a01f04f7074696f6e3c426f756e6465645665633c4c6f636b496e666f3c42616c616e63652c20426c6f636b4e756d6265723e2c204d61784c6f636b733e3e0000e50a04184f7074696f6e04045401e90a0108104e6f6e6500000010536f6d650400e90a0000010000e90a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401ed0a045300000400f10a01185665633c543e0000ed0a104474616e676c655f7072696d6974697665731474797065731c72657761726473204c6f636b496e666f081c42616c616e636501182c426c6f636b4e756d6265720130000c0118616d6f756e7418011c42616c616e636500013c6c6f636b5f6d756c7469706c696572110601384c6f636b4d756c7469706c6965720001306578706972795f626c6f636b30012c426c6f636b4e756d6265720000f10a000002ed0a00f50a000002f90a00f90a00000408f101e10a00fd0a0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401010b045300000400050b01185665633c543e0000010b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c576974686472617752657175657374081c4173736574496401181c42616c616e63650118000c012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e6465780000050b000002010b00090b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010d0b045300000400110b01185665633c543e00000d0b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f7244426f6e64496e666f44656c656761746f7210244163636f756e74496401001c42616c616e636501181c417373657449640118344d6178426c75657072696e7473011906001001206f70657261746f720001244163636f756e744964000118616d6f756e7418011c42616c616e636500012061737365745f6964f101013841737365743c417373657449643e00014c626c75657072696e745f73656c656374696f6e150601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e0000110b0000020d0b00150b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401190b0453000004001d0b01185665633c543e0000190b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c426f6e644c6573735265717565737410244163636f756e74496401001c4173736574496401181c42616c616e63650118344d6178426c75657072696e7473011906001401206f70657261746f720001244163636f756e74496400012061737365745f6964f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e636500013c7265717565737465645f726f756e64100128526f756e64496e64657800014c626c75657072696e745f73656c656374696f6e150601a844656c656761746f72426c75657072696e7453656c656374696f6e3c4d6178426c75657072696e74733e00001d0b000002190b00210b107470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1474797065732464656c656761746f723c44656c656761746f7253746174757300010818416374697665000000404c656176696e675363686564756c65640400100128526f756e64496e64657800010000250b0c7470616c6c65745f6d756c74695f61737365745f64656c65676174696f6e1870616c6c6574144572726f720404540001d03c416c72656164794f70657261746f720000048c546865206163636f756e7420697320616c726561647920616e206f70657261746f722e28426f6e64546f6f4c6f7700010470546865207374616b6520616d6f756e7420697320746f6f206c6f772e344e6f74416e4f70657261746f720002047c546865206163636f756e74206973206e6f7420616e206f70657261746f722e2843616e6e6f744578697400030460546865206163636f756e742063616e6e6f7420657869742e38416c72656164794c656176696e6700040480546865206f70657261746f7220697320616c7265616479206c656176696e672e484e6f744c656176696e674f70657261746f72000504a8546865206163636f756e74206973206e6f74206c656176696e6720617320616e206f70657261746f722e3c4e6f744c656176696e67526f756e64000604cc54686520726f756e6420646f6573206e6f74206d6174636820746865207363686564756c6564206c6561766520726f756e642e584c656176696e67526f756e644e6f7452656163686564000704644c656176696e6720726f756e64206e6f7420726561636865644c4e6f5363686564756c6564426f6e644c657373000804985468657265206973206e6f207363686564756c656420756e7374616b6520726571756573742e6c426f6e644c657373526571756573744e6f745361746973666965640009049454686520756e7374616b652072657175657374206973206e6f74207361746973666965642e444e6f744163746976654f70657261746f72000a046c546865206f70657261746f72206973206e6f74206163746976652e484e6f744f66666c696e654f70657261746f72000b0470546865206f70657261746f72206973206e6f74206f66666c696e652e40416c726561647944656c656761746f72000c048c546865206163636f756e7420697320616c726561647920612064656c656761746f722e304e6f7444656c656761746f72000d047c546865206163636f756e74206973206e6f7420612064656c656761746f722e70576974686472617752657175657374416c7265616479457869737473000e048841207769746864726177207265717565737420616c7265616479206578697374732e4c496e73756666696369656e7442616c616e6365000f0494546865206163636f756e742068617320696e73756666696369656e742062616c616e63652e444e6f576974686472617752657175657374001004745468657265206973206e6f20776974686472617720726571756573742e444e6f426f6e644c65737352657175657374001104705468657265206973206e6f20756e7374616b6520726571756573742e40426f6e644c6573734e6f7452656164790012048454686520756e7374616b652072657175657374206973206e6f742072656164792e70426f6e644c65737352657175657374416c7265616479457869737473001304844120756e7374616b65207265717565737420616c7265616479206578697374732e6041637469766553657276696365735573696e674173736574001404a854686572652061726520616374697665207365727669636573207573696e67207468652061737365742e484e6f41637469766544656c65676174696f6e001504785468657265206973206e6f74206163746976652064656c65676174696f6e4c41737365744e6f7457686974656c697374656400160470546865206173736574206973206e6f742077686974656c6973746564344e6f74417574686f72697a6564001704cc546865206f726967696e206973206e6f7420617574686f72697a656420746f20706572666f726d207468697320616374696f6e544d6178426c75657072696e74734578636565646564001804944d6178696d756d206e756d626572206f6620626c75657072696e74732065786365656465643441737365744e6f74466f756e6400190464546865206173736574204944206973206e6f7420666f756e646c426c75657072696e74416c726561647957686974656c6973746564001a049c54686520626c75657072696e7420494420697320616c72656164792077686974656c6973746564484e6f77697468647261775265717565737473001b04684e6f20776974686472617720726571756573747320666f756e64644e6f4d61746368696e67776974686472617752657175657374001c04884e6f206d61746368696e67207769746864726177207265716573747320666f756e644c4173736574416c7265616479496e5661756c74001d0498417373657420616c72656164792065786973747320696e206120726577617264207661756c743c41737365744e6f74496e5661756c74001e047c4173736574206e6f7420666f756e6420696e20726577617264207661756c74345661756c744e6f74466f756e64001f047c54686520726577617264207661756c7420646f6573206e6f74206578697374504475706c6963617465426c75657072696e74496400200415014572726f722072657475726e6564207768656e20747279696e6720746f20616464206120626c75657072696e74204944207468617420616c7265616479206578697374732e4c426c75657072696e7449644e6f74466f756e640021041d014572726f722072657475726e6564207768656e20747279696e6720746f2072656d6f7665206120626c75657072696e74204944207468617420646f65736e27742065786973742e384e6f74496e46697865644d6f64650022043d014572726f722072657475726e6564207768656e20747279696e6720746f206164642f72656d6f766520626c75657072696e7420494473207768696c65206e6f7420696e204669786564206d6f64652e584d617844656c65676174696f6e73457863656564656400230409014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662064656c65676174696f6e732069732065786365656465642e684d6178556e7374616b65526571756573747345786365656465640024041d014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f6620756e7374616b652072657175657374732069732065786365656465642e6c4d617857697468647261775265717565737473457863656564656400250421014572726f722072657475726e6564207768656e20746865206d6178696d756d206e756d626572206f662077697468647261772072657175657374732069732065786365656465642e3c4465706f7369744f766572666c6f770026045c4465706f73697420616d6f756e74206f766572666c6f7754556e7374616b65416d6f756e74546f6f4c6172676500270444556e7374616b6520756e646572666c6f77345374616b654f766572666c6f770028046c4f766572666c6f77207768696c6520616464696e67207374616b6568496e73756666696369656e745374616b6552656d61696e696e6700290478556e646572666c6f77207768696c65207265647563696e67207374616b6544415059457863656564734d6178696d756d002a04b04150592065786365656473206d6178696d756d20616c6c6f776564206279207468652065787472696e7369633c43617043616e6e6f7442655a65726f002b04484361702063616e6e6f74206265207a65726f5443617045786365656473546f74616c537570706c79002c0484436170206578636565647320746f74616c20737570706c79206f662061737365746c50656e64696e67556e7374616b6552657175657374457869737473002d0494416e20756e7374616b65207265717565737420697320616c72656164792070656e64696e6750426c75657072696e744e6f7453656c6563746564002e047454686520626c75657072696e74206973206e6f742073656c65637465644c45524332305472616e736665724661696c6564002f04544572633230207472616e73666572206661696c65643045564d416269456e636f64650030044045564d20656e636f6465206572726f723045564d4162694465636f64650031044045564d206465636f6465206572726f72344c6f636b56696f6c6174696f6e0032046443616e6e6f7420756e7374616b652077697468206c6f636b73644465706f73697445786365656473436170466f7241737365740033046041626f7665206465706f736974206361707320736574757004744572726f727320656d6974746564206279207468652070616c6c65742e290b00000408002906002d0b00000408300000310b0c4474616e676c655f7072696d69746976657320736572766963657338536572766963655265717565737410044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273350b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e000118617373657473390b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d626572000110617267733d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0001746f70657261746f72735f776974685f617070726f76616c5f7374617465410b010501426f756e6465645665633c284163636f756e7449642c20417070726f76616c5374617465292c20433a3a4d61784f70657261746f7273506572536572766963653e0000350b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540100045300000400350201185665633c543e0000390b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e6465645665630804540118045300000400390201185665633c543e00003d0b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454010902045300000400050201185665633c543e0000410b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401450b0453000004004d0b01185665633c543e0000450b0000040800490b00490b0c4474616e676c655f7072696d69746976657320736572766963657334417070726f76616c537461746500010c1c50656e64696e6700000020417070726f76656404014472657374616b696e675f70657263656e745502011c50657263656e740001002052656a6563746564000200004d0b000002450b00510b0c4474616e676c655f7072696d6974697665732073657276696365731c5365727669636510044300244163636f756e74496401002c426c6f636b4e756d62657201301c417373657449640118001c0108696430010c753634000124626c75657072696e7430010c7536340001146f776e65720001244163636f756e7449640001447065726d69747465645f63616c6c657273350b01b4426f756e6465645665633c4163636f756e7449642c20433a3a4d61785065726d697474656443616c6c6572733e0001246f70657261746f7273550b01ec426f756e6465645665633c284163636f756e7449642c2050657263656e74292c20433a3a4d61784f70657261746f7273506572536572766963653e000118617373657473390b01ac426f756e6465645665633c417373657449642c20433a3a4d6178417373657473506572536572766963653e00010c74746c30012c426c6f636b4e756d6265720000550b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401590b0453000004005d0b01185665633c543e0000590b00000408005502005d0b000002590b00610b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400650b012c42547265655365743c543e0000650b0420425472656553657404045401300004002106000000690b0c4474616e676c655f7072696d6974697665732073657276696365731c4a6f6243616c6c08044300244163636f756e7449640100000c0128736572766963655f696430010c75363400010c6a6f620801087538000110617267733d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e00006d0b0c4474616e676c655f7072696d697469766573207365727669636573344a6f6243616c6c526573756c7408044300244163636f756e7449640100000c0128736572766963655f696430010c75363400011c63616c6c5f696430010c753634000118726573756c743d0b01b4426f756e6465645665633c4669656c643c432c204163636f756e7449643e2c20433a3a4d61784669656c64733e0000710b0c3c70616c6c65745f736572766963657314747970657338556e6170706c696564536c61736808244163636f756e74496401001c42616c616e6365011800180128736572766963655f696430010c7536340001206f70657261746f720001244163636f756e74496400010c6f776e18011c42616c616e63650001186f7468657273d001645665633c284163636f756e7449642c2042616c616e6365293e0001247265706f7274657273350201385665633c4163636f756e7449643e0001187061796f757418011c42616c616e63650000750b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e646564566563080454019101045300000400cd0501185665633c543e0000790b0c4474616e676c655f7072696d6974697665732073657276696365733c4f70657261746f7250726f66696c65040443000008012073657276696365737d0b01bc426f756e64656442547265655365743c7536342c20433a3a4d617853657276696365735065724f70657261746f723e000128626c75657072696e7473810b01c4426f756e64656442547265655365743c7536342c20433a3a4d6178426c75657072696e74735065724f70657261746f723e00007d0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400650b012c42547265655365743c543e0000810b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f7365743c426f756e64656442547265655365740804540130045300000400650b012c42547265655365743c543e0000850b0c4474616e676c655f7072696d6974697665732073657276696365735453746167696e67536572766963655061796d656e740c244163636f756e74496401001c4173736574496401181c42616c616e6365011800100128726571756573745f696430010c753634000124726566756e645f746f890b01484163636f756e743c4163636f756e7449643e0001146173736574f101013841737365743c417373657449643e000118616d6f756e7418011c42616c616e63650000890b0c4474616e676c655f7072696d6974697665731474797065731c4163636f756e7404244163636f756e7449640100010808496404000001244163636f756e7449640000001c4164647265737304009101013473705f636f72653a3a48313630000100008d0b0c3c70616c6c65745f7365727669636573186d6f64756c65144572726f720404540001ac44426c75657072696e744e6f74466f756e6400000490546865207365727669636520626c75657072696e7420776173206e6f7420666f756e642e70426c75657072696e744372656174696f6e496e74657272757074656400010488426c75657072696e74206372656174696f6e20697320696e7465727275707465642e44416c726561647952656769737465726564000204bc5468652063616c6c657220697320616c726561647920726567697374657265642061732061206f70657261746f722e60496e76616c6964526567697374726174696f6e496e707574000304ec5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2062652061206f70657261746f722e584e6f74416c6c6f776564546f556e7265676973746572000404a8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f20756e72656769737465722e784e6f74416c6c6f776564546f557064617465507269636554617267657473000504e8546865204f70657261746f72206973206e6f7420616c6c6f77656420746f2075706461746520746865697220707269636520746172676574732e4c496e76616c696452657175657374496e707574000604fc5468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2072657175657374206120736572766963652e4c496e76616c69644a6f6243616c6c496e707574000704e05468652063616c6c657220646f6573206e6f7420686176652074686520726571756972656d656e747320746f2063616c6c2061206a6f622e40496e76616c69644a6f62526573756c74000804a85468652063616c6c65722070726f766964656420616e20696e76616c6964206a6f6220726573756c742e344e6f7452656769737465726564000904ac5468652063616c6c6572206973206e6f7420726567697374657265642061732061206f70657261746f722e4c417070726f76616c496e746572727570746564000a0480417070726f76616c2050726f6365737320697320696e7465727275707465642e5052656a656374696f6e496e746572727570746564000b048452656a656374696f6e2050726f6365737320697320696e7465727275707465642e5853657276696365526571756573744e6f74466f756e64000c04885468652073657276696365207265717565737420776173206e6f7420666f756e642e8053657276696365496e697469616c697a6174696f6e496e746572727570746564000d048c5365727669636520496e697469616c697a6174696f6e20696e7465727275707465642e3c536572766963654e6f74466f756e64000e0468546865207365727669636520776173206e6f7420666f756e642e585465726d696e6174696f6e496e746572727570746564000f04bc546865207465726d696e6174696f6e206f662074686520736572766963652077617320696e7465727275707465642e2454797065436865636b0400910b013854797065436865636b4572726f72001004fc416e206572726f72206f63637572726564207768696c65207479706520636865636b696e67207468652070726f766964656420696e70757420696e7075742e6c4d61785065726d697474656443616c6c65727345786365656465640011041901546865206d6178696d756d206e756d626572206f66207065726d69747465642063616c6c65727320706572207365727669636520686173206265656e2065786365656465642e6c4d61785365727669636550726f7669646572734578636565646564001204f8546865206d6178696d756d206e756d626572206f66206f70657261746f727320706572207365727669636520686173206265656e2065786365656465642e684d61785365727669636573506572557365724578636565646564001304e8546865206d6178696d756d206e756d626572206f6620736572766963657320706572207573657220686173206265656e2065786365656465642e444d61784669656c64734578636565646564001404ec546865206d6178696d756d206e756d626572206f66206669656c647320706572207265717565737420686173206265656e2065786365656465642e50417070726f76616c4e6f74526571756573746564001504f054686520617070726f76616c206973206e6f742072657175657374656420666f7220746865206f70657261746f7220287468652063616c6c6572292e544a6f62446566696e6974696f6e4e6f74466f756e6400160cb054686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f742065786973742e590154686973206572726f722069732072657475726e6564207768656e2074686520726571756573746564206a6f6220646566696e6974696f6e20646f6573206e6f7420657869737420696e20746865207365727669636528626c75657072696e742e60536572766963654f724a6f6243616c6c4e6f74466f756e64001704c4456974686572207468652073657276696365206f7220746865206a6f622063616c6c20776173206e6f7420666f756e642e544a6f6243616c6c526573756c744e6f74466f756e64001804a454686520726573756c74206f6620746865206a6f622063616c6c20776173206e6f7420666f756e642e3045564d416269456e636f6465001904b4416e206572726f72206f63637572726564207768696c6520656e636f64696e67207468652045564d204142492e3045564d4162694465636f6465001a04b4416e206572726f72206f63637572726564207768696c65206465636f64696e67207468652045564d204142492e5c4f70657261746f7250726f66696c654e6f74466f756e64001b046c4f70657261746f722070726f66696c65206e6f7420666f756e642e784d6178536572766963657350657250726f76696465724578636565646564001c04c04d6178696d756d206e756d626572206f66207365727669636573207065722050726f766964657220726561636865642e444f70657261746f724e6f74416374697665001d045901546865206f70657261746f72206973206e6f74206163746976652c20656e73757265206f70657261746f72207374617475732069732041435449564520696e206d756c74692d61737365742d64656c65676174696f6e404e6f41737365747350726f7669646564001e040d014e6f206173736574732070726f766964656420666f722074686520736572766963652c206174206c65617374206f6e652061737365742069732072657175697265642e6c4d6178417373657473506572536572766963654578636565646564001f04ec546865206d6178696d756d206e756d626572206f662061737365747320706572207365727669636520686173206265656e2065786365656465642e4c4f6666656e6465724e6f744f70657261746f72002004984f6666656e646572206973206e6f7420612072656769737465726564206f70657261746f722e644f6666656e6465724e6f744163746976654f70657261746f720021048c4f6666656e646572206973206e6f7420616e20616374697665206f70657261746f722e404e6f536c617368696e674f726967696e0022042101546865205365727669636520426c75657072696e7420646964206e6f742072657475726e206120736c617368696e67206f726967696e20666f72207468697320736572766963652e3c4e6f446973707574654f726967696e0023041d01546865205365727669636520426c75657072696e7420646964206e6f742072657475726e20612064697370757465206f726967696e20666f72207468697320736572766963652e58556e6170706c696564536c6173684e6f74466f756e640024048854686520556e6170706c69656420536c61736820617265206e6f7420666f756e642eb44d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e4e6f74466f756e64002504110154686520537570706c696564204d617374657220426c75657072696e742053657276696365204d616e61676572205265766973696f6e206973206e6f7420666f756e642ec04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e73457863656564656400260415014d6178696d756d206e756d626572206f66204d617374657220426c75657072696e742053657276696365204d616e61676572207265766973696f6e7320726561636865642e4c45524332305472616e736665724661696c656400270468546865204552433230207472616e73666572206661696c65642e404d697373696e6745564d4f726967696e002804a44d697373696e672045564d204f726967696e20666f72207468652045564d20657865637574696f6e2e48457870656374656445564d41646472657373002904a8457870656374656420746865206163636f756e7420746f20626520616e2045564d20616464726573732e4445787065637465644163636f756e744964002a04a4457870656374656420746865206163636f756e7420746f20626520616e206163636f756e742049442e048054686520604572726f726020656e756d206f6620746869732070616c6c65742e910b0c4474616e676c655f7072696d6974697665732073657276696365733854797065436865636b4572726f7200010c50417267756d656e74547970654d69736d617463680c0114696e646578080108753800012065787065637465644d0601244669656c645479706500011861637475616c4d0601244669656c6454797065000000484e6f74456e6f756768417267756d656e74730801206578706563746564080108753800011861637475616c080108753800010048526573756c74547970654d69736d617463680c0114696e646578080108753800012065787065637465644d0601244669656c645479706500011861637475616c4d0601244669656c645479706500020000950b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c3c426f6e646564506f6f6c496e6e65720404540000100128636f6d6d697373696f6e990b0134436f6d6d697373696f6e3c543e000114726f6c6573a10b015c506f6f6c526f6c65733c543a3a4163636f756e7449643e000114737461746541020124506f6f6c53746174650001206d65746164617461a50b013c506f6f6c4d657461646174613c543e0000990b104470616c6c65745f74616e676c655f6c737414747970657328636f6d6d697373696f6e28436f6d6d697373696f6e040454000014011c63757272656e742101017c4f7074696f6e3c2850657262696c6c2c20543a3a4163636f756e744964293e00010c6d61785d09013c4f7074696f6e3c50657262696c6c3e00012c6368616e67655f726174659d0b01bc4f7074696f6e3c436f6d6d697373696f6e4368616e6765526174653c426c6f636b4e756d626572466f723c543e3e3e0001347468726f74746c655f66726f6d810401644f7074696f6e3c426c6f636b4e756d626572466f723c543e3e000140636c61696d5f7065726d697373696f6e490201bc4f7074696f6e3c436f6d6d697373696f6e436c61696d5065726d697373696f6e3c543a3a4163636f756e7449643e3e00009d0b04184f7074696f6e0404540145020108104e6f6e6500000010536f6d65040045020000010000a10b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7324506f6f6c526f6c657304244163636f756e7449640100001001246465706f7369746f720001244163636f756e744964000110726f6f748801444f7074696f6e3c4163636f756e7449643e0001246e6f6d696e61746f728801444f7074696f6e3c4163636f756e7449643e00011c626f756e6365728801444f7074696f6e3c4163636f756e7449643e0000a50b104470616c6c65745f74616e676c655f6c73741474797065732c626f6e6465645f706f6f6c30506f6f6c4d6574616461746104045400000801106e616d65fd0601a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d61784e616d654c656e6774683e3e00011069636f6e050701a04f7074696f6e3c426f756e6465645665633c75382c20543a3a4d617849636f6e4c656e6774683e3e0000a90b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328526577617264506f6f6c04045400001401706c6173745f7265636f726465645f7265776172645f636f756e746572a5070140543a3a526577617264436f756e74657200016c6c6173745f7265636f726465645f746f74616c5f7061796f75747318013042616c616e63654f663c543e000154746f74616c5f726577617264735f636c61696d656418013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f70656e64696e6718013042616c616e63654f663c543e000160746f74616c5f636f6d6d697373696f6e5f636c61696d656418013042616c616e63654f663c543e0000ad0b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7320537562506f6f6c7304045400000801186e6f5f657261b10b0134556e626f6e64506f6f6c3c543e000120776974685f657261b50b010101426f756e64656442547265654d61703c457261496e6465782c20556e626f6e64506f6f6c3c543e2c20546f74616c556e626f6e64696e67506f6f6c733c543e3e0000b10b104470616c6c65745f74616e676c655f6c7374147479706573247375625f706f6f6c7328556e626f6e64506f6f6c0404540000080118706f696e747318013042616c616e63654f663c543e00011c62616c616e636518013042616c616e63654f663c543e0000b50b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b0110045601b10b045300000400b90b013842547265654d61703c4b2c20563e0000b90b042042547265654d617008044b0110045601b10b000400bd0b000000bd0b000002c10b00c10b0000040810b10b00c50b0c4c626f756e6465645f636f6c6c656374696f6e732c626f756e6465645f76656328426f756e64656456656308045401080453000004003801185665633c543e0000c90b104470616c6c65745f74616e676c655f6c737414747970657314706f6f6c7328506f6f6c4d656d6265720404540000040138756e626f6e64696e675f65726173cd0b010901426f756e64656442547265654d61703c457261496e6465782c2028506f6f6c49642c2042616c616e63654f663c543e292c20543a3a4d6178556e626f6e64696e673e0000cd0b0c4c626f756e6465645f636f6c6c656374696f6e7344626f756e6465645f62747265655f6d61703c426f756e64656442547265654d61700c044b01100456015109045300000400d10b013842547265654d61703c4b2c20563e0000d10b042042547265654d617008044b01100456015109000400d50b000000d50b000002d90b00d90b0000040810510900dd0b0c4470616c6c65745f74616e676c655f6c73741474797065733c436c61696d5065726d697373696f6e000110305065726d697373696f6e6564000000585065726d697373696f6e6c657373436f6d706f756e64000100585065726d697373696f6e6c6573735769746864726177000200445065726d697373696f6e6c657373416c6c00030000e10b0c4470616c6c65745f74616e676c655f6c73741870616c6c6574144572726f7204045400018430506f6f6c4e6f74466f756e6400000488412028626f6e6465642920706f6f6c20696420646f6573206e6f742065786973742e48506f6f6c4d656d6265724e6f74466f756e640001046c416e206163636f756e74206973206e6f742061206d656d6265722e48526577617264506f6f6c4e6f74466f756e640002042101412072657761726420706f6f6c20646f6573206e6f742065786973742e20496e20616c6c206361736573207468697320697320612073797374656d206c6f676963206572726f722e40537562506f6f6c734e6f74466f756e6400030468412073756220706f6f6c20646f6573206e6f742065786973742e3846756c6c79556e626f6e64696e670004083d01546865206d656d6265722069732066756c6c7920756e626f6e6465642028616e6420746875732063616e6e6f74206163636573732074686520626f6e64656420616e642072657761726420706f6f6ca8616e796d6f726520746f2c20666f72206578616d706c652c20636f6c6c6563742072657761726473292e444d6178556e626f6e64696e674c696d69740005040901546865206d656d6265722063616e6e6f7420756e626f6e642066757274686572206368756e6b732064756520746f207265616368696e6720746865206c696d69742e4443616e6e6f745769746864726177416e790006044d014e6f6e65206f66207468652066756e64732063616e2062652077697468647261776e2079657420626563617573652074686520626f6e64696e67206475726174696f6e20686173206e6f74207061737365642e444d696e696d756d426f6e644e6f744d6574000714290154686520616d6f756e7420646f6573206e6f74206d65657420746865206d696e696d756d20626f6e6420746f20656974686572206a6f696e206f7220637265617465206120706f6f6c2e005501546865206465706f7369746f722063616e206e6576657220756e626f6e6420746f20612076616c7565206c657373207468616e206050616c6c65743a3a6465706f7369746f725f6d696e5f626f6e64602e205468655d0163616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e204d656d626572732063616e206e6576657220756e626f6e6420746f20616876616c75652062656c6f7720604d696e4a6f696e426f6e64602e304f766572666c6f775269736b0008042101546865207472616e73616374696f6e20636f756c64206e6f742062652065786563757465642064756520746f206f766572666c6f77207269736b20666f722074686520706f6f6c2e344e6f7444657374726f79696e670009085d014120706f6f6c206d75737420626520696e205b60506f6f6c53746174653a3a44657374726f79696e67605d20696e206f7264657220666f7220746865206465706f7369746f7220746f20756e626f6e64206f7220666f72b86f74686572206d656d6265727320746f206265207065726d697373696f6e6c6573736c7920756e626f6e6465642e304e6f744e6f6d696e61746f72000a04f45468652063616c6c657220646f6573206e6f742068617665206e6f6d696e6174696e67207065726d697373696f6e7320666f722074686520706f6f6c2e544e6f744b69636b65724f7244657374726f79696e67000b043d01456974686572206129207468652063616c6c65722063616e6e6f74206d616b6520612076616c6964206b69636b206f722062292074686520706f6f6c206973206e6f742064657374726f79696e672e1c4e6f744f70656e000c047054686520706f6f6c206973206e6f74206f70656e20746f206a6f696e204d6178506f6f6c73000d04845468652073797374656d206973206d61786564206f7574206f6e20706f6f6c732e384d6178506f6f6c4d656d62657273000e049c546f6f206d616e79206d656d6265727320696e2074686520706f6f6c206f722073797374656d2e4443616e4e6f744368616e67655374617465000f048854686520706f6f6c732073746174652063616e6e6f74206265206368616e6765642e54446f65734e6f74486176655065726d697373696f6e001004b85468652063616c6c657220646f6573206e6f742068617665206164657175617465207065726d697373696f6e732e544d65746164617461457863656564734d61784c656e001104ac4d657461646174612065786365656473205b60436f6e6669673a3a4d61784d657461646174614c656e605d24446566656e736976650400e50b0138446566656e736976654572726f720012083101536f6d65206572726f72206f6363757272656420746861742073686f756c64206e657665722068617070656e2e20546869732073686f756c64206265207265706f7274656420746f20746865306d61696e7461696e6572732e9c5061727469616c556e626f6e644e6f74416c6c6f7765645065726d697373696f6e6c6573736c79001304bc5061727469616c20756e626f6e64696e67206e6f7720616c6c6f776564207065726d697373696f6e6c6573736c792e5c4d6178436f6d6d697373696f6e526573747269637465640014041d0154686520706f6f6c2773206d617820636f6d6d697373696f6e2063616e6e6f742062652073657420686967686572207468616e20746865206578697374696e672076616c75652e60436f6d6d697373696f6e457863656564734d6178696d756d001504ec54686520737570706c69656420636f6d6d697373696f6e206578636565647320746865206d617820616c6c6f77656420636f6d6d697373696f6e2e78436f6d6d697373696f6e45786365656473476c6f62616c4d6178696d756d001604e854686520737570706c69656420636f6d6d697373696f6e206578636565647320676c6f62616c206d6178696d756d20636f6d6d697373696f6e2e64436f6d6d697373696f6e4368616e67655468726f74746c656400170409014e6f7420656e6f75676820626c6f636b732068617665207375727061737365642073696e636520746865206c61737420636f6d6d697373696f6e207570646174652e78436f6d6d697373696f6e4368616e6765526174654e6f74416c6c6f7765640018040101546865207375626d6974746564206368616e67657320746f20636f6d6d697373696f6e206368616e6765207261746520617265206e6f7420616c6c6f7765642e4c4e6f50656e64696e67436f6d6d697373696f6e001904a05468657265206973206e6f2070656e64696e6720636f6d6d697373696f6e20746f20636c61696d2e584e6f436f6d6d697373696f6e43757272656e74536574001a048c4e6f20636f6d6d697373696f6e2063757272656e7420686173206265656e207365742e2c506f6f6c4964496e557365001b0464506f6f6c2069642063757272656e746c7920696e207573652e34496e76616c6964506f6f6c4964001c049c506f6f6c2069642070726f7669646564206973206e6f7420636f72726563742f757361626c652e4c426f6e64457874726152657374726963746564001d04fc426f6e64696e67206578747261206973207265737472696374656420746f207468652065786163742070656e64696e672072657761726420616d6f756e742e3c4e6f7468696e67546f41646a757374001e04b04e6f20696d62616c616e636520696e20746865204544206465706f73697420666f722074686520706f6f6c2e5c506f6f6c546f6b656e4372656174696f6e4661696c6564001f046c506f6f6c20746f6b656e206372656174696f6e206661696c65642e444e6f42616c616e6365546f556e626f6e64002004544e6f2062616c616e636520746f20756e626f6e642e048054686520604572726f726020656e756d206f6620746869732070616c6c65742ee50b0c4470616c6c65745f74616e676c655f6c73741870616c6c657438446566656e736976654572726f72000114684e6f74456e6f7567685370616365496e556e626f6e64506f6f6c00000030506f6f6c4e6f74466f756e6400010048526577617264506f6f6c4e6f74466f756e6400020040537562506f6f6c734e6f74466f756e6400030070426f6e64656453746173684b696c6c65645072656d61747572656c7900040000e90b0000040800f10100ed0b00000408301800f10b000002f10100f50b0c3870616c6c65745f726577617264731870616c6c6574144572726f72040454000130484e6f52657761726473417661696c61626c65000004744e6f207265776172647320617661696c61626c6520746f20636c61696d68496e73756666696369656e745265776172647342616c616e6365000104b8496e73756666696369656e7420726577617264732062616c616e636520696e2070616c6c6574206163636f756e744c41737365744e6f7457686974656c6973746564000204904173736574206973206e6f742077686974656c697374656420666f7220726577617264735c4173736574416c726561647957686974656c697374656400030470417373657420697320616c72656164792077686974656c697374656428496e76616c696441505900040444496e76616c6964204150592076616c75654c4173736574416c7265616479496e5661756c7400050498417373657420616c72656164792065786973747320696e206120726577617264207661756c743c41737365744e6f74496e5661756c740006047c4173736574206e6f7420666f756e6420696e20726577617264207661756c74345661756c744e6f74466f756e640007047c54686520726577617264207661756c7420646f6573206e6f74206578697374504475706c6963617465426c75657072696e74496400080415014572726f722072657475726e6564207768656e20747279696e6720746f20616464206120626c75657072696e74204944207468617420616c7265616479206578697374732e4c426c75657072696e7449644e6f74466f756e640009041d014572726f722072657475726e6564207768656e20747279696e6720746f2072656d6f7665206120626c75657072696e74204944207468617420646f65736e27742065786973742e50526577617264436f6e6669674e6f74466f756e64000a0421014572726f722072657475726e6564207768656e207468652072657761726420636f6e66696775726174696f6e20666f7220746865207661756c74206973206e6f7420666f756e642e3c41726974686d657469634572726f72000b049c41726974686d65746963206f7065726174696f6e2063617573656420616e206f766572666c6f77048054686520604572726f726020656e756d206f6620746869732070616c6c65742ef90b0c4466705f73656c665f636f6e7461696e65644c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c5021043616c6c01bd02245369676e617475726501650514457874726101fd0b0004002d0c01250173705f72756e74696d653a3a67656e657269633a3a556e636865636b656445787472696e7369633c416464726573732c2043616c6c2c205369676e61747572652c2045787472610a3e0000fd0b00000424010c050c090c0d0c110c190c1d0c210c250c00010c10306672616d655f73797374656d28657874656e73696f6e7354636865636b5f6e6f6e5f7a65726f5f73656e64657248436865636b4e6f6e5a65726f53656e64657204045400000000050c10306672616d655f73797374656d28657874656e73696f6e7348636865636b5f737065635f76657273696f6e40436865636b5370656356657273696f6e04045400000000090c10306672616d655f73797374656d28657874656e73696f6e7340636865636b5f74785f76657273696f6e38436865636b547856657273696f6e040454000000000d0c10306672616d655f73797374656d28657874656e73696f6e7334636865636b5f67656e6573697330436865636b47656e6573697304045400000000110c10306672616d655f73797374656d28657874656e73696f6e733c636865636b5f6d6f7274616c69747938436865636b4d6f7274616c69747904045400000400150c010c4572610000150c102873705f72756e74696d651c67656e657269630c6572610c4572610001010420496d6d6f7274616c0000001c4d6f7274616c31040008000001001c4d6f7274616c32040008000002001c4d6f7274616c33040008000003001c4d6f7274616c34040008000004001c4d6f7274616c35040008000005001c4d6f7274616c36040008000006001c4d6f7274616c37040008000007001c4d6f7274616c38040008000008001c4d6f7274616c3904000800000900204d6f7274616c313004000800000a00204d6f7274616c313104000800000b00204d6f7274616c313204000800000c00204d6f7274616c313304000800000d00204d6f7274616c313404000800000e00204d6f7274616c313504000800000f00204d6f7274616c313604000800001000204d6f7274616c313704000800001100204d6f7274616c313804000800001200204d6f7274616c313904000800001300204d6f7274616c323004000800001400204d6f7274616c323104000800001500204d6f7274616c323204000800001600204d6f7274616c323304000800001700204d6f7274616c323404000800001800204d6f7274616c323504000800001900204d6f7274616c323604000800001a00204d6f7274616c323704000800001b00204d6f7274616c323804000800001c00204d6f7274616c323904000800001d00204d6f7274616c333004000800001e00204d6f7274616c333104000800001f00204d6f7274616c333204000800002000204d6f7274616c333304000800002100204d6f7274616c333404000800002200204d6f7274616c333504000800002300204d6f7274616c333604000800002400204d6f7274616c333704000800002500204d6f7274616c333804000800002600204d6f7274616c333904000800002700204d6f7274616c343004000800002800204d6f7274616c343104000800002900204d6f7274616c343204000800002a00204d6f7274616c343304000800002b00204d6f7274616c343404000800002c00204d6f7274616c343504000800002d00204d6f7274616c343604000800002e00204d6f7274616c343704000800002f00204d6f7274616c343804000800003000204d6f7274616c343904000800003100204d6f7274616c353004000800003200204d6f7274616c353104000800003300204d6f7274616c353204000800003400204d6f7274616c353304000800003500204d6f7274616c353404000800003600204d6f7274616c353504000800003700204d6f7274616c353604000800003800204d6f7274616c353704000800003900204d6f7274616c353804000800003a00204d6f7274616c353904000800003b00204d6f7274616c363004000800003c00204d6f7274616c363104000800003d00204d6f7274616c363204000800003e00204d6f7274616c363304000800003f00204d6f7274616c363404000800004000204d6f7274616c363504000800004100204d6f7274616c363604000800004200204d6f7274616c363704000800004300204d6f7274616c363804000800004400204d6f7274616c363904000800004500204d6f7274616c373004000800004600204d6f7274616c373104000800004700204d6f7274616c373204000800004800204d6f7274616c373304000800004900204d6f7274616c373404000800004a00204d6f7274616c373504000800004b00204d6f7274616c373604000800004c00204d6f7274616c373704000800004d00204d6f7274616c373804000800004e00204d6f7274616c373904000800004f00204d6f7274616c383004000800005000204d6f7274616c383104000800005100204d6f7274616c383204000800005200204d6f7274616c383304000800005300204d6f7274616c383404000800005400204d6f7274616c383504000800005500204d6f7274616c383604000800005600204d6f7274616c383704000800005700204d6f7274616c383804000800005800204d6f7274616c383904000800005900204d6f7274616c393004000800005a00204d6f7274616c393104000800005b00204d6f7274616c393204000800005c00204d6f7274616c393304000800005d00204d6f7274616c393404000800005e00204d6f7274616c393504000800005f00204d6f7274616c393604000800006000204d6f7274616c393704000800006100204d6f7274616c393804000800006200204d6f7274616c393904000800006300244d6f7274616c31303004000800006400244d6f7274616c31303104000800006500244d6f7274616c31303204000800006600244d6f7274616c31303304000800006700244d6f7274616c31303404000800006800244d6f7274616c31303504000800006900244d6f7274616c31303604000800006a00244d6f7274616c31303704000800006b00244d6f7274616c31303804000800006c00244d6f7274616c31303904000800006d00244d6f7274616c31313004000800006e00244d6f7274616c31313104000800006f00244d6f7274616c31313204000800007000244d6f7274616c31313304000800007100244d6f7274616c31313404000800007200244d6f7274616c31313504000800007300244d6f7274616c31313604000800007400244d6f7274616c31313704000800007500244d6f7274616c31313804000800007600244d6f7274616c31313904000800007700244d6f7274616c31323004000800007800244d6f7274616c31323104000800007900244d6f7274616c31323204000800007a00244d6f7274616c31323304000800007b00244d6f7274616c31323404000800007c00244d6f7274616c31323504000800007d00244d6f7274616c31323604000800007e00244d6f7274616c31323704000800007f00244d6f7274616c31323804000800008000244d6f7274616c31323904000800008100244d6f7274616c31333004000800008200244d6f7274616c31333104000800008300244d6f7274616c31333204000800008400244d6f7274616c31333304000800008500244d6f7274616c31333404000800008600244d6f7274616c31333504000800008700244d6f7274616c31333604000800008800244d6f7274616c31333704000800008900244d6f7274616c31333804000800008a00244d6f7274616c31333904000800008b00244d6f7274616c31343004000800008c00244d6f7274616c31343104000800008d00244d6f7274616c31343204000800008e00244d6f7274616c31343304000800008f00244d6f7274616c31343404000800009000244d6f7274616c31343504000800009100244d6f7274616c31343604000800009200244d6f7274616c31343704000800009300244d6f7274616c31343804000800009400244d6f7274616c31343904000800009500244d6f7274616c31353004000800009600244d6f7274616c31353104000800009700244d6f7274616c31353204000800009800244d6f7274616c31353304000800009900244d6f7274616c31353404000800009a00244d6f7274616c31353504000800009b00244d6f7274616c31353604000800009c00244d6f7274616c31353704000800009d00244d6f7274616c31353804000800009e00244d6f7274616c31353904000800009f00244d6f7274616c3136300400080000a000244d6f7274616c3136310400080000a100244d6f7274616c3136320400080000a200244d6f7274616c3136330400080000a300244d6f7274616c3136340400080000a400244d6f7274616c3136350400080000a500244d6f7274616c3136360400080000a600244d6f7274616c3136370400080000a700244d6f7274616c3136380400080000a800244d6f7274616c3136390400080000a900244d6f7274616c3137300400080000aa00244d6f7274616c3137310400080000ab00244d6f7274616c3137320400080000ac00244d6f7274616c3137330400080000ad00244d6f7274616c3137340400080000ae00244d6f7274616c3137350400080000af00244d6f7274616c3137360400080000b000244d6f7274616c3137370400080000b100244d6f7274616c3137380400080000b200244d6f7274616c3137390400080000b300244d6f7274616c3138300400080000b400244d6f7274616c3138310400080000b500244d6f7274616c3138320400080000b600244d6f7274616c3138330400080000b700244d6f7274616c3138340400080000b800244d6f7274616c3138350400080000b900244d6f7274616c3138360400080000ba00244d6f7274616c3138370400080000bb00244d6f7274616c3138380400080000bc00244d6f7274616c3138390400080000bd00244d6f7274616c3139300400080000be00244d6f7274616c3139310400080000bf00244d6f7274616c3139320400080000c000244d6f7274616c3139330400080000c100244d6f7274616c3139340400080000c200244d6f7274616c3139350400080000c300244d6f7274616c3139360400080000c400244d6f7274616c3139370400080000c500244d6f7274616c3139380400080000c600244d6f7274616c3139390400080000c700244d6f7274616c3230300400080000c800244d6f7274616c3230310400080000c900244d6f7274616c3230320400080000ca00244d6f7274616c3230330400080000cb00244d6f7274616c3230340400080000cc00244d6f7274616c3230350400080000cd00244d6f7274616c3230360400080000ce00244d6f7274616c3230370400080000cf00244d6f7274616c3230380400080000d000244d6f7274616c3230390400080000d100244d6f7274616c3231300400080000d200244d6f7274616c3231310400080000d300244d6f7274616c3231320400080000d400244d6f7274616c3231330400080000d500244d6f7274616c3231340400080000d600244d6f7274616c3231350400080000d700244d6f7274616c3231360400080000d800244d6f7274616c3231370400080000d900244d6f7274616c3231380400080000da00244d6f7274616c3231390400080000db00244d6f7274616c3232300400080000dc00244d6f7274616c3232310400080000dd00244d6f7274616c3232320400080000de00244d6f7274616c3232330400080000df00244d6f7274616c3232340400080000e000244d6f7274616c3232350400080000e100244d6f7274616c3232360400080000e200244d6f7274616c3232370400080000e300244d6f7274616c3232380400080000e400244d6f7274616c3232390400080000e500244d6f7274616c3233300400080000e600244d6f7274616c3233310400080000e700244d6f7274616c3233320400080000e800244d6f7274616c3233330400080000e900244d6f7274616c3233340400080000ea00244d6f7274616c3233350400080000eb00244d6f7274616c3233360400080000ec00244d6f7274616c3233370400080000ed00244d6f7274616c3233380400080000ee00244d6f7274616c3233390400080000ef00244d6f7274616c3234300400080000f000244d6f7274616c3234310400080000f100244d6f7274616c3234320400080000f200244d6f7274616c3234330400080000f300244d6f7274616c3234340400080000f400244d6f7274616c3234350400080000f500244d6f7274616c3234360400080000f600244d6f7274616c3234370400080000f700244d6f7274616c3234380400080000f800244d6f7274616c3234390400080000f900244d6f7274616c3235300400080000fa00244d6f7274616c3235310400080000fb00244d6f7274616c3235320400080000fc00244d6f7274616c3235330400080000fd00244d6f7274616c3235340400080000fe00244d6f7274616c3235350400080000ff0000190c10306672616d655f73797374656d28657874656e73696f6e732c636865636b5f6e6f6e636528436865636b4e6f6e63650404540000040069020120543a3a4e6f6e636500001d0c10306672616d655f73797374656d28657874656e73696f6e7330636865636b5f7765696768742c436865636b57656967687404045400000000210c086870616c6c65745f7472616e73616374696f6e5f7061796d656e74604368617267655472616e73616374696f6e5061796d656e74040454000004006d01013042616c616e63654f663c543e0000250c08746672616d655f6d657461646174615f686173685f657874656e73696f6e44436865636b4d657461646174614861736804045400000401106d6f6465290c01104d6f64650000290c08746672616d655f6d657461646174615f686173685f657874656e73696f6e104d6f64650001082044697361626c65640000001c456e61626c6564000100002d0c102873705f72756e74696d651c67656e657269634c756e636865636b65645f65787472696e73696348556e636865636b656445787472696e736963101c4164647265737301c5021043616c6c01bd02245369676e617475726501650514457874726101fd0b00040038000000310c085874616e676c655f746573746e65745f72756e74696d651c52756e74696d6500000000b01853797374656d011853797374656d481c4163636f756e7401010402000c4101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008004e8205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e3845787472696e736963436f756e74000010040004b820546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e40496e686572656e74734170706c696564010020040004a4205768657468657220616c6c20696e686572656e74732068617665206265656e206170706c6965642e2c426c6f636b576569676874010024180000000000000488205468652063757272656e742077656967687420666f722074686520626c6f636b2e40416c6c45787472696e736963734c656e000010040004410120546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e24426c6f636b486173680101040530348000000000000000000000000000000000000000000000000000000000000000000498204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e3445787472696e736963446174610101040510380400043d012045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e184e756d626572010030200000000000000000040901205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e28506172656e744861736801003480000000000000000000000000000000000000000000000000000000000000000004702048617368206f66207468652070726576696f757320626c6f636b2e1844696765737401003c040004f020446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e184576656e747301004c04001ca0204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e001d01204e4f54453a20546865206974656d20697320756e626f756e6420616e642073686f756c64207468657265666f7265206e657665722062652072656164206f6e20636861696e2ed020497420636f756c64206f746865727769736520696e666c6174652074686520506f562073697a65206f66206120626c6f636b2e002d01204576656e747320686176652061206c6172676520696e2d6d656d6f72792073697a652e20426f7820746865206576656e747320746f206e6f7420676f206f75742d6f662d6d656d6f7279fc206a75737420696e206361736520736f6d656f6e65207374696c6c207265616473207468656d2066726f6d2077697468696e207468652072756e74696d652e284576656e74436f756e74010010100000000004b820546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e2c4576656e74546f70696373010104023461020400282501204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e646578657394206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e00510120416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e2054686973450120616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e64e420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e005901205468652076616c756520686173207468652074797065206028426c6f636b4e756d626572466f723c543e2c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573744d012074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b0101206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e484c61737452756e74696d65557067726164650000650204000455012053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e545570677261646564546f553332526566436f756e740100200400044d012054727565206966207765206861766520757067726164656420736f207468617420607479706520526566436f756e74602069732060753332602e2046616c7365202864656661756c7429206966206e6f742e605570677261646564546f547269706c65526566436f756e740100200400085d012054727565206966207765206861766520757067726164656420736f2074686174204163636f756e74496e666f20636f6e7461696e73207468726565207479706573206f662060526566436f756e74602e2046616c736548202864656661756c7429206966206e6f742e38457865637574696f6e506861736500005d02040004882054686520657865637574696f6e207068617365206f662074686520626c6f636b2e44417574686f72697a65645570677261646500006d02040004b82060536f6d6560206966206120636f6465207570677261646520686173206265656e20617574686f72697a65642e01710201581830426c6f636b576569676874738102f901624d186c000b00204aa9d10113ffffffffffffffff4247871900010b30f6a7a72e011366666666666666a6010b0098f73e5d0113ffffffffffffffbf0100004247871900010b307efa11a3011366666666666666e6010b00204aa9d10113ffffffffffffffff01070088526a74130000000000000040424787190000000004d020426c6f636b20262065787472696e7369637320776569676874733a20626173652076616c75657320616e64206c696d6974732e2c426c6f636b4c656e67746891023000003c00000050000000500004a820546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e38426c6f636b48617368436f756e7430200001000000000000045501204d6178696d756d206e756d626572206f6620626c6f636b206e756d62657220746f20626c6f636b2068617368206d617070696e677320746f206b65657020286f6c64657374207072756e6564206669727374292e20446257656967687499024040787d010000000000e1f505000000000409012054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e1c56657273696f6e9d02c1033874616e676c652d746573746e65743874616e676c652d746573746e657401000000b40400000100000040df6acb689907609b0500000037e397fc7c91f5e40200000040fe3ad401f8959a060000009bbaa777b4c15fc401000000582211f65bb14b8905000000e65b00e46cedd0aa02000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000cbca25e39f14238702000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000ed99c5acb25eedf503000000bd78255d4feeea1f06000000a33d43f58731ad8402000000fbc577b9d747efd60100000001000000000484204765742074686520636861696e277320696e2d636f64652076657273696f6e2e2853533538507265666978e901082a0014a8205468652064657369676e61746564205353353820707265666978206f66207468697320636861696e2e0039012054686973207265706c6163657320746865202273733538466f726d6174222070726f7065727479206465636c6172656420696e2074686520636861696e20737065632e20526561736f6e20697331012074686174207468652072756e74696d652073686f756c64206b6e6f772061626f7574207468652070726566697820696e206f7264657220746f206d616b6520757365206f662069742061737020616e206964656e746966696572206f662074686520636861696e2e01b102012454696d657374616d70012454696d657374616d70080c4e6f7701003020000000000000000004a0205468652063757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e24446964557064617465010020040010d82057686574686572207468652074696d657374616d7020686173206265656e207570646174656420696e207468697320626c6f636b2e00550120546869732076616c7565206973207570646174656420746f206074727565602075706f6e207375636365737366756c207375626d697373696f6e206f6620612074696d657374616d702062792061206e6f64652e4501204974206973207468656e20636865636b65642061742074686520656e64206f66206561636820626c6f636b20657865637574696f6e20696e2074686520606f6e5f66696e616c697a656020686f6f6b2e01b5020004344d696e696d756d506572696f643020b80b000000000000188c20546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e004d012042652061776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e4901206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f61012064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20466f72206578616d706c652c20696e2074686520417572612070616c6c65742069742077696c6c20626520646f75626c6520746869737020706572696f64206f6e2064656661756c742073657474696e67732e0002105375646f01105375646f040c4b6579000000040004842054686520604163636f756e74496460206f6620746865207375646f206b65792e01b902017c00012507036052616e646f6d6e657373436f6c6c656374697665466c6970016052616e646f6d6e657373436f6c6c656374697665466c6970043852616e646f6d4d6174657269616c0100290704000c610120536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e2054686973610120697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f664420746865206f6c6465737420686173682e00000000041841737365747301184173736574731414417373657400010402182d07040004542044657461696c73206f6620616e2061737365742e1c4163636f756e74000108020235073907040004e42054686520686f6c64696e6773206f662061207370656369666963206163636f756e7420666f7220612073706563696669632061737365742e24417070726f76616c7300010c0202024507490704000c590120417070726f7665642062616c616e6365207472616e73666572732e2046697273742062616c616e63652069732074686520616d6f756e7420617070726f76656420666f72207472616e736665722e205365636f6e64e82069732074686520616d6f756e74206f662060543a3a43757272656e63796020726573657276656420666f722073746f72696e6720746869732e4901204669727374206b6579206973207468652061737365742049442c207365636f6e64206b657920697320746865206f776e657220616e64207468697264206b6579206973207468652064656c65676174652e204d6574616461746101010402184d075000000000000000000000000000000000000000000458204d65746164617461206f6620616e2061737365742e2c4e657874417373657449640000180400246d012054686520617373657420494420656e666f7263656420666f7220746865206e657874206173736574206372656174696f6e2c20696620616e792070726573656e742e204f74686572776973652c20746869732073746f7261676550206974656d20686173206e6f206566666563742e00650120546869732063616e2062652075736566756c20666f722073657474696e6720757020636f6e73747261696e747320666f7220494473206f6620746865206e6577206173736574732e20466f72206578616d706c652c20627969012070726f766964696e6720616e20696e697469616c205b604e65787441737365744964605d20616e64207573696e6720746865205b6063726174653a3a4175746f496e6341737365744964605d2063616c6c6261636b2c20616ee8206175746f2d696e6372656d656e74206d6f64656c2063616e206265206170706c69656420746f20616c6c206e6577206173736574204944732e0021012054686520696e697469616c206e6578742061737365742049442063616e20626520736574207573696e6720746865205b6047656e65736973436f6e666967605d206f72207468652101205b5365744e657874417373657449645d28606d6967726174696f6e3a3a6e6578745f61737365745f69643a3a5365744e657874417373657449646029206d6967726174696f6e2e01c102018c1c4052656d6f76654974656d734c696d69741010e80300000c5101204d6178206e756d626572206f66206974656d7320746f2064657374726f7920706572206064657374726f795f6163636f756e74736020616e64206064657374726f795f617070726f76616c73602063616c6c2e003901204d75737420626520636f6e6669677572656420746f20726573756c7420696e2061207765696768742074686174206d616b657320656163682063616c6c2066697420696e206120626c6f636b2e3041737365744465706f73697418400000e8890423c78a000000000000000004f82054686520626173696320616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f7220616e2061737365742e4c41737365744163636f756e744465706f73697418400000e8890423c78a00000000000000000845012054686520616d6f756e74206f662066756e64732074686174206d75737420626520726573657276656420666f722061206e6f6e2d70726f7669646572206173736574206163636f756e7420746f20626530206d61696e7461696e65642e4c4d657461646174614465706f736974426173651840000054129336377505000000000000000451012054686520626173696320616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e20616464696e67206d6574616461746120746f20796f75722061737365742e584d657461646174614465706f7369745065724279746518400000c16ff2862300000000000000000008550120546865206164646974696f6e616c2066756e64732074686174206d75737420626520726573657276656420666f7220746865206e756d626572206f6620627974657320796f752073746f726520696e20796f757228206d657461646174612e3c417070726f76616c4465706f736974184000e40b540200000000000000000000000421012054686520616d6f756e74206f662066756e64732074686174206d757374206265207265736572766564207768656e206372656174696e672061206e657720617070726f76616c2e2c537472696e674c696d697410103200000004e020546865206d6178696d756d206c656e677468206f662061206e616d65206f722073796d626f6c2073746f726564206f6e2d636861696e2e015507052042616c616e636573012042616c616e6365731c34546f74616c49737375616e6365010018400000000000000000000000000000000004982054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e40496e61637469766549737375616e636501001840000000000000000000000000000000000409012054686520746f74616c20756e697473206f66206f75747374616e64696e672064656163746976617465642062616c616e636520696e207468652073797374656d2e1c4163636f756e74010104020014010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080600901205468652042616c616e6365732070616c6c6574206578616d706c65206f662073746f72696e67207468652062616c616e6365206f6620616e206163636f756e742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b19022020202074797065204163636f756e7453746f7265203d2053746f726167654d61705368696d3c53656c663a3a4163636f756e743c52756e74696d653e2c206672616d655f73797374656d3a3a50726f76696465723c52756e74696d653e2c204163636f756e7449642c2053656c663a3a4163636f756e74446174613c42616c616e63653e3e0c20207d102060606000150120596f752063616e20616c736f2073746f7265207468652062616c616e6365206f6620616e206163636f756e7420696e20746865206053797374656d602070616c6c65742e00282023204578616d706c650034206060606e6f636f6d70696c65b02020696d706c2070616c6c65745f62616c616e6365733a3a436f6e66696720666f722052756e74696d65207b7420202074797065204163636f756e7453746f7265203d2053797374656d0c20207d102060606000510120427574207468697320636f6d657320776974682074726164656f6666732c2073746f72696e67206163636f756e742062616c616e63657320696e207468652073797374656d2070616c6c65742073746f7265736d0120606672616d655f73797374656d60206461746120616c6f6e677369646520746865206163636f756e74206461746120636f6e747261727920746f2073746f72696e67206163636f756e742062616c616e63657320696e207468652901206042616c616e636573602070616c6c65742c20776869636820757365732061206053746f726167654d61706020746f2073746f72652062616c616e6365732064617461206f6e6c792e4101204e4f54453a2054686973206973206f6e6c79207573656420696e207468652063617365207468617420746869732070616c6c6574206973207573656420746f2073746f72652062616c616e6365732e144c6f636b7301010402005907040010b820416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e2501204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602052657365727665730101040200690704000ca4204e616d6564207265736572766573206f6e20736f6d65206163636f756e742062616c616e6365732e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f6014486f6c6473010104020075070400046c20486f6c6473206f6e206163636f756e742062616c616e6365732e1c467265657a6573010104020089070400048820467265657a65206c6f636b73206f6e206163636f756e742062616c616e6365732e01c902019010484578697374656e7469616c4465706f736974184000e40b5402000000000000000000000020410120546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e204d5553542042452047524541544552205448414e205a45524f2100590120496620796f75202a7265616c6c792a206e65656420697420746f206265207a65726f2c20796f752063616e20656e61626c652074686520666561747572652060696e7365637572655f7a65726f5f65646020666f72610120746869732070616c6c65742e20486f77657665722c20796f7520646f20736f20617420796f7572206f776e207269736b3a20746869732077696c6c206f70656e2075702061206d616a6f7220446f5320766563746f722e590120496e206361736520796f752068617665206d756c7469706c6520736f7572636573206f662070726f7669646572207265666572656e6365732c20796f75206d617920616c736f2067657420756e65787065637465648c206265686176696f757220696620796f7520736574207468697320746f207a65726f2e00f020426f74746f6d206c696e653a20446f20796f757273656c662061206661766f757220616e64206d616b65206974206174206c65617374206f6e6521204d61784c6f636b7310103200000010f420546865206d6178696d756d206e756d626572206f66206c6f636b7320746861742073686f756c64206578697374206f6e20616e206163636f756e742edc204e6f74207374726963746c7920656e666f726365642c20627574207573656420666f722077656967687420657374696d6174696f6e2e00ad0120557365206f66206c6f636b73206973206465707265636174656420696e206661766f7572206f6620667265657a65732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f602c4d617852657365727665731010320000000c0d0120546865206d6178696d756d206e756d626572206f66206e616d656420726573657276657320746861742063616e206578697374206f6e20616e206163636f756e742e00b10120557365206f66207265736572766573206973206465707265636174656420696e206661766f7572206f6620686f6c64732e20536565206068747470733a2f2f6769746875622e636f6d2f706172697479746563682f7375627374726174652f70756c6c2f31323935312f60284d6178467265657a657310103200000004610120546865206d6178696d756d206e756d626572206f6620696e646976696475616c20667265657a65206c6f636b7320746861742063616e206578697374206f6e20616e206163636f756e7420617420616e792074696d652e01a10706485472616e73616374696f6e5061796d656e7401485472616e73616374696f6e5061796d656e7408444e6578744665654d756c7469706c6965720100a50740000064a7b3b6e00d0000000000000000003853746f7261676556657273696f6e0100a90704000000019804604f7065726174696f6e616c4665654d756c7469706c696572080405545901204120666565206d756c7469706c69657220666f7220604f7065726174696f6e616c602065787472696e7369637320746f20636f6d7075746520227669727475616c207469702220746f20626f6f73742074686569722c20607072696f726974796000510120546869732076616c7565206973206d756c7469706c69656420627920746865206066696e616c5f6665656020746f206f627461696e206120227669727475616c20746970222074686174206973206c61746572f420616464656420746f20612074697020636f6d706f6e656e7420696e20726567756c617220607072696f72697479602063616c63756c6174696f6e732e4d01204974206d65616e732074686174206120604e6f726d616c60207472616e73616374696f6e2063616e2066726f6e742d72756e20612073696d696c61726c792d73697a656420604f7065726174696f6e616c6041012065787472696e736963202877697468206e6f20746970292c20627920696e636c7564696e672061207469702076616c75652067726561746572207468616e20746865207669727475616c207469702e003c20606060727573742c69676e6f726540202f2f20466f7220604e6f726d616c608c206c6574207072696f72697479203d207072696f726974795f63616c6328746970293b0054202f2f20466f7220604f7065726174696f6e616c601101206c6574207669727475616c5f746970203d2028696e636c7573696f6e5f666565202b2074697029202a204f7065726174696f6e616c4665654d756c7469706c6965723bc4206c6574207072696f72697479203d207072696f726974795f63616c6328746970202b207669727475616c5f746970293b1020606060005101204e6f746520746861742073696e636520776520757365206066696e616c5f6665656020746865206d756c7469706c696572206170706c69657320616c736f20746f2074686520726567756c61722060746970605d012073656e74207769746820746865207472616e73616374696f6e2e20536f2c206e6f74206f6e6c7920646f657320746865207472616e73616374696f6e206765742061207072696f726974792062756d702062617365646101206f6e207468652060696e636c7573696f6e5f666565602c2062757420776520616c736f20616d706c6966792074686520696d70616374206f662074697073206170706c69656420746f20604f7065726174696f6e616c6038207472616e73616374696f6e732e000728417574686f72736869700128417574686f72736869700418417574686f720000000400046420417574686f72206f662063757272656e7420626c6f636b2e00000000081042616265011042616265442845706f6368496e64657801003020000000000000000004542043757272656e742065706f636820696e6465782e2c417574686f7269746965730100ad070400046c2043757272656e742065706f636820617574686f7269746965732e2c47656e65736973536c6f740100e10220000000000000000008f82054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e205468697320697320309020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2c43757272656e74536c6f740100e10220000000000000000004542043757272656e7420736c6f74206e756d6265722e2852616e646f6d6e65737301000480000000000000000000000000000000000000000000000000000000000000000028b8205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e002c20232053656375726974790005012054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061f8206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e7915012063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d6265727320746861742074686973150120286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e206265050120757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e0d01206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e6050656e64696e6745706f6368436f6e6669674368616e67650000e90204000461012050656e64696e672065706f636820636f6e66696775726174696f6e206368616e676520746861742077696c6c206265206170706c696564207768656e20746865206e6578742065706f636820697320656e61637465642e384e65787452616e646f6d6e657373010004800000000000000000000000000000000000000000000000000000000000000000045c204e6578742065706f63682072616e646f6d6e6573732e3c4e657874417574686f7269746965730100ad0704000460204e6578742065706f636820617574686f7269746965732e305365676d656e74496e6465780100101000000000247c2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e00f8205765206d616b6520612074726164652d6f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e01012057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f942060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e00ec204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e090120576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572791c2065706f63682e44556e646572436f6e737472756374696f6e0101040510b90704000415012054574f582d4e4f54453a20605365676d656e74496e6465786020697320616e20696e6372656173696e6720696e74656765722c20736f2074686973206973206f6b61792e2c496e697469616c697a65640000c10704000801012054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d65601d01206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e4c417574686f7256726652616e646f6d6e65737301003d0104001015012054686973206669656c642073686f756c6420616c7761797320626520706f70756c6174656420647572696e6720626c6f636b2070726f63657373696e6720756e6c6573731901207365636f6e6461727920706c61696e20736c6f74732061726520656e61626c65642028776869636820646f6e277420636f6e7461696e206120565246206f7574707574292e0049012049742069732073657420696e20606f6e5f66696e616c697a65602c206265666f72652069742077696c6c20636f6e7461696e207468652076616c75652066726f6d20746865206c61737420626c6f636b2e2845706f636853746172740100ed024000000000000000000000000000000000145d012054686520626c6f636b206e756d62657273207768656e20746865206c61737420616e642063757272656e742065706f6368206861766520737461727465642c20726573706563746976656c7920604e2d316020616e641420604e602e4901204e4f54453a20576520747261636b207468697320697320696e206f7264657220746f20616e6e6f746174652074686520626c6f636b206e756d626572207768656e206120676976656e20706f6f6c206f66590120656e74726f7079207761732066697865642028692e652e20697420776173206b6e6f776e20746f20636861696e206f6273657276657273292e2053696e63652065706f6368732061726520646566696e656420696e590120736c6f74732c207768696368206d617920626520736b69707065642c2074686520626c6f636b206e756d62657273206d6179206e6f74206c696e6520757020776974682074686520736c6f74206e756d626572732e204c6174656e65737301003020000000000000000014d820486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e001501205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e65642075701101206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636bb020657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2c45706f6368436f6e6669670000d90704000861012054686520636f6e66696775726174696f6e20666f72207468652063757272656e742065706f63682e2053686f756c64206e6576657220626520604e6f6e656020617320697420697320696e697469616c697a656420696e242067656e657369732e3c4e65787445706f6368436f6e6669670000d9070400082d012054686520636f6e66696775726174696f6e20666f7220746865206e6578742065706f63682c20604e6f6e65602069662074686520636f6e6669672077696c6c206e6f74206368616e6765e82028796f752063616e2066616c6c6261636b20746f206045706f6368436f6e6669676020696e737465616420696e20746861742063617365292e34536b697070656445706f6368730100dd0704002029012041206c697374206f6620746865206c6173742031303020736b69707065642065706f63687320616e642074686520636f72726573706f6e64696e672073657373696f6e20696e64657870207768656e207468652065706f63682077617320736b69707065642e0031012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f663501206d75737420636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e656564206139012077617920746f2074696520746f6765746865722073657373696f6e7320616e642065706f636820696e64696365732c20692e652e207765206e65656420746f2076616c69646174652074686174290120612076616c696461746f722077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e64207768617420746865b0206163746976652065706f636820696e6465782077617320647572696e6720746861742073657373696f6e2e01d10200103445706f63684475726174696f6e3020b0040000000000000cec2054686520616d6f756e74206f662074696d652c20696e20736c6f74732c207468617420656163682065706f63682073686f756c64206c6173742e1901204e4f54453a2043757272656e746c79206974206973206e6f7420706f737369626c6520746f206368616e6765207468652065706f6368206475726174696f6e20616674657221012074686520636861696e2068617320737461727465642e20417474656d7074696e6720746f20646f20736f2077696c6c20627269636b20626c6f636b2070726f64756374696f6e2e444578706563746564426c6f636b54696d653020701700000000000014050120546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e67110120626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f75740501207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f740901206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473a0207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e384d6178417574686f7269746965731010e80300000488204d6178206e756d626572206f6620617574686f72697469657320616c6c6f776564344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e01e107091c4772616e647061011c4772616e6470611c1453746174650100e50704000490205374617465206f66207468652063757272656e7420617574686f72697479207365742e3450656e64696e674368616e67650000e907040004c42050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e284e657874466f72636564000030040004bc206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e1c5374616c6c65640000ed020400049020607472756560206966207765206172652063757272656e746c79207374616c6c65642e3043757272656e745365744964010030200000000000000000085d0120546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c697469657329c420696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e30536574496453657373696f6e00010405301004002859012041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f722077686963682069747368206d656d62657273207765726520726573706f6e7369626c652e0045012054686973206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e2070726f6f66732e20416e2065717569766f636174696f6e2070726f6f66206d7573744d0120636f6e7461696e732061206b65792d6f776e6572736869702070726f6f6620666f72206120676976656e2073657373696f6e2c207468657265666f7265207765206e65656420612077617920746f20746965450120746f6765746865722073657373696f6e7320616e64204752414e44504120736574206964732c20692e652e207765206e65656420746f2076616c6964617465207468617420612076616c696461746f7241012077617320746865206f776e6572206f66206120676976656e206b6579206f6e206120676976656e2073657373696f6e2c20616e642077686174207468652061637469766520736574204944207761735420647572696e6720746861742073657373696f6e2e00b82054574f582d4e4f54453a2060536574496460206973206e6f7420756e646572207573657220636f6e74726f6c2e2c417574686f7269746965730100ed0704000484205468652063757272656e74206c697374206f6620617574686f7269746965732e01f502019c0c384d6178417574686f7269746965731010e8030000045c204d617820417574686f72697469657320696e20757365344d61784e6f6d696e61746f727310100001000004d420546865206d6178696d756d206e756d626572206f66206e6f6d696e61746f727320666f7220656163682076616c696461746f722e584d6178536574496453657373696f6e456e74726965733020000000000000000018390120546865206d6178696d756d206e756d626572206f6620656e747269657320746f206b65657020696e207468652073657420696420746f2073657373696f6e20696e646578206d617070696e672e0031012053696e6365207468652060536574496453657373696f6e60206d6170206973206f6e6c79207573656420666f722076616c69646174696e672065717569766f636174696f6e73207468697329012076616c75652073686f756c642072656c61746520746f2074686520626f6e64696e67206475726174696f6e206f66207768617465766572207374616b696e672073797374656d2069733501206265696e6720757365642028696620616e79292e2049662065717569766f636174696f6e2068616e646c696e67206973206e6f7420656e61626c6564207468656e20746869732076616c7565342063616e206265207a65726f2e01f1070a1c496e6469636573011c496e646963657304204163636f756e74730001040210f5070400048820546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e01250301ac041c4465706f7369741840000064a7b3b6e00d000000000000000004ac20546865206465706f736974206e656564656420666f7220726573657276696e6720616e20696e6465782e01f9070b2444656d6f6372616379012444656d6f6372616379303c5075626c696350726f70436f756e74010010100000000004f420546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e2c5075626c696350726f70730100fd07040004050120546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c2e244465706f7369744f660001040510090804000c842054686f73652077686f2068617665206c6f636b65642061206465706f7369742e00d82054574f582d4e4f54453a20536166652c20617320696e6372656173696e6720696e7465676572206b6579732061726520736166652e3c5265666572656e64756d436f756e74010010100000000004310120546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e344c6f77657374556e62616b6564010010100000000008250120546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746fdc20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e405265666572656e64756d496e666f4f6600010405100d0804000cb420496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e0009012054574f582d4e4f54453a205341464520617320696e646578657320617265206e6f7420756e64657220616e2061747461636b6572e280997320636f6e74726f6c2e20566f74696e674f6601010405001908e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105d0120416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077655d012068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e00e82054574f582d4e4f54453a205341464520617320604163636f756e7449646073206172652063727970746f2068617368657320616e797761792e544c6173745461626c656457617345787465726e616c0100200400085901205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c6963282070726f706f73616c2e304e65787445787465726e616c00003108040010590120546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e550120546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743aa4202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f7268202d20605075626c696350726f70736020697320656d7074792e24426c61636b6c6973740001040634350804000851012041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d626572e82028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e3443616e63656c6c6174696f6e730101040634200400042901205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e284d657461646174614f6600010402c034040018ec2047656e6572616c20696e666f726d6174696f6e20636f6e6365726e696e6720616e792070726f706f73616c206f72207265666572656e64756d2e490120546865206048617368602072656665727320746f2074686520707265696d616765206f66207468652060507265696d61676573602070726f76696465722077686963682063616e2062652061204a534f4e882064756d70206f7220495046532068617368206f662061204a534f4e2066696c652e00750120436f6e73696465722061206761726261676520636f6c6c656374696f6e20666f722061206d65746164617461206f662066696e6973686564207265666572656e64756d7320746f2060756e7265717565737460202872656d6f76652944206c6172676520707265696d616765732e01290301b0303c456e6163746d656e74506572696f643020c0a800000000000014e82054686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e0031012049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e737572652074686174510120766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365b4207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e304c61756e6368506572696f643020201c00000000000004e420486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e30566f74696e67506572696f643020c08901000000000004b820486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e44566f74654c6f636b696e67506572696f643020c0a8000000000000109020546865206d696e696d756d20706572696f64206f6620766f7465206c6f636b696e672e0065012049742073686f756c64206265206e6f2073686f72746572207468616e20656e6163746d656e7420706572696f6420746f20656e73757265207468617420696e207468652063617365206f6620616e20617070726f76616c2c49012074686f7365207375636365737366756c20766f7465727320617265206c6f636b656420696e746f2074686520636f6e73657175656e636573207468617420746865697220766f74657320656e7461696c2e384d696e696d756d4465706f73697418400000a0dec5adc935360000000000000004350120546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e38496e7374616e74416c6c6f7765642004010c550120496e64696361746f7220666f72207768657468657220616e20656d657267656e6379206f726967696e206973206576656e20616c6c6f77656420746f2068617070656e2e20536f6d6520636861696e73206d617961012077616e7420746f207365742074686973207065726d616e656e746c7920746f206066616c7365602c206f7468657273206d61792077616e7420746f20636f6e646974696f6e206974206f6e207468696e67732073756368a020617320616e207570677261646520686176696e672068617070656e656420726563656e746c792e5446617374547261636b566f74696e67506572696f643020807000000000000004ec204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f72206120666173742d747261636b207265666572656e64756d2e34436f6f6c6f6666506572696f643020c0a800000000000004610120506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d6178566f74657310106400000010b020546865206d6178696d756d206e756d626572206f6620766f74657320666f7220616e206163636f756e742e00d420416c736f207573656420746f20636f6d70757465207765696768742c20616e206f7665726c79206269672076616c75652063616e1501206c65616420746f2065787472696e7369632077697468207665727920626967207765696768743a20736565206064656c65676174656020666f7220696e7374616e63652e304d617850726f706f73616c73101064000000040d0120546865206d6178696d756d206e756d626572206f66207075626c69632070726f706f73616c7320746861742063616e20657869737420617420616e792074696d652e2c4d61784465706f73697473101064000000041d0120546865206d6178696d756d206e756d626572206f66206465706f736974732061207075626c69632070726f706f73616c206d6179206861766520617420616e792074696d652e384d6178426c61636b6c697374656410106400000004d820546865206d6178696d756d206e756d626572206f66206974656d732077686963682063616e20626520626c61636b6c69737465642e0139080c1c436f756e63696c011c436f756e63696c182450726f706f73616c7301003d08040004902054686520686173686573206f6620746865206163746976652070726f706f73616c732e2850726f706f73616c4f660001040634bd02040004cc2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e18566f74696e6700010406344108040004b420566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e3450726f706f73616c436f756e74010010100000000004482050726f706f73616c7320736f206661722e1c4d656d62657273010035020400043901205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e145072696d65000000040004610120546865207072696d65206d656d62657220746861742068656c70732064657465726d696e65207468652064656661756c7420766f7465206265686176696f7220696e2063617365206f662061627374656e74696f6e732e01450301c404444d617850726f706f73616c576569676874283c070010a5d4e813ffffffffffffff7f04250120546865206d6178696d756d20776569676874206f6620612064697370617463682063616c6c20746861742063616e2062652070726f706f73656420616e642065786563757465642e0145080d1c56657374696e67011c56657374696e67081c56657374696e6700010402004908040004d820496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e3853746f7261676556657273696f6e0100510804000c7c2053746f726167652076657273696f6e206f66207468652070616c6c65742e003101204e6577206e6574776f726b732073746172742077697468206c61746573742076657273696f6e2c2061732064657465726d696e6564206279207468652067656e65736973206275696c642e01490301c808444d696e5665737465645472616e736665721840000010632d5ec76b050000000000000004e820546865206d696e696d756d20616d6f756e74207472616e7366657272656420746f2063616c6c20607665737465645f7472616e73666572602e4c4d617856657374696e675363686564756c657310101c000000000155080e24456c656374696f6e730124456c656374696f6e73141c4d656d626572730100590804000c74205468652063757272656e7420656c6563746564206d656d626572732e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e2452756e6e65727355700100590804001084205468652063757272656e742072657365727665642072756e6e6572732d75702e00590120496e76617269616e743a20416c7761797320736f72746564206261736564206f6e2072616e6b2028776f72736520746f2062657374292e2055706f6e2072656d6f76616c206f662061206d656d6265722c20746865bc206c6173742028692e652e205f626573745f292072756e6e65722d75702077696c6c206265207265706c616365642e2843616e646964617465730100d00400185901205468652070726573656e742063616e646964617465206c6973742e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f72d020616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e007c205365636f6e6420656c656d656e7420697320746865206465706f7369742e00b820496e76617269616e743a20416c7761797320736f72746564206261736564206f6e206163636f756e742069642e38456c656374696f6e526f756e647301001010000000000441012054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e18566f74696e6701010405006108840000000000000000000000000000000000000000000000000000000000000000000cb820566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e00c42054574f582d4e4f54453a205341464520617320604163636f756e7449646020697320612063727970746f20686173682e01510301cc282050616c6c65744964ad0220706872656c65637404d0204964656e74696669657220666f722074686520656c656374696f6e732d70687261676d656e2070616c6c65742773206c6f636b3443616e646964616379426f6e6418400000a0dec5adc935360000000000000004050120486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e38566f74696e67426f6e6442617365184000005053c91aa974050000000000000010942042617365206465706f736974206173736f636961746564207769746820766f74696e672e00550120546869732073686f756c642062652073656e7369626c79206869676820746f2065636f6e6f6d6963616c6c7920656e73757265207468652070616c6c65742063616e6e6f742062652061747461636b656420627994206372656174696e67206120676967616e746963206e756d626572206f6620766f7465732e40566f74696e67426f6e64466163746f721840000020f84dde700400000000000000000411012054686520616d6f756e74206f6620626f6e642074686174206e65656420746f206265206c6f636b656420666f72206561636820766f746520283332206279746573292e38446573697265644d656d626572731010050000000470204e756d626572206f66206d656d6265727320746f20656c6563742e404465736972656452756e6e65727355701010030000000478204e756d626572206f662072756e6e6572735f757020746f206b6565702e305465726d4475726174696f6e3020c0890100000000000c510120486f77206c6f6e6720656163682073656174206973206b6570742e205468697320646566696e657320746865206e65787420626c6f636b206e756d62657220617420776869636820616e20656c656374696f6e5d0120726f756e642077696c6c2068617070656e2e2049662073657420746f207a65726f2c206e6f20656c656374696f6e732061726520657665722074726967676572656420616e6420746865206d6f64756c652077696c6c5020626520696e2070617373697665206d6f64652e344d617843616e6469646174657310104000000018e420546865206d6178696d756d206e756d626572206f662063616e6469646174657320696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e003101205768656e2074686973206c696d69742069732072656163686564206e6f206d6f72652063616e646964617465732061726520616363657074656420696e2074686520656c656374696f6e2e244d6178566f7465727310100002000018f820546865206d6178696d756d206e756d626572206f6620766f7465727320746f20616c6c6f7720696e20612070687261676d656e20656c656374696f6e2e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e00d8205768656e20746865206c696d6974206973207265616368656420746865206e657720766f74657273206172652069676e6f7265642e404d6178566f746573506572566f7465721010640000001090204d6178696d756d206e756d62657273206f6620766f7465732070657220766f7465722e005d01205761726e696e673a205468697320696d7061637473207468652073697a65206f662074686520656c656374696f6e2077686963682069732072756e206f6e636861696e2e2043686f736520776973656c792c20616e64010120636f6e736964657220686f772069742077696c6c20696d706163742060543a3a576569676874496e666f3a3a656c656374696f6e5f70687261676d656e602e0165080f68456c656374696f6e50726f76696465724d756c746950686173650168456c656374696f6e50726f76696465724d756c746950686173652814526f756e64010010100100000018ac20496e7465726e616c20636f756e74657220666f7220746865206e756d626572206f6620726f756e64732e00550120546869732069732075736566756c20666f722064652d6475706c69636174696f6e206f66207472616e73616374696f6e73207375626d697474656420746f2074686520706f6f6c2c20616e642067656e6572616c6c20646961676e6f7374696373206f66207468652070616c6c65742e004d012054686973206973206d6572656c7920696e6372656d656e746564206f6e6365207065722065766572792074696d65207468617420616e20757073747265616d2060656c656374602069732063616c6c65642e3043757272656e7450686173650100e40400043c2043757272656e742070686173652e38517565756564536f6c7574696f6e0000690804000c3d012043757272656e74206265737420736f6c7574696f6e2c207369676e6564206f7220756e7369676e65642c2071756575656420746f2062652072657475726e65642075706f6e2060656c656374602e006020416c7761797320736f727465642062792073636f72652e20536e617073686f74000071080400107020536e617073686f742064617461206f662074686520726f756e642e005d01205468697320697320637265617465642061742074686520626567696e6e696e67206f6620746865207369676e656420706861736520616e6420636c65617265642075706f6e2063616c6c696e672060656c656374602e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e384465736972656454617267657473000010040010cc2044657369726564206e756d626572206f66207461726765747320746f20656c65637420666f72207468697320726f756e642e00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e40536e617073686f744d6574616461746100002d040400109820546865206d65746164617461206f6620746865205b60526f756e64536e617073686f74605d00a8204f6e6c7920657869737473207768656e205b60536e617073686f74605d2069732070726573656e742e2901204e6f74653a20546869732073746f726167652074797065206d757374206f6e6c79206265206d757461746564207468726f756768205b60536e617073686f7457726170706572605d2e645369676e65645375626d697373696f6e4e657874496e646578010010100000000024010120546865206e65787420696e64657820746f2062652061737369676e656420746f20616e20696e636f6d696e67207369676e6564207375626d697373696f6e2e007501204576657279206163636570746564207375626d697373696f6e2069732061737369676e6564206120756e6971756520696e6465783b207468617420696e64657820697320626f756e6420746f207468617420706172746963756c61726501207375626d697373696f6e20666f7220746865206475726174696f6e206f662074686520656c656374696f6e2e204f6e20656c656374696f6e2066696e616c697a6174696f6e2c20746865206e65787420696e6465782069733020726573657420746f20302e0069012057652063616e2774206a7573742075736520605369676e65645375626d697373696f6e496e64696365732e6c656e2829602c206265636175736520746861742773206120626f756e646564207365743b20706173742069747359012063617061636974792c2069742077696c6c2073696d706c792073617475726174652e2057652063616e2774206a7573742069746572617465206f76657220605369676e65645375626d697373696f6e734d6170602cf4206265636175736520697465726174696f6e20697320736c6f772e20496e73746561642c2077652073746f7265207468652076616c756520686572652e5c5369676e65645375626d697373696f6e496e6469636573010081080400186d01204120736f727465642c20626f756e64656420766563746f72206f6620602873636f72652c20626c6f636b5f6e756d6265722c20696e64657829602c20776865726520656163682060696e6465786020706f696e747320746f2061782076616c756520696e20605369676e65645375626d697373696f6e73602e007101205765206e65766572206e65656420746f2070726f63657373206d6f7265207468616e20612073696e676c65207369676e6564207375626d697373696f6e20617420612074696d652e205369676e6564207375626d697373696f6e7375012063616e206265207175697465206c617267652c20736f2077652772652077696c6c696e6720746f207061792074686520636f7374206f66206d756c7469706c6520646174616261736520616363657373657320746f206163636573732101207468656d206f6e6520617420612074696d6520696e7374656164206f662072656164696e6720616e64206465636f64696e6720616c6c206f66207468656d206174206f6e63652e505369676e65645375626d697373696f6e734d617000010405108d0804001c7420556e636865636b65642c207369676e656420736f6c7574696f6e732e00690120546f676574686572207769746820605375626d697373696f6e496e6469636573602c20746869732073746f726573206120626f756e64656420736574206f6620605369676e65645375626d697373696f6e7360207768696c65ec20616c6c6f77696e6720757320746f206b656570206f6e6c7920612073696e676c65206f6e6520696e206d656d6f727920617420612074696d652e0069012054776f78206e6f74653a20746865206b6579206f6620746865206d617020697320616e206175746f2d696e6372656d656e74696e6720696e6465782077686963682075736572732063616e6e6f7420696e7370656374206f72f4206166666563743b2077652073686f756c646e2774206e65656420612063727970746f67726170686963616c6c7920736563757265206861736865722e544d696e696d756d556e7472757374656453636f72650000e00400105d0120546865206d696e696d756d2073636f7265207468617420656163682027756e747275737465642720736f6c7574696f6e206d7573742061747461696e20696e206f7264657220746f20626520636f6e7369646572656428206665617369626c652e00b82043616e206265207365742076696120607365745f6d696e696d756d5f756e747275737465645f73636f7265602e01590301d838544265747465725369676e65645468726573686f6c64f41000000000084d0120546865206d696e696d756d20616d6f756e74206f6620696d70726f76656d656e7420746f2074686520736f6c7574696f6e2073636f7265207468617420646566696e6573206120736f6c7574696f6e2061737820226265747465722220696e20746865205369676e65642070686173652e384f6666636861696e5265706561743020050000000000000010b42054686520726570656174207468726573686f6c64206f6620746865206f6666636861696e20776f726b65722e00610120466f72206578616d706c652c20696620697420697320352c2074686174206d65616e732074686174206174206c65617374203520626c6f636b732077696c6c20656c61707365206265747765656e20617474656d7074738420746f207375626d69742074686520776f726b6572277320736f6c7574696f6e2e3c4d696e657254785072696f726974793020feffffffffffff7f04250120546865207072696f72697479206f662074686520756e7369676e6564207472616e73616374696f6e207375626d697474656420696e2074686520756e7369676e65642d7068617365505369676e65644d61785375626d697373696f6e7310100a0000001ce4204d6178696d756d206e756d626572206f66207369676e6564207375626d697373696f6e7320746861742063616e206265207175657565642e005501204974206973206265737420746f2061766f69642061646a757374696e67207468697320647572696e6720616e20656c656374696f6e2c20617320697420696d706163747320646f776e73747265616d2064617461650120737472756374757265732e20496e20706172746963756c61722c20605369676e65645375626d697373696f6e496e64696365733c543e6020697320626f756e646564206f6e20746869732076616c75652e20496620796f75f42075706461746520746869732076616c756520647572696e6720616e20656c656374696f6e2c20796f75205f6d7573745f20656e7375726520746861744d0120605369676e65645375626d697373696f6e496e64696365732e6c656e282960206973206c657373207468616e206f7220657175616c20746f20746865206e65772076616c75652e204f74686572776973652cf020617474656d70747320746f207375626d6974206e657720736f6c7574696f6e73206d617920636175736520612072756e74696d652070616e69632e3c5369676e65644d617857656967687428400bd8e2a18c2e011366666666666666a61494204d6178696d756d20776569676874206f662061207369676e656420736f6c7574696f6e2e005d01204966205b60436f6e6669673a3a4d696e6572436f6e666967605d206973206265696e6720696d706c656d656e74656420746f207375626d6974207369676e656420736f6c7574696f6e7320286f757473696465206f663d0120746869732070616c6c6574292c207468656e205b604d696e6572436f6e6669673a3a736f6c7574696f6e5f776569676874605d206973207573656420746f20636f6d7061726520616761696e73743020746869732076616c75652e405369676e65644d6178526566756e647310100300000004190120546865206d6178696d756d20616d6f756e74206f6620756e636865636b656420736f6c7574696f6e7320746f20726566756e64207468652063616c6c2066656520666f722e405369676e6564526577617264426173651840000064a7b3b6e00d0000000000000000048820426173652072657761726420666f722061207369676e656420736f6c7574696f6e445369676e65644465706f73697442797465184000008a5d78456301000000000000000004a0205065722d62797465206465706f73697420666f722061207369676e656420736f6c7574696f6e2e4c5369676e65644465706f73697457656967687418400000000000000000000000000000000004a8205065722d776569676874206465706f73697420666f722061207369676e656420736f6c7574696f6e2e284d617857696e6e6572731010e803000010350120546865206d6178696d756d206e756d626572206f662077696e6e65727320746861742063616e20626520656c656374656420627920746869732060456c656374696f6e50726f7669646572604020696d706c656d656e746174696f6e2e005101204e6f74653a2054686973206d75737420616c776179732062652067726561746572206f7220657175616c20746f2060543a3a4461746150726f76696465723a3a646573697265645f746172676574732829602e384d696e65724d61784c656e67746810100000360000384d696e65724d617857656967687428400bd8e2a18c2e011366666666666666a600544d696e65724d6178566f746573506572566f746572101010000000003c4d696e65724d617857696e6e6572731010e803000000019108101c5374616b696e67011c5374616b696e67ac3856616c696461746f72436f756e740100101000000000049c2054686520696465616c206e756d626572206f66206163746976652076616c696461746f72732e544d696e696d756d56616c696461746f72436f756e740100101000000000044101204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e34496e76756c6e657261626c65730100350204000c590120416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e636520746865792772654d01206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f7572ac20696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e18426f6e64656400010405000004000c0101204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e404d696e4e6f6d696e61746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f662061206e6f6d696e61746f722e404d696e56616c696461746f72426f6e64010018400000000000000000000000000000000004210120546865206d696e696d756d2061637469766520626f6e6420746f206265636f6d6520616e64206d61696e7461696e2074686520726f6c65206f6620612076616c696461746f722e484d696e696d756d4163746976655374616b65010018400000000000000000000000000000000004110120546865206d696e696d756d20616374697665206e6f6d696e61746f72207374616b65206f6620746865206c617374207375636365737366756c20656c656374696f6e2e344d696e436f6d6d697373696f6e0100f410000000000ce820546865206d696e696d756d20616d6f756e74206f6620636f6d6d697373696f6e20746861742076616c696461746f72732063616e207365742e00802049662073657420746f206030602c206e6f206c696d6974206578697374732e184c6564676572000104020095080400104501204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e007501204e6f74653a20416c6c2074686520726561647320616e64206d75746174696f6e7320746f20746869732073746f72616765202a4d5553542a20626520646f6e65207468726f75676820746865206d6574686f6473206578706f736564e8206279205b605374616b696e674c6564676572605d20746f20656e73757265206461746120616e64206c6f636b20636f6e73697374656e63792e1450617965650001040500f004000ce42057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e2856616c696461746f72730101040500f80800000c450120546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f7256616c696461746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d617856616c696461746f7273436f756e7400001004000c310120546865206d6178696d756d2076616c696461746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e284e6f6d696e61746f727300010405009d0804004c750120546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f207468656972206e6f6d696e6174696f6e20707265666572656e6365732c206e616d656c79207468652076616c696461746f72732074686174582074686579207769736820746f20737570706f72742e003901204e6f7465207468617420746865206b657973206f6620746869732073746f72616765206d6170206d69676874206265636f6d65206e6f6e2d6465636f6461626c6520696e2063617365207468652d01206163636f756e742773205b604e6f6d696e6174696f6e7351756f74613a3a4d61784e6f6d696e6174696f6e73605d20636f6e66696775726174696f6e206973206465637265617365642e9020496e2074686973207261726520636173652c207468657365206e6f6d696e61746f7273650120617265207374696c6c206578697374656e7420696e2073746f726167652c207468656972206b657920697320636f727265637420616e64207265747269657661626c652028692e652e2060636f6e7461696e735f6b657960710120696e6469636174657320746861742074686579206578697374292c206275742074686569722076616c75652063616e6e6f74206265206465636f6465642e205468657265666f72652c20746865206e6f6e2d6465636f6461626c656d01206e6f6d696e61746f72732077696c6c206566666563746976656c79206e6f742d65786973742c20756e74696c20746865792072652d7375626d697420746865697220707265666572656e6365732073756368207468617420697401012069732077697468696e2074686520626f756e6473206f6620746865206e65776c79207365742060436f6e6669673a3a4d61784e6f6d696e6174696f6e73602e006101205468697320696d706c696573207468617420603a3a697465725f6b65797328292e636f756e7428296020616e6420603a3a6974657228292e636f756e74282960206d696768742072657475726e20646966666572656e746d012076616c75657320666f722074686973206d61702e204d6f72656f7665722c20746865206d61696e20603a3a636f756e7428296020697320616c69676e656420776974682074686520666f726d65722c206e616d656c79207468656c206e756d626572206f66206b65797320746861742065786973742e006d01204c6173746c792c20696620616e79206f6620746865206e6f6d696e61746f7273206265636f6d65206e6f6e2d6465636f6461626c652c20746865792063616e206265206368696c6c656420696d6d6564696174656c7920766961b8205b6043616c6c3a3a6368696c6c5f6f74686572605d20646973706174636861626c6520627920616e796f6e652e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e50436f756e746572466f724e6f6d696e61746f7273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170385669727475616c5374616b657273000104050084040018c8205374616b6572732077686f73652066756e647320617265206d616e61676564206279206f746865722070616c6c6574732e00750120546869732070616c6c657420646f6573206e6f74206170706c7920616e79206c6f636b73206f6e207468656d2c207468657265666f7265207468657920617265206f6e6c79207669727475616c6c7920626f6e6465642e20546865796d012061726520657870656374656420746f206265206b65796c657373206163636f756e747320616e642068656e63652073686f756c64206e6f7420626520616c6c6f77656420746f206d7574617465207468656972206c65646765727101206469726563746c792076696120746869732070616c6c65742e20496e73746561642c207468657365206163636f756e747320617265206d616e61676564206279206f746865722070616c6c65747320616e64206163636573736564290120766961206c6f77206c6576656c20617069732e205765206b65657020747261636b206f66207468656d20746f20646f206d696e696d616c20696e7465677269747920636865636b732e60436f756e746572466f725669727475616c5374616b657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170484d61784e6f6d696e61746f7273436f756e7400001004000c310120546865206d6178696d756d206e6f6d696e61746f7220636f756e74206265666f72652077652073746f7020616c6c6f77696e67206e65772076616c696461746f727320746f206a6f696e2e00d0205768656e20746869732076616c7565206973206e6f74207365742c206e6f206c696d6974732061726520656e666f726365642e2843757272656e744572610000100400105c205468652063757272656e742065726120696e6465782e006501205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f7280207365742c206974206d6967687420626520616374697665206f72206e6f742e244163746976654572610000a108040010d820546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e0059012054686520616374697665206572612069732074686520657261206265696e672063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d757374206265ac20657175616c20746f205b6053657373696f6e496e746572666163653a3a76616c696461746f7273605d2e5445726173537461727453657373696f6e496e6465780001040510100400105501205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e006101204e6f74653a205468697320747261636b7320746865207374617274696e672073657373696f6e2028692e652e2073657373696f6e20696e646578207768656e20657261207374617274206265696e672061637469766529f020666f7220746865206572617320696e20605b43757272656e74457261202d20484953544f52595f44455054482c2043757272656e744572615d602e2c457261735374616b6572730101080505a50869010c0000002078204578706f73757265206f662076616c696461746f72206174206572612e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e4c457261735374616b6572734f766572766965770001080505a508a908040030b82053756d6d617279206f662076616c696461746f72206578706f73757265206174206120676976656e206572612e007101205468697320636f6e7461696e732074686520746f74616c207374616b6520696e20737570706f7274206f66207468652076616c696461746f7220616e64207468656972206f776e207374616b652e20496e206164646974696f6e2c75012069742063616e20616c736f206265207573656420746f2067657420746865206e756d626572206f66206e6f6d696e61746f7273206261636b696e6720746869732076616c696461746f7220616e6420746865206e756d626572206f666901206578706f73757265207061676573207468657920617265206469766964656420696e746f2e20546865207061676520636f756e742069732075736566756c20746f2064657465726d696e6520746865206e756d626572206f66ac207061676573206f6620726577617264732074686174206e6565647320746f20626520636c61696d65642e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742eac2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206f766572766965772069732072657475726e65642e48457261735374616b657273436c69707065640101080505a50869010c000000409820436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e006501204e6f74653a205468697320697320646570726563617465642c2073686f756c64206265207573656420617320726561642d6f6e6c7920616e642077696c6c2062652072656d6f76656420696e20746865206675747572652e3101204e657720604578706f737572656073206172652073746f72656420696e2061207061676564206d616e6e657220696e2060457261735374616b65727350616765646020696e73746561642e00590120546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f20746865a82060543a3a4d61784578706f737572655061676553697a65602062696767657374207374616b6572732e1d0120284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292ef42054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e005d012054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4101204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e002901204e6f74653a20446570726563617465642073696e6365207631342e205573652060457261496e666f6020696e737465616420746f20776f726b2077697468206578706f73757265732e40457261735374616b657273506167656400010c050505ad08b108040018c020506167696e61746564206578706f73757265206f6620612076616c696461746f7220617420676976656e206572612e0071012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e2c207468656e207374617368206163636f756e7420616e642066696e616c6c79d42074686520706167652e2053686f756c64206f6e6c79206265206163636573736564207468726f7567682060457261496e666f602e00d4205468697320697320636c6561726564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e38436c61696d6564526577617264730101080505a5084904040018dc20486973746f7279206f6620636c61696d656420706167656420726577617264732062792065726120616e642076616c696461746f722e0069012054686973206973206b657965642062792065726120616e642076616c696461746f72207374617368207768696368206d61707320746f2074686520736574206f66207061676520696e6465786573207768696368206861766538206265656e20636c61696d65642e00cc2049742069732072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e484572617356616c696461746f7250726566730101080505a508f80800001411012053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e0061012054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e00cc2049732069742072656d6f766564206166746572205b60436f6e6669673a3a486973746f72794465707468605d20657261732e4c4572617356616c696461746f7252657761726400010405101804000c2d012054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e0021012045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e4045726173526577617264506f696e74730101040510b50814000000000008d0205265776172647320666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e250120496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e3845726173546f74616c5374616b6501010405101840000000000000000000000000000000000811012054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c617374205b60436f6e6669673a3a486973746f72794465707468605d20657261732e1d0120496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e20466f7263654572610100010104000454204d6f6465206f662065726120666f7263696e672e404d61785374616b6564526577617264730000550204000c1901204d6178696d756d207374616b656420726577617264732c20692e652e207468652070657263656e74616765206f66207468652065726120696e666c6174696f6e20746861746c206973207573656420666f72207374616b6520726577617264732eac20536565205b457261207061796f75745d282e2f696e6465782e68746d6c236572612d7061796f7574292e4c536c6173685265776172644672616374696f6e0100f410000000000cf8205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e00e4205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e4c43616e63656c6564536c6173685061796f757401001840000000000000000000000000000000000815012054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e7420776869636820776173ec2063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e40556e6170706c696564536c61736865730101040510c508040004c420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e28426f6e646564457261730100cd0804001025012041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e00c8204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653abc20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d604c56616c696461746f72536c617368496e4572610001080505a508d508040008450120416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e7020616e6420736c6173682076616c7565206f6620746865206572612e4c4e6f6d696e61746f72536c617368496e4572610001080505a50818040004610120416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e34536c617368696e675370616e730001040500d9080400048c20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e245370616e536c61736801010405c108dd08800000000000000000000000000000000000000000000000000000000000000000083d01205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2cb82061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e5443757272656e74506c616e6e656453657373696f6e01001010000000000ce820546865206c61737420706c616e6e65642073657373696f6e207363686564756c6564206279207468652073657373696f6e2070616c6c65742e0071012054686973206973206261736963616c6c7920696e2073796e632077697468207468652063616c6c20746f205b6070616c6c65745f73657373696f6e3a3a53657373696f6e4d616e616765723a3a6e65775f73657373696f6e605d2e4844697361626c656456616c696461746f72730100490404001c750120496e6469636573206f662076616c696461746f727320746861742068617665206f6666656e64656420696e2074686520616374697665206572612e20546865206f6666656e64657273206172652064697361626c656420666f72206169012077686f6c65206572612e20466f72207468697320726561736f6e207468657920617265206b6570742068657265202d206f6e6c79207374616b696e672070616c6c6574206b6e6f77732061626f757420657261732e20546865550120696d706c656d656e746f72206f66205b6044697361626c696e675374726174656779605d20646566696e657320696620612076616c696461746f722073686f756c642062652064697361626c65642077686963686d0120696d706c696369746c79206d65616e7320746861742074686520696d706c656d656e746f7220616c736f20636f6e74726f6c7320746865206d6178206e756d626572206f662064697361626c65642076616c696461746f72732e006d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f72206861732070726576696f75736c7978206f6666656e646564207573696e672062696e617279207365617263682e384368696c6c5468726573686f6c640000550204000c510120546865207468726573686f6c6420666f72207768656e2075736572732063616e2073746172742063616c6c696e6720606368696c6c5f6f746865726020666f72206f746865722076616c696461746f7273202f5901206e6f6d696e61746f72732e20546865207468726573686f6c6420697320636f6d706172656420746f207468652061637475616c206e756d626572206f662076616c696461746f7273202f206e6f6d696e61746f72732901202860436f756e74466f722a602920696e207468652073797374656d20636f6d706172656420746f2074686520636f6e66696775726564206d61782028604d61782a436f756e7460292e01410401ec1830486973746f72794465707468101050000000508c204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e00e820466f6c6c6f77696e6720696e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d090120486973746f727944657074682c2063757272656e745f6572615d603a2060457261735374616b657273602c2060457261735374616b657273436c6970706564602c050120604572617356616c696461746f725072656673602c20604572617356616c696461746f72526577617264602c206045726173526577617264506f696e7473602c4501206045726173546f74616c5374616b65602c206045726173537461727453657373696f6e496e646578602c2060436c61696d656452657761726473602c2060457261735374616b6572735061676564602c5c2060457261735374616b6572734f76657276696577602e00e4204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e2ef820492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203ec42063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e001101204966206d6967726174696e6720616e206578697374696e672070616c6c65742066726f6d2073746f726167652076616c756520746f20636f6e6669672076616c75652cec20746869732073686f756c642062652073657420746f2073616d652076616c7565206f72206772656174657220617320696e2073746f726167652e001501204e6f74653a2060486973746f727944657074686020697320757365642061732074686520757070657220626f756e6420666f72207468652060426f756e646564566563602d01206974656d20605374616b696e674c65646765722e6c65676163795f636c61696d65645f72657761726473602e2053657474696e6720746869732076616c7565206c6f776572207468616ed820746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865150120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e2061206d6967726174696f6e2ef020546865207465737420607265647563696e675f686973746f72795f64657074685f616272757074602073686f77732074686973206566666563742e3853657373696f6e735065724572611010030000000470204e756d626572206f662073657373696f6e7320706572206572612e3c426f6e64696e674475726174696f6e10100e00000004e4204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e48536c61736844656665724475726174696f6e10100a000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e4c4d61784578706f737572655061676553697a651010400000002cb020546865206d6178696d756d2073697a65206f6620656163682060543a3a4578706f7375726550616765602e00290120416e20604578706f737572655061676560206973207765616b6c7920626f756e64656420746f2061206d6178696d756d206f6620604d61784578706f737572655061676553697a656030206e6f6d696e61746f72732e00210120466f72206f6c646572206e6f6e2d7061676564206578706f737572652c206120726577617264207061796f757420776173207265737472696374656420746f2074686520746f70210120604d61784578706f737572655061676553697a6560206e6f6d696e61746f72732e205468697320697320746f206c696d69742074686520692f6f20636f737420666f722074686548206e6f6d696e61746f72207061796f75742e005901204e6f74653a20604d61784578706f737572655061676553697a6560206973207573656420746f20626f756e642060436c61696d6564526577617264736020616e6420697320756e7361666520746f207265647563659020776974686f75742068616e646c696e6720697420696e2061206d6967726174696f6e2e484d6178556e6c6f636b696e674368756e6b7310102000000028050120546865206d6178696d756d206e756d626572206f662060756e6c6f636b696e6760206368756e6b732061205b605374616b696e674c6564676572605d2063616e090120686176652e204566666563746976656c792064657465726d696e657320686f77206d616e7920756e6971756520657261732061207374616b6572206d61792062653820756e626f6e64696e6720696e2e00f8204e6f74653a20604d6178556e6c6f636b696e674368756e6b736020697320757365642061732074686520757070657220626f756e6420666f722074686501012060426f756e64656456656360206974656d20605374616b696e674c65646765722e756e6c6f636b696e67602e2053657474696e6720746869732076616c75650501206c6f776572207468616e20746865206578697374696e672076616c75652063616e206c65616420746f20696e636f6e73697374656e6369657320696e20746865090120605374616b696e674c65646765726020616e642077696c6c206e65656420746f2062652068616e646c65642070726f7065726c7920696e20612072756e74696d650501206d6967726174696f6e2e20546865207465737420607265647563696e675f6d61785f756e6c6f636b696e675f6368756e6b735f616272757074602073686f7773342074686973206566666563742e01e108111c53657373696f6e011c53657373696f6e1c2856616c696461746f7273010035020400047c205468652063757272656e7420736574206f662076616c696461746f72732e3043757272656e74496e646578010010100000000004782043757272656e7420696e646578206f66207468652073657373696f6e2e345175657565644368616e676564010020040008390120547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f7273a420686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e285175657565644b6579730100e5080400083d012054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b657973e02077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e4844697361626c656456616c696461746f7273010049040400148020496e6469636573206f662064697361626c65642076616c696461746f72732e003d01205468652076656320697320616c77617973206b65707420736f7274656420736f20746861742077652063616e2066696e642077686574686572206120676976656e2076616c696461746f722069733d012064697361626c6564207573696e672062696e617279207365617263682e204974206765747320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e73642061206e657720736574206f66206964656e7469746965732e204e6578744b657973000104050079040400049c20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e204b65794f776e657200010405ed0800040004090120546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e0175040105010001f5081228486973746f726963616c0128486973746f726963616c0848486973746f726963616c53657373696f6e730001040510f9080400045d01204d617070696e672066726f6d20686973746f726963616c2073657373696f6e20696e646963657320746f2073657373696f6e2d6461746120726f6f74206861736820616e642076616c696461746f7220636f756e742e2c53746f72656452616e67650000d108040004e4205468652072616e6765206f6620686973746f726963616c2073657373696f6e732077652073746f72652e205b66697273742c206c61737429000000001320547265617375727901205472656173757279183450726f706f73616c436f756e74010010100000000004a4204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e2450726f706f73616c730001040510fd080400047c2050726f706f73616c7320746861742068617665206265656e206d6164652e2c4465616374697661746564010018400000000000000000000000000000000004f02054686520616d6f756e7420776869636820686173206265656e207265706f7274656420617320696e61637469766520746f2043757272656e63792e24417070726f76616c7301000109040004f82050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e285370656e64436f756e74010010100000000004a42054686520636f756e74206f66207370656e647320746861742068617665206265656e206d6164652e185370656e647300010405100509040004d0205370656e647320746861742068617665206265656e20617070726f76656420616e64206265696e672070726f6365737365642e017d04010901142c5370656e64506572696f6430204038000000000000048820506572696f64206265747765656e2073756363657373697665207370656e64732e104275726ed10110000000000411012050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e2050616c6c657449640d092070792f74727372790419012054686520747265617375727927732070616c6c65742069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e304d6178417070726f76616c731010640000000c150120546865206d6178696d756d206e756d626572206f6620617070726f76616c7320746861742063616e207761697420696e20746865207370656e64696e672071756575652e004d01204e4f54453a205468697320706172616d6574657220697320616c736f20757365642077697468696e2074686520426f756e746965732050616c6c657420657874656e73696f6e20696620656e61626c65642e305061796f7574506572696f6430200a000000000000000419012054686520706572696f6420647572696e6720776869636820616e20617070726f766564207472656173757279207370656e642068617320746f20626520636c61696d65642e0111091420426f756e746965730120426f756e74696573102c426f756e7479436f756e74010010100000000004c0204e756d626572206f6620626f756e74792070726f706f73616c7320746861742068617665206265656e206d6164652e20426f756e74696573000104051015090400047820426f756e7469657320746861742068617665206265656e206d6164652e48426f756e74794465736372697074696f6e7300010405101d090400048020546865206465736372697074696f6e206f66206561636820626f756e74792e3c426f756e7479417070726f76616c7301000109040004ec20426f756e747920696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f74207965742066756e6465642e018504010d012444426f756e74794465706f736974426173651840000064a7b3b6e00d000000000000000004e82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120626f756e74792070726f706f73616c2e60426f756e74794465706f7369745061796f757444656c617930204038000000000000045901205468652064656c617920706572696f6420666f72207768696368206120626f756e74792062656e6566696369617279206e65656420746f2077616974206265666f726520636c61696d20746865207061796f75742e48426f756e7479557064617465506572696f6430208013030000000000046c20426f756e7479206475726174696f6e20696e20626c6f636b732e6043757261746f724465706f7369744d756c7469706c696572d1011020a10700101901205468652063757261746f72206465706f7369742069732063616c63756c6174656420617320612070657263656e74616765206f66207468652063757261746f72206665652e0039012054686973206465706f73697420686173206f7074696f6e616c20757070657220616e64206c6f77657220626f756e64732077697468206043757261746f724465706f7369744d61786020616e6454206043757261746f724465706f7369744d696e602e4443757261746f724465706f7369744d617861044401000010632d5ec76b0500000000000000044901204d6178696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e4443757261746f724465706f7369744d696e61044401000064a7b3b6e00d0000000000000000044901204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e48426f756e747956616c75654d696e696d756d18400000f4448291634500000000000000000470204d696e696d756d2076616c756520666f72206120626f756e74792e48446174614465706f73697450657242797465184000008a5d7845630100000000000000000461012054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e206f7220626f756e7479206465736372697074696f6e2e4c4d6178696d756d526561736f6e4c656e67746810102c0100000c88204d6178696d756d2061636365707461626c6520726561736f6e206c656e6774682e0065012042656e63686d61726b7320646570656e64206f6e20746869732076616c75652c206265207375726520746f2075706461746520776569676874732066696c65207768656e206368616e67696e6720746869732076616c756501210915344368696c64426f756e7469657301344368696c64426f756e7469657314404368696c64426f756e7479436f756e7401001010000000000480204e756d626572206f6620746f74616c206368696c6420626f756e746965732e4c506172656e744368696c64426f756e74696573010104051010100000000008b0204e756d626572206f66206368696c6420626f756e746965732070657220706172656e7420626f756e74792ee0204d6170206f6620706172656e7420626f756e747920696e64657820746f206e756d626572206f66206368696c6420626f756e746965732e344368696c64426f756e746965730001080505d108250904000494204368696c6420626f756e7469657320746861742068617665206265656e2061646465642e5c4368696c64426f756e74794465736372697074696f6e7300010405101d090400049820546865206465736372697074696f6e206f662065616368206368696c642d626f756e74792e4c4368696c6472656e43757261746f72466565730101040510184000000000000000000000000000000000040101205468652063756d756c6174697665206368696c642d626f756e74792063757261746f722066656520666f72206561636820706172656e7420626f756e74792e01890401110108644d61784163746976654368696c64426f756e7479436f756e74101005000000041d01204d6178696d756d206e756d626572206f66206368696c6420626f756e7469657320746861742063616e20626520616464656420746f206120706172656e7420626f756e74792e5c4368696c64426f756e747956616c75654d696e696d756d1840000064a7b3b6e00d00000000000000000488204d696e696d756d2076616c756520666f722061206368696c642d626f756e74792e012d091620426167734c6973740120426167734c6973740c244c6973744e6f6465730001040500310904000c8020412073696e676c65206e6f64652c2077697468696e20736f6d65206261672e000501204e6f6465732073746f7265206c696e6b7320666f727761726420616e64206261636b2077697468696e207468656972207265737065637469766520626167732e4c436f756e746572466f724c6973744e6f646573010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204c697374426167730001040530350904000c642041206261672073746f72656420696e2073746f726167652e0019012053746f7265732061206042616760207374727563742c2077686963682073746f726573206865616420616e64207461696c20706f696e7465727320746f20697473656c662e018d0401150104344261675468726573686f6c647321060919210300407a10f35a00006a70ccd4a96000009ef3397fbc660000a907ccd5306d00003d9a67fb0c740000a9bfa275577b0000a6fdf73217830000034f5d91538b0000132445651494000078081001629d00000302f63c45a70000392e6f7fc7b10000f59c23c6f2bc00004ae76aafd1c80000598a64846fd50000129fb243d8e200003f22e1ac18f1000033a4844c3e000100e2e51b895710010076a2c0b0732101006789b407a3330100793ed8d7f646010078131b81815b01000c1cf38a567101004437eeb68a8801009eb56d1434a10100335e9f156abb010067c3c7a545d701003218f340e1f40100de0b230d59140200699c11f5ca350200ad50a2c4565902009ae41c471e7f0200d0244e6745a70200f984ad51f2d10200ace7a7984dff0200a118325b822f0300ffa4c76dbe620300580bfd8532990300a9afce6812d30300109ad81b95100400d9caa519f551040038df488970970400bee1727949e10400cc73401fc62f0500b304f91831830500828bffb4d9db05001235383d143a0600a5b42a473a9e060036662d09ab080700f73aeab4cb790700b87e93d707f20700ffec23c0d1710800b84b0beca2f90800c9dcae7afc89090091752ba867230a0064f1cd4f76c60a003609be76c3730b0078655fdff32b0c00a407f5a5b6ef0c0052f61be7c5bf0d00da71bb70e79c0e000de9127eed870f001477987fb7811000ebee65ef328b11001269fe325ca5120033f8428b3fd113008ba57a13fa0f15001b2b60d0ba6216000d1d37d0c3ca17006c64fa5c6b4919002622c7411de01a00045bb9245c901c00233d83f6c25b1e00c8771c79064420003013fddef64a2200aa8b6e848172240082c096c4b2bc260016a3faebb72b29008296524ae1c12b00a636a865a4812e00d0e2d4509e6d31009c0a9a2796883400e4faafb27fd53700e6e64d367e573b000e4bd66de7113f0088b17db746084300b07def72603e470034de249635b84b00d48bd57b077a5000d0bd20ef5b885500b8f0467801e85a0010f88aee139e60003892925301b066009c95e4fc8e236d00b4126d10dffe730028b43e5976487b00a08a1c7a42078300b09ab083a0428b002846b2f463029400c861a42ade4e9d0050d23d4ae630a700805101a7e1b1b10038e501b2ccdbbc002016527844b9c800388924ba9055d50070ca35a4aebce200805fb1355cfbf0008035685d241f0001a0c3dcd96b361001d07862e87e50210160e852d09f7d330190662c5816cf460110274c3340575b01804be277a22971013082b92dfc5a880180d276075a01a101b0f511592b34bb014031745f580cd701802f6cee59a4f40140ff799b521814026075607d2986350260fde999a60d590200e5e71c91d07e02c0df2575cff2a602a07fd975899ad102a067009d4cf0fe0220dc29a1321f2f0320ff526b0a5562038088caa383c29803e05683fb5c9bd203401dd75d9516100400317e39a06e5104c0b071129de1960480b48c9192b1e00480e8124aad242f05c007ca7082858205007c13c45623db0540836fe869523906c0700f81466c9d0640f09c5017d00707c0e624b301e37807c0332ac78510f10780074ca1e4ca700800d5a9eb8c8bf80800a849588ed3880900804254142c220a80a25170e826c50a00e8d5fafc5e720b801df64e00792a0c80d4fe64f923ee0c006dd038ee19be0d001e90a494209b0e0010bf570e0a860f00da6a9db0b57f1000bf64afd810891100bb5b60cd17a31200f963f3aed6ce1300d5f004766a0d1500e099770202601600103d663bdfc71700de3e2d4158461900ecdbadb2d8dc1a0045c70007e38c1c00b8bde0fc11581e00ba5c2a211a402000407de46dcb462200dea55b03136e2400aaf1f3fcfcb7260014226f63b62629006492803e8fbc2b008486a6c7fc7b2e002cf05fc09b673100da63f7ed32823400f0b13fbdb5ce3700f291c41047503b00422a1a3c3c0a3f002c24212f20004300ac9342d4b6354700cc6ed7a400af4b00c4d022773e70500020017d89f57d5500f86387cef3dc5a008c4c7f7e54926000206207f284a36600cc1e05cb49166d00b42a7a70c4f07300d43a90e278397b0038f461ec53f78200a07264b9b1318b0048c9b3d464f09300007fe998bd3b9d0010058f17921ca70000dfaf7f469cb100e80c880bd6c4bc0058bdcb7ddca0c80038d18d37a03bd50030d55bf01ca1e200704ac01a0fdef0ffffffffffffffffacd020546865206c697374206f66207468726573686f6c64732073657061726174696e672074686520766172696f757320626167732e00490120496473206172652073657061726174656420696e746f20756e736f727465642062616773206163636f7264696e6720746f2074686569722073636f72652e205468697320737065636966696573207468656101207468726573686f6c64732073657061726174696e672074686520626167732e20416e20696427732062616720697320746865206c6172676573742062616720666f722077686963682074686520696427732073636f7265b8206973206c657373207468616e206f7220657175616c20746f20697473207570706572207468726573686f6c642e006501205768656e20696473206172652069746572617465642c2068696768657220626167732061726520697465726174656420636f6d706c6574656c79206265666f7265206c6f77657220626167732e2054686973206d65616e735901207468617420697465726174696f6e206973205f73656d692d736f727465645f3a20696473206f66206869676865722073636f72652074656e6420746f20636f6d65206265666f726520696473206f66206c6f7765722d012073636f72652c206275742070656572206964732077697468696e206120706172746963756c6172206261672061726520736f7274656420696e20696e73657274696f6e206f726465722e006820232045787072657373696e672074686520636f6e7374616e74004d01205468697320636f6e7374616e74206d75737420626520736f7274656420696e207374726963746c7920696e6372656173696e67206f726465722e204475706c6963617465206974656d7320617265206e6f742c207065726d69747465642e00410120546865726520697320616e20696d706c696564207570706572206c696d6974206f66206053636f72653a3a4d4158603b20746861742076616c756520646f6573206e6f74206e65656420746f2062652101207370656369666965642077697468696e20746865206261672e20466f7220616e792074776f207468726573686f6c64206c697374732c206966206f6e6520656e647320776974683101206053636f72653a3a4d4158602c20746865206f74686572206f6e6520646f6573206e6f742c20616e64207468657920617265206f746865727769736520657175616c2c207468652074776f7c206c697374732077696c6c20626568617665206964656e746963616c6c792e003820232043616c63756c6174696f6e005501204974206973207265636f6d6d656e64656420746f2067656e65726174652074686520736574206f66207468726573686f6c647320696e20612067656f6d6574726963207365726965732c2073756368207468617441012074686572652065786973747320736f6d6520636f6e7374616e7420726174696f2073756368207468617420607468726573686f6c645b6b202b20315d203d3d20287468726573686f6c645b6b5d202ad020636f6e7374616e745f726174696f292e6d6178287468726573686f6c645b6b5d202b2031296020666f7220616c6c20606b602e005901205468652068656c7065727320696e2074686520602f7574696c732f6672616d652f67656e65726174652d6261677360206d6f64756c652063616e2073696d706c69667920746869732063616c63756c6174696f6e2e002c2023204578616d706c6573005101202d20496620604261675468726573686f6c64733a3a67657428292e69735f656d7074792829602c207468656e20616c6c20696473206172652070757420696e746f207468652073616d65206261672c20616e64b0202020697465726174696f6e206973207374726963746c7920696e20696e73657274696f6e206f726465722e6101202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d203634602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f11012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320657175616c20746f20322e6501202d20496620604261675468726573686f6c64733a3a67657428292e6c656e2829203d3d20323030602c20616e6420746865207468726573686f6c6473206172652064657465726d696e6564206163636f7264696e6720746f59012020207468652070726f63656475726520676976656e2061626f76652c207468656e2074686520636f6e7374616e7420726174696f20697320617070726f78696d6174656c7920657175616c20746f20312e3234382e6101202d20496620746865207468726573686f6c64206c69737420626567696e7320605b312c20322c20332c202e2e2e5d602c207468656e20616e20696420776974682073636f72652030206f7220312077696c6c2066616c6cf0202020696e746f2062616720302c20616e20696420776974682073636f726520322077696c6c2066616c6c20696e746f2062616720312c206574632e00302023204d6967726174696f6e00610120496e20746865206576656e7420746861742074686973206c6973742065766572206368616e6765732c206120636f7079206f6620746865206f6c642062616773206c697374206d7573742062652072657461696e65642e5d012057697468207468617420604c6973743a3a6d696772617465602063616e2062652063616c6c65642c2077686963682077696c6c20706572666f726d2074686520617070726f707269617465206d6967726174696f6e2e013909173c4e6f6d696e6174696f6e506f6f6c73013c4e6f6d696e6174696f6e506f6f6c735440546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e384d6178506f6f6c4d656d626572730000100400084901204d6178696d756d206e756d626572206f66206d656d6265727320746861742063616e20657869737420696e207468652073797374656d2e20496620604e6f6e65602c207468656e2074686520636f756e74b8206d656d6265727320617265206e6f7420626f756e64206f6e20612073797374656d20776964652062617369732e544d6178506f6f6c4d656d62657273506572506f6f6c0000100400084101204d6178696d756d206e756d626572206f66206d656d626572732074686174206d61792062656c6f6e6720746f20706f6f6c2e20496620604e6f6e65602c207468656e2074686520636f756e74206f66a8206d656d62657273206973206e6f7420626f756e64206f6e20612070657220706f6f6c2062617369732e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c506f6f6c4d656d626572730001040500410904000c4020416374697665206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e54436f756e746572466f72506f6f6c4d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c426f6e646564506f6f6c7300010405105509040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510690904000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f7574206f66207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f7261676500010405106d0904000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d65746164617461010104051055010400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e4c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0075012054686973206973206f6e6c79207573656420666f7220736c617368696e6720616e64206f6e206175746f6d61746963207769746864726177207570646174652e20496e20616c6c206f7468657220696e7374616e6365732c20746865250120706f6f6c20696420697320757365642c20616e6420746865206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500a9040402040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e0191040119010c2050616c6c657449640d092070792f6e6f706c73048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101008000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e01850918245363686564756c657201245363686564756c6572103c496e636f6d706c65746553696e6365000030040000184167656e646101010405308d090400044d01204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e1c526574726965730001040239019d09040004210120526574727920636f6e66696775726174696f6e7320666f72206974656d7320746f2062652065786563757465642c20696e6465786564206279207461736b20616464726573732e184c6f6f6b757000010405043901040010f8204c6f6f6b75702066726f6d2061206e616d6520746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e00590120466f72207633202d3e207634207468652070726576696f75736c7920756e626f756e646564206964656e7469746965732061726520426c616b65322d3235362068617368656420746f20666f726d2074686520763430206964656e7469746965732e01ad0401350108344d6178696d756d57656967687428400b00806e87740113cccccccccccccccc04290120546865206d6178696d756d207765696768742074686174206d6179206265207363686564756c65642070657220626c6f636b20666f7220616e7920646973706174636861626c65732e504d61785363686564756c6564506572426c6f636b101000020000141d0120546865206d6178696d756d206e756d626572206f66207363686564756c65642063616c6c7320696e2074686520717565756520666f7220612073696e676c6520626c6f636b2e0018204e4f54453a5101202b20446570656e64656e742070616c6c657473272062656e63686d61726b73206d696768742072657175697265206120686967686572206c696d697420666f72207468652073657474696e672e205365742061c420686967686572206c696d697420756e646572206072756e74696d652d62656e63686d61726b736020666561747572652e01a1091920507265696d6167650120507265696d6167650c24537461747573466f720001040634a5090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e4052657175657374537461747573466f720001040634ad090400049020546865207265717565737420737461747573206f66206120676976656e20686173682e2c507265696d616765466f7200010406f908b90904000001b5040141010001bd091a204f6666656e63657301204f6666656e636573081c5265706f7274730001040534c109040004490120546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e58436f6e63757272656e745265706f727473496e6465780101080505c509c1010400042901204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e0001450100001b1c54785061757365011c54785061757365042c50617573656443616c6c7300010402510184040004b42054686520736574206f662063616c6c73207468617420617265206578706c696369746c79207061757365642e01b904014d0104284d61784e616d654c656e1010000100000c2501204d6178696d756d206c656e67746820666f722070616c6c6574206e616d6520616e642063616c6c206e616d65205343414c4520656e636f64656420737472696e67206e616d65732e00a820544f4f204c4f4e47204e414d45532057494c4c2042452054524541544544204153205041555345442e01c9091c20496d4f6e6c696e650120496d4f6e6c696e65103848656172746265617441667465720100302000000000000000002c1d012054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e207468652063757272656e74242073657373696f6e2e0025012041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c350120726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f721901207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f207468617420746865a820686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00390120546869732076616c75652077696c6c206f6e6c79206265207573656420617320612066616c6c6261636b206966207765206661696c20746f2067657420612070726f7065722073657373696f6e2d012070726f677265737320657374696d6174652066726f6d20604e65787453657373696f6e526f746174696f6e602c2061732074686f736520657374696d617465732073686f756c642062650101206d6f7265206163637572617465207468656e207468652076616c75652077652063616c63756c61746520666f7220604865617274626561744166746572602e104b6579730100cd09040004d0205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e485265636569766564486561727462656174730001080505d10820040004350120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206053657373696f6e496e6465786020616e64206041757468496e646578602e38417574686f726564426c6f636b730101080505a50810100000000008150120466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206056616c696461746f7249643c543e6020746f20746865c8206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e01bd040159010440556e7369676e65645072696f726974793020ffffffffffffffff10f0204120636f6e66696775726174696f6e20666f722062617365207072696f72697479206f6620756e7369676e6564207472616e73616374696f6e732e0015012054686973206973206578706f73656420736f20746861742069742063616e2062652074756e656420666f7220706172746963756c61722072756e74696d652c207768656eb4206d756c7469706c652070616c6c6574732073656e6420756e7369676e6564207472616e73616374696f6e732e01d5091d204964656e7469747901204964656e746974791c284964656e746974794f660001040500d909040010690120496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e204669727374206974656d20697320746865e020726567697374726174696f6e2c207365636f6e6420697320746865206163636f756e742773207072696d61727920757365726e616d652e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e1c53757065724f66000104020059050400086101205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e2074686174510120636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e18537562734f660101040500f10944000000000000000000000000000000000014b820416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e001d0120546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e00c02054574f582d4e4f54453a204f4b20e2809520604163636f756e7449646020697320612073656375726520686173682e28526567697374726172730100f9090400104d012054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061a8207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e0029012054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e4c557365726e616d65417574686f7269746965730001040500090a040004f42041206d6170206f6620746865206163636f756e74732077686f2061726520617574686f72697a656420746f206772616e7420757365726e616d65732e444163636f756e744f66557365726e616d65000104027d01000400146d012052657665727365206c6f6f6b75702066726f6d2060757365726e616d656020746f2074686520604163636f756e7449646020746861742068617320726567697374657265642069742e205468652076616c75652073686f756c6465012062652061206b657920696e2074686520604964656e746974794f6660206d61702c20627574206974206d6179206e6f742069662074686520757365722068617320636c6561726564207468656972206964656e746974792e006901204d756c7469706c6520757365726e616d6573206d6179206d617020746f207468652073616d6520604163636f756e744964602c2062757420604964656e746974794f66602077696c6c206f6e6c79206d617020746f206f6e6548207072696d61727920757365726e616d652e4050656e64696e67557365726e616d6573000104027d01110a0400186d0120557365726e616d6573207468617420616e20617574686f7269747920686173206772616e7465642c20627574207468617420746865206163636f756e7420636f6e74726f6c6c657220686173206e6f7420636f6e6669726d65647101207468617420746865792077616e742069742e2055736564207072696d6172696c7920696e2063617365732077686572652074686520604163636f756e744964602063616e6e6f742070726f766964652061207369676e61747572655d012062656361757365207468657920617265206120707572652070726f78792c206d756c74697369672c206574632e20496e206f7264657220746f20636f6e6669726d2069742c20746865792073686f756c642063616c6c6c205b6043616c6c3a3a6163636570745f757365726e616d65605d2e001d01204669727374207475706c65206974656d20697320746865206163636f756e7420616e64207365636f6e642069732074686520616363657074616e636520646561646c696e652e01c904017901203042617369634465706f7369741840000064a7b3b6e00d000000000000000004d82054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e2c427974654465706f7369741840000064a7b3b6e00d0000000000000000041d012054686520616d6f756e742068656c64206f6e206465706f7369742070657220656e636f646564206279746520666f7220612072656769737465726564206964656e746974792e445375624163636f756e744465706f73697418400000d1d21fe5ea6b05000000000000000c65012054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f7220746865206661637465012074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c350120626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e384d61785375624163636f756e7473101064000000040d0120546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e344d617852656769737472617273101014000000084d01204d6178696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c65786974797c206f662c20652e672e2c207570646174696e67206a756467656d656e74732e6450656e64696e67557365726e616d6545787069726174696f6e3020c08901000000000004150120546865206e756d626572206f6620626c6f636b732077697468696e207768696368206120757365726e616d65206772616e74206d7573742062652061636365707465642e3c4d61785375666669784c656e677468101007000000048020546865206d6178696d756d206c656e677468206f662061207375666669782e444d6178557365726e616d654c656e67746810102000000004610120546865206d6178696d756d206c656e677468206f66206120757365726e616d652c20696e636c7564696e67206974732073756666697820616e6420616e792073797374656d2d61646465642064656c696d69746572732e01150a1e1c5574696c69747900016905018101044c626174636865645f63616c6c735f6c696d69741010aa2a000004a820546865206c696d6974206f6e20746865206e756d626572206f6620626174636865642063616c6c732e01190a1f204d756c746973696701204d756c746973696704244d756c74697369677300010805021d0a210a040004942054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e0181050185010c2c4465706f736974426173651840000068cd83c1fd77050000000000000018590120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e672061206d756c746973696720657865637574696f6e206f7220746f842073746f726520612064697370617463682063616c6c20666f72206c617465722e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069733101206034202b2073697a656f662828426c6f636b4e756d6265722c2042616c616e63652c204163636f756e74496429296020627974657320616e642077686f7365206b65792073697a652069738020603332202b2073697a656f66284163636f756e74496429602062797465732e344465706f736974466163746f721840000020f84dde700400000000000000000c55012054686520616d6f756e74206f662063757272656e6379206e65656465642070657220756e6974207468726573686f6c64207768656e206372656174696e672061206d756c746973696720657865637574696f6e2e00250120546869732069732068656c6420666f7220616464696e67203332206279746573206d6f726520696e746f2061207072652d6578697374696e672073746f726167652076616c75652e384d61785369676e61746f7269657310106400000004ec20546865206d6178696d756d20616d6f756e74206f66207369676e61746f7269657320616c6c6f77656420696e20746865206d756c74697369672e01250a2020457468657265756d0120457468657265756d141c50656e64696e670100290a040004d02043757272656e74206275696c64696e6720626c6f636b2773207472616e73616374696f6e7320616e642072656365697074732e3043757272656e74426c6f636b0000490a04000470205468652063757272656e7420457468657265756d20626c6f636b2e3c43757272656e74526563656970747300005d0a0400047c205468652063757272656e7420457468657265756d2072656365697074732e6843757272656e745472616e73616374696f6e53746174757365730000610a04000488205468652063757272656e74207472616e73616374696f6e2073746174757365732e24426c6f636b4861736801010405c9013480000000000000000000000000000000000000000000000000000000000000000000018905018d010001650a210c45564d010c45564d10304163636f756e74436f64657301010402910138040000504163636f756e74436f6465734d65746164617461000104029101690a0400003c4163636f756e7453746f726167657301010802026d0a34800000000000000000000000000000000000000000000000000000000000000000002053756963696465640001040291018404000001b10501b9010001710a222845564d436861696e4964012845564d436861696e4964041c436861696e49640100302000000000000000000448205468652045564d20636861696e2049442e00000000232844796e616d6963466565012844796e616d6963466565082c4d696e47617350726963650100c90180000000000000000000000000000000000000000000000000000000000000000000445461726765744d696e47617350726963650000c90104000001c105000000241c42617365466565011c426173654665650834426173654665655065724761730100c9018040420f00000000000000000000000000000000000000000000000000000000000028456c61737469636974790100d1011048e801000001c50501c50100002544486f7466697853756666696369656e74730001c905000001750a2618436c61696d730118436c61696d731418436c61696d7300010406d9011804000014546f74616c01001840000000000000000000000000000000000030457870697279436f6e6669670000790a040004c82045787069727920626c6f636b20616e64206163636f756e7420746f206465706f73697420657870697265642066756e64731c56657374696e6700010406d901e905040010782056657374696e67207363686564756c6520666f72206120636c61696d2e0d012046697273742062616c616e63652069732074686520746f74616c20616d6f756e7420746861742073686f756c642062652068656c6420666f722076657374696e672ee4205365636f6e642062616c616e636520697320686f77206d7563682073686f756c6420626520756e6c6f636b65642070657220626c6f636b2ecc2054686520626c6f636b206e756d626572206973207768656e207468652076657374696e672073686f756c642073746172742e1c5369676e696e6700010406d901f905040004c0205468652073746174656d656e74206b696e642074686174206d757374206265207369676e65642c20696620616e792e01d10501d5010418507265666978386c68436c61696d20544e547320746f20746865206163636f756e743a00017d0a271450726f7879011450726f7879081c50726f786965730101040500810a4400000000000000000000000000000000000845012054686520736574206f66206163636f756e742070726f786965732e204d61707320746865206163636f756e74207768696368206861732064656c65676174656420746f20746865206163636f756e7473210120776869636820617265206265696e672064656c65676174656420746f2c20746f67657468657220776974682074686520616d6f756e742068656c64206f6e206465706f7369742e34416e6e6f756e63656d656e74730101040500910a44000000000000000000000000000000000004ac2054686520616e6e6f756e63656d656e7473206d616465206279207468652070726f787920286b6579292e01fd0501e101184050726f78794465706f736974426173651840000018e1c095e36c050000000000000010110120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720612070726f78792e00010120546869732069732068656c6420666f7220616e206164646974696f6e616c2073746f72616765206974656d2077686f73652076616c75652073697a652069732501206073697a656f662842616c616e6365296020627974657320616e642077686f7365206b65792073697a65206973206073697a656f66284163636f756e74496429602062797465732e4850726f78794465706f736974466163746f7218400000e16740659404000000000000000014bc2054686520616d6f756e74206f662063757272656e6379206e6565646564207065722070726f78792061646465642e00350120546869732069732068656c6420666f7220616464696e6720333220627974657320706c757320616e20696e7374616e6365206f66206050726f78795479706560206d6f726520696e746f20616101207072652d6578697374696e672073746f726167652076616c75652e20546875732c207768656e20636f6e6669677572696e67206050726f78794465706f736974466163746f7260206f6e652073686f756c642074616b65f420696e746f206163636f756e7420603332202b2070726f78795f747970652e656e636f646528292e6c656e282960206279746573206f6620646174612e284d617850726f7869657310102000000004f020546865206d6178696d756d20616d6f756e74206f662070726f7869657320616c6c6f77656420666f7220612073696e676c65206163636f756e742e284d617850656e64696e6710102000000004450120546865206d6178696d756d20616d6f756e74206f662074696d652d64656c6179656420616e6e6f756e63656d656e747320746861742061726520616c6c6f77656420746f2062652070656e64696e672e5c416e6e6f756e63656d656e744465706f736974426173651840000018e1c095e36c050000000000000010310120546865206261736520616d6f756e74206f662063757272656e6379206e656564656420746f207265736572766520666f72206372656174696e6720616e20616e6e6f756e63656d656e742e00490120546869732069732068656c64207768656e2061206e65772073746f72616765206974656d20686f6c64696e672061206042616c616e636560206973206372656174656420287479706963616c6c7920313620206279746573292e64416e6e6f756e63656d656e744465706f736974466163746f7218400000c2cf80ca2809000000000000000010d42054686520616d6f756e74206f662063757272656e6379206e65656465642070657220616e6e6f756e63656d656e74206d6164652e00590120546869732069732068656c6420666f7220616464696e6720616e20604163636f756e744964602c2060486173686020616e642060426c6f636b4e756d6265726020287479706963616c6c79203638206279746573298c20696e746f2061207072652d6578697374696e672073746f726167652076616c75652e01a10a2c504d756c7469417373657444656c65676174696f6e01504d756c7469417373657444656c65676174696f6e10244f70657261746f72730001040200a50a040004882053746f7261676520666f72206f70657261746f7220696e666f726d6174696f6e2e3043757272656e74526f756e640100101000000000047c2053746f7261676520666f72207468652063757272656e7420726f756e642e1c41745374616b650001080202a508cd0a040004050120536e617073686f74206f6620636f6c6c61746f722064656c65676174696f6e207374616b6520617420746865207374617274206f662074686520726f756e642e2844656c656761746f72730001040200d10a0400048c2053746f7261676520666f722064656c656761746f7220696e666f726d6174696f6e2e01050601ed0130584d617844656c656761746f72426c75657072696e747310103200000004150120546865206d6178696d756d206e756d626572206f6620626c75657072696e747320612064656c656761746f722063616e206861766520696e204669786564206d6f64652e544d61784f70657261746f72426c75657072696e747310103200000004e820546865206d6178696d756d206e756d626572206f6620626c75657072696e747320616e206f70657261746f722063616e20737570706f72742e4c4d61785769746864726177526571756573747310100500000004f820546865206d6178696d756d206e756d626572206f6620776974686472617720726571756573747320612064656c656761746f722063616e20686176652e384d617844656c65676174696f6e7310103200000004e020546865206d6178696d756d206e756d626572206f662064656c65676174696f6e7320612064656c656761746f722063616e20686176652e484d6178556e7374616b65526571756573747310100500000004f420546865206d6178696d756d206e756d626572206f6620756e7374616b6520726571756573747320612064656c656761746f722063616e20686176652e544d696e4f70657261746f72426f6e64416d6f756e7418401027000000000000000000000000000004d820546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220616e206f70657261746f722e444d696e44656c6567617465416d6f756e741840e803000000000000000000000000000004d420546865206d696e696d756d20616d6f756e74206f66207374616b6520726571756972656420666f7220612064656c65676174652e30426f6e644475726174696f6e10100a00000004b020546865206475726174696f6e20666f7220776869636820746865207374616b65206973206c6f636b65642e4c4c656176654f70657261746f727344656c617910100a000000045501204e756d626572206f6620726f756e64732074686174206f70657261746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e544f70657261746f72426f6e644c65737344656c6179101001000000045901204e756d626572206f6620726f756e6473206f70657261746f7220726571756573747320746f2064656372656173652073656c662d7374616b65206d757374207761697420746f2062652065786563757461626c652e504c6561766544656c656761746f727344656c6179101001000000045901204e756d626572206f6620726f756e647320746861742064656c656761746f72732072656d61696e20626f6e646564206265666f726520746865206578697420726571756573742069732065786563757461626c652e5c44656c65676174696f6e426f6e644c65737344656c6179101005000000045501204e756d626572206f6620726f756e647320746861742064656c65676174696f6e20756e7374616b65207265717565737473206d7573742077616974206265666f7265206265696e672065786563757461626c652e01250b2d20536572766963657301205365727669636573403c4e657874426c75657072696e74496401003020000000000000000004a820546865206e657874206672656520494420666f722061207365727669636520626c75657072696e742e504e6578745365727669636552657175657374496401003020000000000000000004a020546865206e657874206672656520494420666f722061207365727669636520726571756573742e384e657874496e7374616e6365496401003020000000000000000004a420546865206e657874206672656520494420666f722061207365727669636520496e7374616e63652e344e6578744a6f6243616c6c4964010030200000000000000000049420546865206e657874206672656520494420666f72206120736572766963652063616c6c2e5c4e657874556e6170706c696564536c617368496e646578010010100000000004a020546865206e657874206672656520494420666f72206120756e6170706c69656420736c6173682e28426c75657072696e74730001040630290b08010004bc20546865207365727669636520626c75657072696e747320616c6f6e672077697468207468656972206f776e65722e244f70657261746f727300010806062d0bf90108010908c020546865206f70657261746f727320666f722061207370656369666963207365727669636520626c75657072696e742ec420426c75657072696e74204944202d3e204f70657261746f72202d3e204f70657261746f7220507265666572656e6365733c5365727669636552657175657374730001040630310b08010c08b420546865207365727669636520726571756573747320616c6f6e672077697468207468656972206f776e65722e782052657175657374204944202d3e2053657276696365205265717565737424496e7374616e6365730001040630510b08010e085c2054686520536572766963657320496e7374616e636573582053657276696365204944202d3e2053657276696365305573657253657276696365730101040600610b0400085c2055736572205365727669636520496e7374616e636573782055736572204163636f756e74204944202d3e2053657276696365204944204a6f6243616c6c730001080606ed02690b0801170858205468652053657276696365204a6f622043616c6c73882053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c284a6f62526573756c74730001080606ed026d0b0801170874205468652053657276696365204a6f622043616c6c20526573756c7473a42053657276696365204944202d3e2043616c6c204944202d3e204a6f622043616c6c20526573756c7440556e6170706c696564536c61736865730001080606d108710b0801240cc420416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e009020457261496e646578202d3e20496e646578202d3e20556e6170706c696564536c617368984d6173746572426c75657072696e74536572766963654d616e616765725265766973696f6e730100750b04000cd420416c6c20746865204d617374657220426c75657072696e742053657276696365204d616e6167657273207265766973696f6e732e00a02057686572652074686520696e64657820697320746865207265766973696f6e206e756d6265722e404f70657261746f727350726f66696c650001040600790b08011b005853746167696e67536572766963655061796d656e74730001040630850b040014f420486f6c6473207468652073657276696365207061796d656e7420696e666f726d6174696f6e20666f722061207365727669636520726571756573742e3d01204f6e636520746865207365727669636520697320696e697469617465642c20746865207061796d656e74206973207472616e7366657272656420746f20746865204d42534d20616e6420746869736020696e666f726d6174696f6e2069732072656d6f7665642e0094205365727669636520526571757374204944202d3e2053657276696365205061796d656e7401250601f5015c4050616c6c657445564d4164647265737391015011111111111111111111111111111111111111110458206050616c6c6574602045564d20416464726573732e244d61784669656c647310100001000004a0204d6178696d756d206e756d626572206f66206669656c647320696e2061206a6f622063616c6c2e344d61784669656c647353697a65101000040000049c204d6178696d756d2073697a65206f662061206669656c6420696e2061206a6f622063616c6c2e444d61784d657461646174614c656e67746810100004000004a8204d6178696d756d206c656e677468206f66206d6574616461746120737472696e67206c656e6774682e444d61784a6f6273506572536572766963651010000400000490204d6178696d756d206e756d626572206f66206a6f62732070657220736572766963652e584d61784f70657261746f72735065725365727669636510100004000004a4204d6178696d756d206e756d626572206f66204f70657261746f72732070657220736572766963652e4c4d61785065726d697474656443616c6c65727310100001000004c4204d6178696d756d206e756d626572206f66207065726d69747465642063616c6c6572732070657220736572766963652e584d617853657276696365735065724f70657261746f7210100004000004a4204d6178696d756d206e756d626572206f6620736572766963657320706572206f70657261746f722e604d6178426c75657072696e74735065724f70657261746f7210100004000004ac204d6178696d756d206e756d626572206f6620626c75657072696e747320706572206f70657261746f722e484d61785365727669636573506572557365721010000400000494204d6178696d756d206e756d626572206f662073657276696365732070657220757365722e504d617842696e6172696573506572476164676574101040000000049c204d6178696d756d206e756d626572206f662062696e617269657320706572206761646765742e4c4d6178536f75726365735065724761646765741010400000000498204d6178696d756d206e756d626572206f6620736f757263657320706572206761646765742e444d61784769744f776e65724c656e677468101000040000046820476974206f776e6572206d6178696d756d206c656e6774682e404d61784769745265706f4c656e677468101000040000047c20476974207265706f7369746f7279206d6178696d756d206c656e6774682e3c4d61784769745461674c656e67746810100004000004602047697420746167206d6178696d756d206c656e6774682e4c4d617842696e6172794e616d654c656e67746810100004000004702062696e617279206e616d65206d6178696d756d206c656e6774682e444d617849706673486173684c656e67746810102e000000046820495046532068617368206d6178696d756d206c656e6774682e684d6178436f6e7461696e657252656769737472794c656e677468101000040000048c20436f6e7461696e6572207265676973747279206d6178696d756d206c656e6774682e6c4d6178436f6e7461696e6572496d6167654e616d654c656e677468101000040000049420436f6e7461696e657220696d616765206e616d65206d6178696d756d206c656e6774682e684d6178436f6e7461696e6572496d6167655461674c656e677468101000040000049020436f6e7461696e657220696d61676520746167206d6178696d756d206c656e6774682e4c4d6178417373657473506572536572766963651010400000000498204d6178696d756d206e756d626572206f66206173736574732070657220736572766963652ea04d61784d6173746572426c75657072696e74536572766963654d616e6167657256657273696f6e731010ffffffff042101204d6178696d756d206e756d626572206f662076657273696f6e73206f66204d617374657220426c75657072696e742053657276696365204d616e6167657220616c6c6f7765642e48536c61736844656665724475726174696f6e101007000000100101204e756d626572206f662065726173207468617420736c6173686573206172652064656665727265642062792c20616674657220636f6d7075746174696f6e2e000d0120546869732073686f756c64206265206c657373207468616e2074686520626f6e64696e67206475726174696f6e2e2053657420746f203020696620736c617368657315012073686f756c64206265206170706c69656420696d6d6564696174656c792c20776974686f7574206f70706f7274756e69747920666f7220696e74657276656e74696f6e2e018d0b330c4c7374010c4c73744c40546f74616c56616c75654c6f636b65640100184000000000000000000000000000000000148c205468652073756d206f662066756e6473206163726f737320616c6c20706f6f6c732e0071012054686973206d69676874206265206c6f77657220627574206e6576657220686967686572207468616e207468652073756d206f662060746f74616c5f62616c616e636560206f6620616c6c205b60506f6f6c4d656d62657273605d590120626563617573652063616c6c696e672060706f6f6c5f77697468647261775f756e626f6e64656460206d696768742064656372656173652074686520746f74616c207374616b65206f662074686520706f6f6c277329012060626f6e6465645f6163636f756e746020776974686f75742061646a757374696e67207468652070616c6c65742d696e7465726e616c2060556e626f6e64696e67506f6f6c6027732e2c4d696e4a6f696e426f6e640100184000000000000000000000000000000000049c204d696e696d756d20616d6f756e7420746f20626f6e6420746f206a6f696e206120706f6f6c2e344d696e437265617465426f6e6401001840000000000000000000000000000000001ca0204d696e696d756d20626f6e6420726571756972656420746f20637265617465206120706f6f6c2e00650120546869732069732074686520616d6f756e74207468617420746865206465706f7369746f72206d7573742070757420617320746865697220696e697469616c207374616b6520696e2074686520706f6f6c2c20617320616e8820696e6469636174696f6e206f662022736b696e20696e207468652067616d65222e0069012054686973206973207468652076616c756520746861742077696c6c20616c7761797320657869737420696e20746865207374616b696e67206c6564676572206f662074686520706f6f6c20626f6e646564206163636f756e7480207768696c6520616c6c206f74686572206163636f756e7473206c656176652e204d6178506f6f6c730000100400086901204d6178696d756d206e756d626572206f66206e6f6d696e6174696f6e20706f6f6c7320746861742063616e2065786973742e20496620604e6f6e65602c207468656e20616e20756e626f756e646564206e756d626572206f664420706f6f6c732063616e2065786973742e4c476c6f62616c4d6178436f6d6d697373696f6e0000f404000c690120546865206d6178696d756d20636f6d6d697373696f6e20746861742063616e2062652063686172676564206279206120706f6f6c2e2055736564206f6e20636f6d6d697373696f6e207061796f75747320746f20626f756e64250120706f6f6c20636f6d6d697373696f6e73207468617420617265203e2060476c6f62616c4d6178436f6d6d697373696f6e602c206e65636573736172792069662061206675747572650d012060476c6f62616c4d6178436f6d6d697373696f6e60206973206c6f776572207468616e20736f6d652063757272656e7420706f6f6c20636f6d6d697373696f6e732e2c426f6e646564506f6f6c730001040510950b040004682053746f7261676520666f7220626f6e64656420706f6f6c732e54436f756e746572466f72426f6e646564506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61702c526577617264506f6f6c730001040510a90b04000875012052657761726420706f6f6c732e2054686973206973207768657265207468657265207265776172647320666f72206561636820706f6f6c20616363756d756c6174652e205768656e2061206d656d62657273207061796f7574206973590120636c61696d65642c207468652062616c616e636520636f6d6573206f757420666f207468652072657761726420706f6f6c2e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e54436f756e746572466f72526577617264506f6f6c73010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61703c537562506f6f6c7353746f726167650001040510ad0b04000819012047726f757073206f6620756e626f6e64696e6720706f6f6c732e20456163682067726f7570206f6620756e626f6e64696e6720706f6f6c732062656c6f6e677320746f2061290120626f6e64656420706f6f6c2c2068656e636520746865206e616d65207375622d706f6f6c732e204b657965642062792074686520626f6e64656420706f6f6c73206163636f756e742e64436f756e746572466f72537562506f6f6c7353746f72616765010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170204d657461646174610101040510c50b0400045c204d6574616461746120666f722074686520706f6f6c2e48436f756e746572466f724d65746164617461010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d6170284c617374506f6f6c4964010010100000000004d0204576657220696e6372656173696e67206e756d626572206f6620616c6c20706f6f6c73206372656174656420736f206661722e40556e626f6e64696e674d656d626572730001040500c90b04000c4c20556e626f6e64696e67206d656d626572732e00d02054574f582d4e4f54453a20534146452073696e636520604163636f756e7449646020697320612073656375726520686173682e68436f756e746572466f72556e626f6e64696e674d656d62657273010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d61704c52657665727365506f6f6c49644c6f6f6b7570000104050010040010dc20412072657665727365206c6f6f6b75702066726f6d2074686520706f6f6c2773206163636f756e7420696420746f206974732069642e0055012054686973206973206f6e6c79207573656420666f7220736c617368696e672e20496e20616c6c206f7468657220696e7374616e6365732c2074686520706f6f6c20696420697320757365642c20616e6420746865c0206163636f756e7473206172652064657465726d696e6973746963616c6c7920646572697665642066726f6d2069742e74436f756e746572466f7252657665727365506f6f6c49644c6f6f6b7570010010100000000004ac436f756e74657220666f72207468652072656c6174656420636f756e7465642073746f72616765206d617040436c61696d5065726d697373696f6e730101040500dd0b0400040101204d61702066726f6d206120706f6f6c206d656d626572206163636f756e7420746f207468656972206f7074656420636c61696d207065726d697373696f6e2e01f506013d02142050616c6c657449640d092070792f746e6c7374048420546865206e6f6d696e6174696f6e20706f6f6c27732070616c6c65742069642e484d6178506f696e7473546f42616c616e636508040a301d0120546865206d6178696d756d20706f6f6c20706f696e74732d746f2d62616c616e636520726174696f207468617420616e20606f70656e6020706f6f6c2063616e20686176652e005501205468697320697320696d706f7274616e7420696e20746865206576656e7420736c617368696e672074616b657320706c61636520616e642074686520706f6f6c277320706f696e74732d746f2d62616c616e63657c20726174696f206265636f6d65732064697370726f706f7274696f6e616c2e006501204d6f72656f7665722c20746869732072656c6174657320746f207468652060526577617264436f756e7465726020747970652061732077656c6c2c206173207468652061726974686d65746963206f7065726174696f6e7355012061726520612066756e6374696f6e206f66206e756d626572206f6620706f696e74732c20616e642062792073657474696e6720746869732076616c756520746f20652e672e2031302c20796f7520656e73757265650120746861742074686520746f74616c206e756d626572206f6620706f696e747320696e207468652073797374656d20617265206174206d6f73742031302074696d65732074686520746f74616c5f69737375616e6365206f669c2074686520636861696e2c20696e20746865206162736f6c75746520776f72736520636173652e00490120466f7220612076616c7565206f662031302c20746865207468726573686f6c6420776f756c64206265206120706f6f6c20706f696e74732d746f2d62616c616e636520726174696f206f662031303a312e310120537563682061207363656e6172696f20776f756c6420616c736f20626520746865206571756976616c656e74206f662074686520706f6f6c206265696e672039302520736c61736865642e304d6178556e626f6e64696e67101020000000043d0120546865206d6178696d756d206e756d626572206f662073696d756c74616e656f757320756e626f6e64696e67206368756e6b7320746861742063616e20657869737420706572206d656d6265722e344d61784e616d654c656e677468101032000000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c206e616d652e344d617849636f6e4c656e6774681010f4010000048c20546865206d6178696d756d206c656e677468206f66206120706f6f6c2069636f6e2e01e10b341c52657761726473011c526577617264731854546f74616c5265776172645661756c7453636f7265010104021018400000000000000000000000000000000004982053746f7265732074686520746f74616c2073636f726520666f7220656163682061737365744455736572536572766963655265776172640101080202e90b18400000000000000000000000000000000004ac2053746f7265732074686520736572766963652072657761726420666f72206120676976656e20757365724455736572436c61696d65645265776172640001080202c108ed0b040004ac2053746f7265732074686520736572766963652072657761726420666f72206120676976656e2075736572305265776172645661756c74730001040210f10b040004782053746f7261676520666f722074686520726577617264207661756c74735c41737365744c6f6f6b75705265776172645661756c747300010402f10110040004782053746f7261676520666f722074686520726577617264207661756c74734c526577617264436f6e66696753746f726167650001040210210704000425012053746f7261676520666f72207468652072657761726420636f6e66696775726174696f6e2c20776869636820696e636c75646573204150592c2063617020666f7220617373657473011d070151020001f50b35f90b042448436865636b4e6f6e5a65726f53656e646572010c8440436865636b5370656356657273696f6e050c1038436865636b547856657273696f6e090c1030436865636b47656e657369730d0c3438436865636b4d6f7274616c697479110c3428436865636b4e6f6e6365190c842c436865636b5765696768741d0c84604368617267655472616e73616374696f6e5061796d656e74210c8444436865636b4d6574616461746148617368250c3d01310c","id":"1"} \ No newline at end of file From 7760cffed18821fdb35b0ea73dfd386daa16092d Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:40:14 +0530 Subject: [PATCH 62/63] chore: update tangle-subxt --- tangle-subxt/Cargo.toml | 2 +- .../metadata/tangle-testnet-runtime.scale | Bin 398583 -> 392133 bytes tangle-subxt/src/tangle_testnet_runtime.rs | 2950 +++++++---------- 3 files changed, 1265 insertions(+), 1687 deletions(-) diff --git a/tangle-subxt/Cargo.toml b/tangle-subxt/Cargo.toml index 3fedbd3d..0de3439e 100644 --- a/tangle-subxt/Cargo.toml +++ b/tangle-subxt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tangle-subxt" -version = "0.8.0" +version = "0.9.0" description = "Rust bindings and interface to interact with Tangle Network using subxt" authors = { workspace = true } edition = { workspace = true } diff --git a/tangle-subxt/metadata/tangle-testnet-runtime.scale b/tangle-subxt/metadata/tangle-testnet-runtime.scale index 7dcc96d908d8e378b763acadd56f30a5b7661f90..75801c341f71bd16b4b93184bd5ccee1aa79e04c 100644 GIT binary patch delta 50210 zcmcG13wTXO_xGNeo#aF=5^}%D2}uY^BqRiJ388|x(^48oa>%LNQuNSLm(tRryrre3MQLd%T3TA#?>Bp&lMC(p{r}JNeV!v{&z?0iYt~w`X00`s z^ZUA>{l5pg6|=Mei!NQfyp*t^*3vRt;aF8Upe4Ju6o=SqGXEliwP#!t#YuLQ*zY1r`^Gh#UD5t> zoyokk8E&bpO55eu26f%W^D;`B#sjrprp9I#xu6rVzt6g?) z%(iRZ^_sK&T8Dbk>IsHA^6DkBbJ|Pw+NoC=+d>wL8m`@`*NENHLOfci9XXq!_4bHL z2pedfXer4pRh0ppO)9qJ=UdCNON@8z+jp0wNgG&RSY|7*c2ZKbLXU^pg3Sj!f>a=T zu6{C`vpL9T6>B(+rDoVli!Eh2c>}Gb<@sgm7VW6-NH$CJ9T&in=+&Sr67w4jKo7oa z(C%Lf#0#Mw(5wvyB~4RJBhr^>77#R^5sCh&jWv8`oB7T7wOg$<>w5#SUwrz9A$i0l6 z)p(Qf?28kNIP_n?>&`1?-G*TPF(y?J3%JBPURY2F9W zFE#JUmv~bD?P}<&yaj;i#@7&zMsYEID_L@Sd0AdjiLI=nkFB%}eVn6>h>K@SwB2zL z+M96=Q0eZtp7mEM3SX_PM!sonqOw+tjBkhfN5-#XJ2dx%0$^5=@F?4;eVH&8Z_-;9 zxt~lo7nhIDx8-Q(9%-l@X&KL}(rG}TOGE9)N9rN%sx?k*&9-QdBo5^3(*YE!9ZYO* zJT}xqlDdL}*-67eksV3d?1I*))x0`29B!4!_AP8(%C>0}S~tQdqSiTJ{k_&%pnC7* z1h!lAP3a=M)#KWpCT^VZ4No%GZOOM(7VW%S~q*Zn42F$+d zG5};hmflnwl3t-d#p3V1^zM$g;ot~dXFqY;WHhVgW%fn+ z?U^r#3(i+Xy_!Q-mh}pEza)_~Cn{HHq^g=Vj~4FQwO)46c3tm>*>#HehBelr`-Fg* zUHaT*H#c|AYR@p%p6WZC9o>AYZ+!*@@l!u`x?f62q{1I_}oW&!_CdYabCs%oUYG}wpT*4`SNfKmAE;4qiF zisE`xQ-|CH2mc)M3c9#*=s7lP^Nff4G1q13=0fX4ZRGIA+Py~xu|wLRVR=C6gJG3G zW8m#m#vpmmMZ~o2FK;r9>W5p;h%}JKp_Kn<9XcMz_8C$Y>mo=7wTtAIT zWEVC!8k+}^+dMmO9WyOSHy2n7Mq8jGoi`C#Yy?85K5Go2nq?AwcW2Ng}?i5P4LwDuoAf&SY+wn4C)9H_t`dig+@_IUBDptsNX0rtT)%mESttkTCrx-7O7h->s~pt2S}__uy;{*!t9arIJPmxZ z1B76~la-9Erv*%n*9J`9j>*ky%2S~5oGGPjpT?(7MKv>~%HIDqwFty3o^}v&ls0{` z9CJIKehX+8JaYzp?>%EY$6UAT*)NfiKFd%0>$!TG{kcTY!${o%s=v+ZjhQfG_B7Wy zx)4zREY(jtJG(2JO%Z2!r1tF#i7HbMq#GFvo*z;xqY(=#(dVlNCNPDo%c_gGYm;8+ zR#U7MUs)?F^yPY5+MGx>TN^cJ5Sy#LJExU52;kE*sZFB7Fa|5NKjyS#OSQPUP0^2` za|f|XZT;NPkVTA{A1zPqU~ZK-Qc)IRE)#y3+)T<+Eo(uL_V--h(B+K9b)RG_8&sZ? zW3}cY*AG))5hlM?TFZGsEjBUMOy&=S5mQp8aK*2OrOcAADq9(gk{NnZ5sI>0n=~(j zt$K|&{C&I>bCzXN-=e}CtKzLFYc#$fDtsMNJ-Zc6R5AB%V3=O< zN74VdaAgyai(^|+QGm8^L3;2iM@u?h5`%tac~&4Os}F)*;!)XLYg?J-Swj+-1FIJL zX;hg6LVQ{|swPXQw~-aDJ+iPpvKB3TRtwk6ZEH$8?K3nfm37ZnDQ!9_%m)g^lFIzL zR+L#w6=e^Q<;lu^?J2DtJE(2bQoWBcedrX(p~DsJT#Lvy2bn3YxWraqE3-|oW|vhI zTT6Y0pgw3n<*?3}Hpv~#$zaT3$rzXzN}_U1%dTq4PH2@?53^I+PgTt^=z|tz;JLCY zh!XzfuG-{90ql&ncu^uh!>IC4o}k@ci`)4>C~}IrLmR)ilwH(*SRCVV znK94uq&5(t(^?p{h4C@XUHEI`$O`5CIX%lR(s(A~v{_56&d0E&sr(|-BGn+RcxgxX z%fQ@4Rjx8RI!#Bs4q`;q?f+@g7GBkqbunv zEhw74GFtm&Wty};@RYEsp7!@Eomc~{)2qW-Lv87+E$<&JU%eV9{M0JVV|50hT&M7Lfwr_6?E=9S;XnIFj0YlfMpoMvBGN2KX-VV^-daa&GQCAxp zf%Os%wFa+A90t5r1L29Obmwa$*;+09_0HAhJhW-Ad-6L>oA-JEl;Z2J_g7swOvrn$ z$3m~hu8qOpfor8%vTCigg&eKHa-F4ltQ!Cgm%Xls!h1F#}7H((|n8I0xllH_W74-g*L>Kk4nF zn#N4E@EM{-ZhW;mtDg45M#+GLO^d3js{OLb0v-%~XO-jCJCdwjH@E&L!SK`tBU(GN zxj%T4xaDncFLh3Op}AkNwM0&vT9++Bn%h=KCMLcan)kbr7&}LcMYz`Q-C)=l`_Ln0VwiTz7#Io83JlCdDPqTG{8 zAzjzjj2rOZ+Q)c6KPudvEAHG!8(h>mn!JK*8+9WIPO3qa zc6NI!FHglsx(TY{eByGbyrQ6pPimy*DMo3kbTnE57opp5iaRJd|Mh<*9@_ zkUsK^2<4HSB4-MJ`F(Dh>QB>1jpxyh#L8qfG{Bv!gQT{^=m^p!x09m8)&gi7?*K@u z1rU#>R8zR5Q4$_G(kb#=QQFC`Af+Rx^j)GM{k&Rr)7tNNANIlR9d(T>almY@YhIn& z-HEYuEokq!{~tzHci27uYGh^d|7K)ugprlO(>ZM-H9}Jlw&dOQ=U}bx!On)s#WOjD zX=;qt`e2MEJ{jUWfP1Faam2OCQ4M|lQXQUpw|onn@m$Y^t%6O=PapVFCHvD0(ITk1 zqAqj5ne!|Ytme^HYoR&EC}JL6VYU>SErxp0QddR#`>VJ7 z_Q?=;ii|M1p2xhcz?}%y`qf1e2DB|j)6lm=~9l^(Q zZM=uSw&BwZ7^ycu?TUCnyF()xE7$07S2lU`SBD>$F2F;deE|>Ce6){@8x$RD!{9=# z{m)J2MK^qT_aKQx1y}Ha$fu?%ljVz4WxDpq=OfgaG6M71@g}fceZELYoy`?b7F1YN zQeerS&6%8~am$cJuf^*qoUs!tvL3BFuj-XQ};)r6Za4 zu+=s;uMDGduD0StGz_YbPBaf&#MxkY5zc50q^Yztt-N(BfGq+h7TBp}U!<|++U75s zvkltWFT(Km?=K#O={WMsj>)TdwPm=5WANh-j7Hh9bzH#*J>9^4lnrrwIPsJEu0mO&{~s_ZZ#%zU~TZvg+&g?6}tL^lG+`ETdTq%KnYJX<=v9 zgG!&C`5t*&zG-6+HUmawt8e49QQt1a|0pf!>_!AQK0O=H4#}dewS;rtY(MRZVL{r% z=L(I-U>Bbp1h@18p66{&&^OO}qk$dgJ3Ff8JGpK>jrh*ndr8osiqbM`fvUg@*`Q7T zVT5+_y9jkFNBc7I=!I}~JBKkX6Q?hPsC%4X!!I^c4|4QM&$$?;9&>_?_&!v<#n~o3 z=j-nqA)e?+Jo^I%=K$VB?PDaSyExG4 zdBd#Eb|wzp2vs+^K;k4iy?+T8dt8{d>8Fv}pf{OS;3iC^e7L-oMvU z%lsqBA&1)HKavsGF#jH}{qaWwSdsPrOn@rs@@I2|2@3ukkMN0h?(V0EIJ|u?4>otm zUtgY^x)Wo7Ix^=GUp9ra+oCIlUzgA=@nyRi%m!MEdC2<5l|xQeE@ zvCXy02T+cQy@uemr#nljQ_1M^l0sCnlDY)5Q2Q!(_B5+qPMCTgr9BN;02O<%$!wYZ zx(7={h{Ar#hmBw~)tj}e4NgCLv+Z@E7C7s3^~ptKT_5AYvQGh`UY{+p?!9aYt$3XU zk=c#8y60L)+hn(@>~A+@2m>CspY~(39hC&pv;ffXCM5;3dFV2T(VPlHm>cLLJ3zic zte=5Uknn7FiKYdiY;Cv&60S&iMO~+JomewE8^XNl$6)qwEvSKbM!|5Ind5w49LlmC zHPerwtO({QT5rM=mQhtxu;h&}HpD>+H$O`*n6sZEUqZC9Q#jBwRGaWg+(*`MHqBY7 zj{0i)pec)mx$-0GK@7&P8C2==M(ieJqbh>UVRNX7nMJW}I`8eDz}#f?Y$WT*rcr)0 zizJUQ))%W3sf|IeErx*n9L?I&hmBc@>$V<6B{^0a9}VGnxCzUwRn5zY8p#?Ssa47; zb*3O&X=%B&#NgMz^=K4W7uA&YxQ`e>rcRga=u#zTmuPKs$X6{9u#afLE@JdJNa;mM zt-!0&Otx>M+vN+6P#MMV%;I?of5$eqt1HfTx-5{EKC!F-uA1B zEbJfPQ)qoF*2X9lLVven9(9mPYs~`W`pe5LS%i`~Z| zZYdD2Epp^V_>`K8jG<% z))sh!>qk@Bc$X@~?MmsKAM>LT?bsvyY#BY-9ujz>9dyNAy3v3|Q&4+|hm%yhDZLr< zrz!2x!Q-^NJp|S0vj}fCOSaj>XfBB+c3{K#X)|qW!(!>L4r~DANgpc(Y0TX~27+rp zmc}3tIyz11MGOr`eRQT1d(#k_2zsM4s}GW+csQNv4E3d3O&I{~(}h`>jo#|Qdi&N1 zoFE8uki64bHz$c3bz}ZQ2|G^DrL#}jMjFx;B5v@nj*0->irQu9YBwmrOO%_zI`Hd{ z(ynx9rR^Dz5e&3mJj7nVJ3D|NE)CehV%-PX#!9`Wth9SS#1K?nMxAJ_2Wh> zdNLohzo{o1#ZqYMr`(^KW?*~d6yc3-z*|qx&o7#2&6Nn0%2mRvx@nr2sN5j`p{$(W z;&QPqkk$-k$?6@B6(Z0u0}3$aVKy9-!nH@h;oFjY{SC_1hFSQ?eJ}%?cRFKF-0^B?sep8`*O(WDH;m&t+>2sE)*~C{aaCu~Ngl7LS40 z%%GlQoYQ(Rp?C-#9)rc@OO!g6bpZQx=i{@fm}gfTt$s9?z2~fNcOJWiu?uXVPHoU% zv*-sKOLMY2mTZp$>v-B&4CVXo;~416=<~;+o2OCtaV!$rb$U5#LUYEkDZXHDRR5Bq z;!KR3NnqU;3eRVD2;!IdP;fR1EnvauTH6AakFVDX(8B||K3aT~*8_pP3o$0pokF%1 zf+`gi#TKyuel(tZ3RxT#6|rO|D%*-MeOxktx)iep1|oqpe>_yh^TjOM0DP8Rq3b2E z7=q`q`XWKm(bb_!!I<|;SsUt50_!23MwKudI(4W7ow_8;bf{G&fb9Uzf;&te<;XfJ zA(~KrIagdV=hqiJDX}vqNXos0vKz?Py#DJH`&!J3oP-9jmfuJjtGt6Yz&mF%1M9HkoyS zq%51v=CafFxG9*njJK`m@u}clt%m4}se0wokrZBGD=A$1=h(P^tfLKWp9LePqy73USarZe7bolU ztRX}T{0g)$d|p~hHd_7y8)G^OG>Rd*^!5rKLU$%IPxl-P7Lf82lnc~p4lKysG=B~Y z3rrU*%@K@1n5n0wG_RA=AnhdWn*$L)WUn`ujh5sunuq!CCasmqh0OEW z4Cla#ryu9Dc-Ng=?a7iTVgdM&LYWHyoJ0&j!-KNo?g-|MI>63+UbB^nxYhSFv6@r*< zs$w&t7}_mDAJ5YBiy$#)X}|nhvUo9Thwy?Q^;^sud0=#VBC4V=I0sKG2BK@}y~S)G zSXQ4{8@E}YVAd!z9a{uN5%D6VdMyKu1i>FIpUYFrBFf_marD$ ztl6wr2&u_h3aQyg&n;z1pym5Z(dJ$HbE$4hjeHS8cb#Uuh?jHh`(9-4GKkdAtwjK7 z%V1ipC%5Hn5E_4UIfjSLzHB+nSa@b{tY9DT2O2p*XIFt?tI7Wrh^=9j(D}DuV=R6J zDsLNo^(uzNkyqF(jQnA*0s~z_9XZvCy31;`tOH~bRCcgaj=f)J?rN5RaTNYKR87em z7Vew~4#^Q0MCaCkf7dB;EgOnHKCzZPLK|Ph{BH~dQ&5>6rFRUAI@M*?(eRg~uQ;u` zCOc|!=j^uq**91WceZ(nzF*JUV@x#Jz(%Y4IZWQU8`xuYDmp+--eONUr8SGbdyCBz z14PXplL&{n(Z09Q>9h9KjST9^p=>_e0;B4Qci=a!rQ`Bz8zpSkZ9sh(BHNYbZ)UB* zpAR>)bwI3W3v|0t+Ky~2GOebcwqocGp_F&oC;YmZrrKFBh1sF}=Gb4dOV8*mJ+mDV zfzxz&J9`ea(hc45@3AuwY&%-A%0>I_J26{rljFZ74gY|7qqpNefbbYx=0gNE`UU3J zjSpC2eW#4Wv>GOyTUv(hVoB;q$-TL|Ser)iDtly5QGU5Jd-|0ODzp@r<`tC-;5x_{IrF+5kjbz`;;`zx8 z+I5}<(%*Z*c1Xg9z&?eZ`w#W{n$m z6fDl6qVy=J>NAZ-e9X#0-s2x*C>b3`ZH}EXRCa**bhHSBYt5yOj#&i5QV8=am1~n{ zS+a90&mft``w}eYA#ScK1jPbNObw#153rD_Rv1PsXhIRzty_(+d2T(k<~g~t<~e0~ z&2yV|HP3Cg);y=~sd;X9SU!j8^(Q5ss+CB(C=*j1S*>o=%4&VDRwCIQK9{qG6#rU@ zHjzjuvIE>E6ntPe+IWFb@KIc`@+|wq%Y}lEqI%kRg+NY)4p$&13k4rn#dW$+rjzd{ zEM}^6Jxr0E=d*=^k6v)DEI1bl0YQ^BNQ&@9LcvD|SSkUQN&x(q0Fq36l~C}}0oF)> zH4;GL41jeKV1rQb(E&Dzf~i8;Bq3Z3h^-Q0yHN1aA$H0tc1i$O13;3Q?-vR_I>12* za8Lrc832bRz%ilVqXV3f04F4XjEe(_Qxf2eQ1Ai3R2x4hAG6Ljv3q3O+i(9SLwp0(ckz_ap#Q6?}967Zm{55}*iA13>bZd%+cW%mLvm zA$%o-mjNM}&VyA2AH9lj2@oy;uw6vC={PTMFmz>ISW}-loZ)sJ5|94GN*J@m5vmC zm}QBhm>kC+MzkWGDm{1vZ8?niqOoI*+>gKlo?sWPq z79l-qybYj+U&E)-v*yx-Gps(H{hBR+QBitYhG=QaY0RUwvJEua(VjC1@$91&-?CQZ z@eT7edJzSysK+<#h64(Y&4h1Z;Ow&l4#xHz`uQyMyxx;`)tR!ABpP=f)~J)t?m-I% zS*iJVED|>U3}Qbb1hMjhj9s2*EvhY-dSRES@ptIi9LoLyB;q4O76nea-@q#c*xaLo7~>UkNxEx&ZQgQ)ND zk8m0e{s3?zq$0dM4^Z+YOoTc}B)xD6CPocjDy3aU1h{tj;XauvGt1R!UAg=ERZ+X2 z5JXr)qkm$*u}k(xudwyfJ*f9H7VGrQd&nu9!6ua`b2&NgX{41CU z7B~JZ2&dD?)x>)lTNvqa6NKMFlT18TwW=^|&i%q0(l!%+0t8EO=Q33CoI8I(hEn}K zc(h}J_3180^?t5o%5NVfOAg_Fl<3Lh$;*>Bp=a?FGXz#ObV5-vbb=?soT`F1a;;Rs zZt;Sm30Aq0V3;f#7k%@7(3=lHj#Le=L2hTDpDR>1uasI_6)a@-;?d2mb(E4#eLySO zfHBmPtyX3J1*)+(V!T?jH==;Hc=4`*7=`BUB^JZ&SH{ckVu`Vwyu5j9Rzd0BJi`5g z4B^6Yw9@JNJccU0`C!P>C2yVtA%txfMyd7rV%SW_>Z6d6V^8(ruFzPN?#pLFIu82s zrViqY3e}TXM})ijHQ-_H2-EFL>uSM9)SV4@f=Ad`1e$Y;Eo)Kt)&{&A1pm(lye*%s z(mh{TDt#Jq8I{%DV3D!SzOf;~Dv+2Uf8GNEVDaa@VVQ35=j9lB(E&Vx?;cD~Me|@P z4&X6tB`pnr7_GM-58xK8RZ(gXFJ{weT@a6e7@@XqdcVs&OyFte|#qhzRAs8LkRc_>}FnFzoRZ+L* zyaa-e+Jfk4bDjpmd9~nS4)Rh)3;qs<;eeJrjQr#Hln3f?HD95%aeS5&s9!v9gF2p# z2Wbz{kMTSi#EMLSP|PuEDNW#=0kAoN`#JBtR>G@yg5XzT`PV7mbu!R#{r~u zYm~Cl)C_LEk67Qe=7Erhd#!ma>PWXi@efSqWAQw{3&iE~WIhc7^;Rn$#}n35dgUhVlyApe`~LH^Tp zu02$qmwiMB{u?tb!=`R*gqc9TJ;3>S9k?5&UN4%`5v;sT?w$C&y6wl&Z=IkUjrQ?X zOGt#8v4AQ%Blk9~>J08W803TPR(9Vm+)qwtb!b>c&!+1lEm?xfeof~?KpBv#2^Dtb zd+JveTWq=J7;{d!zK4!(*kQU1?Z&&K?iJnmh`JRHs6lIG270`NI(6q$F?sIp&NIOR zd__`x4+ysxJ>COya-BBG)B?KRgICn8s|8mb!*eeA^n^GXdd5DcC&#k)ar!Ki%QaZ( zszN(;>c#J3uyyQ>&L1UfZ)ip2VPVviFL$~)Rv3fmc5j~PaiE9QYQ~Bi`bMlb#A|FH z?gNytH75fB_FaAWW^k!Ii_3W6wk+`MB>kKPejK2RzPuG0c&jgeh%ZuU!FnvcHtfgW zz-sjFemsgJ?}q{WWdqq@`zr%E7TVWSmweuw0tWLu5MlaY{yQv%Cx`G!ssoPd59dE% z(CA=I9_1R42_DQdxUz&IhwvD#T%ypEata^I8{wm)3@8axlR|6af!)>i?G_&~Of zUMu2nqs~W)`7O5A-hVv*hSffk(ZH|D-lbH|SI*sn4Sm)kR3l!rhm}iKU9pdtz~@Ty z>&irEI{j=$D+u3}_e3(CoCK|TfKn=Sf!8P7z^GZYx&p*sO{1RT%@NY(LaxPidlDjM z2myWcBqz4oj{E_#;w_WWkO5AOreM%Jo)=HyYf(~{{Y7+cD#Erar}9o<44!*|3;1fP z8(M6Y{v7o`FrU^KrN-_OO+X#J($>>?0oy>YPUpkbO)6-eJ(CYaG&6>#KF#}kR&~?E z#QH8on*KBl!|PA;fps9GXzw$;s_rYHs%vT5)8O=PGq~lxJQsC={q#((o4JRc<2bCd zz>e<@jMyAV%3A6;hxZ4u7tFyhagbmWndb7Qe5*<$+p9tL-g9A!Kp7OwgEGHMYv=K& z5fY1^kI51RS1;g;{Pr-G=-8fZgt1l6eKeqwSBI##Q}{wY3gUrvTQjX(2#MTHn-+o` zyXC7y@D`~6dR*h-4m9Y92DP|{ysCH$b-#+Hx>R9!-K7~-Q0uekqbf{S4vhCu(jvZ+ z?^m^PPsPxmi%>mg(D!)&$C7x|V$|ahh$k2G#;8J{2R~WN13-Z97Gol_VkLj>zZHB0W$vuv z!gZT*lv68H$f$san|*GGTUOm zxE`~*qqKeKTT&l5Na&;PqmSR_J)Kpz*a)^-sP{%liWe1bJKzah zX3yRXTN1Lncne&@!}P-zo~|BKF^MN`#PP&HAu~tRELuWS|%o{${F2p^Fbm>RnAFAOp%FJs&Wwtp(k2n zqrR+APb8~KPwbS}pAm(+iVRmhf$jV^kZ{uzZB^wK5+*&7io;WKH?q5)Ldfb4vg#>* zvQeOL4=E2L1soWHkDf*fNVp*7Wu$GU-S)(o?O0On0Orj1-W`q~6>3BU2@B5WAFQl$;Sj z7>_z%WE9w>b48E$nsh$saa)tl1wBG*(s`iAVof^D^_Z$jC%7IxHR;sWP@MS%V&DJcT= zM@dEzq(4d;ieUXQMLve;kL{+)=TQAwl1_x_kCJX8Tz`~A6OHu8O!*k0KW5>PpTJpu zm)e0;?4i0pk}3rNpCJ-{n2Ums45gk@m60x0nK>Rvh7T%nC0!Y(;V_devw_Sbjvr z5hd@@C@#WGr=Lw;0G_{d2Ihs)s2!b$n^3!v`QL)!bsF(bj5qfyw3>0?x3DZ>27P!I zG&GFF*qL>P>g)%H{cK~{&!$P|c!!2_U0B>;xyjTxvI7+`gFZQ@4_@6-m`gXlgQ?d0 zJUCoQdFMgWRW#>305;I3^BB362Ec{$Jgoge2$X()mPL)VlxAZ(&#~V3E?=Iut$F7- zDYS_8e2)m&L9%?un}jZPVf}02RHHPMMMh)qeaFM(QBdP}H72KSC01hFYtu_H~0qAo$t9Pd`{C3yo381Iat@ZDC>-7_Fd$m z&4Fnc3_NW5#WuvmQk+n{locif^Skm*B;0r}dW*YObW@%dj2)_eDeKugi$sR#MrIdZ+)lO@~mQpQ=5i zw5@f7A4I!<&O2xb|8`xax+pvGt(qzsj*IUheuek)swOltj1k56yJ(ZOAbS4_!n+6Q z0=|5X)jCVgoPaop;+actAA^pbdKH8CuzlB6I0cS@>3&$YS;>@R)bAQ^%TCbxYdqK# zR4O+Xm*}Y`>=eC!iw6s36yjvp5a4o52RH{6M%mX9V5_2Y*YzlKy&ITtPSTOz`70iZ zIc=hG%~x(QWqmcs7vB(na(+oQ@?eu2+-k-qr_QG{F6?^lFDvC-&Pu()Qnaihb( zLWr-^>0g2Jbqc)+g|FB4!GFPYg0lu7xEg)}aEqoEzrzLIP4j*S2~OI9pgZo+G4Q%8 z@hSmIm3I(GK1J*9@WJfV;y)0epJD8E?)3-Uk`t8w2OJNB{LN3);pwRdd3ws==_wa& z)S_@o{*y$YsyGxU!mhMo3`eNhl1S}z+b75Tum9$DpNorSe$Xnq43?wb%PuubOardE7^^}zYPl;{r5Jh! z1z~5h6cQwF)v5Z0Tm(?0+HfbX3mo$<*_2@Wu$Y(%WtbI~rFE(B{AS(3+wH z!PAjkm=|po3m=3|P}dGAETL_G^BBYujG0ZgM?PGP2jqE-R^lNnF6-xnmL^Aq2PAUBpQ9;ir1yAqT1KeLX}gZqVa3$2-EiPfVQ+7T#1kbOM@E7ey6LCv}_ zogzdgxde+)1bzlI68`@JQ$;U@2)Q?)Wq<5K{3%348}-OV^ZZbuFHFfMuY`)(Fgbxt zFz%x8UmS{XvfkiO&n3;xqsj|Q%Pixp*;E+?bY4mj4Qk=~5#$;uWITxB+vqYn(CxvT z%=*p77G>i^L%yxhs+dw|7zp->M2G5h6jIr+vA|6a20%$;P^B)wX-aJ(I(y=PM4dCz z`a$h17H6GMkZmzc19#WziB?{0fr&OPzbI#1b^(rD+lupT))FsQ_K0ID?t`4H>WofG zy^L9OqKS|jGB>ryN<~zZkTKw-7}1!XjRJp`(7C1}3HJ73e-S}ET10@!QPHBGaaV`L zrzaSyi@?v(q6?l;cnAo&Bu=E!hcTke?*R-w)0Py*};J6lsXHczKj8RGH) z>>=4w1g(t~atn3wEb#F2Sn+bL!t_dW;jj9;V!~UHh9P;fIR?{Ry3-u!>m7a={Yz+t zoZT&i2cA)(KYiB%9X?5caUvZvTBAT@PlyAadY2B=s$SIZd4Lwhi>}VfmKl}xOMr%~ zGAb)gz(By+$^>x49FSt}t|Ms)(b(h3Z!U0-}EIauiNfz;{gi%bScz4?aWJ*69K%bLeoa@MmO(gMPSADZ( zP)Cg3aN1KYl0p-WIXDt0VV$>DM4}p=s6^AWjv`%+b;X$exFbk7oxD3i`BmCWI)U^s zc(!x~Csxv>&LSUVez=S1?6Re~`O#6-ax{eQoi32#xpc6LIKXC7Rk|1rH14EBzs{!T zyNW$vcHeH|1=M%C8)i;y#~I&UBr=ynHC62FA$rIQNL(HgIJt~#XXx-CIGm3?Bye$w z{fUP}f!yJNV$oDT6GD5N24{*sz-7Usq6yAN319j$Q+xyCYg;eThr_mZ%fdV|lZvuL zaUHOLzG9R#;esKTJ_Ci9{l&hbHDip9^b;f5YtTt8c^{7;Vnw72{dnr z*b7Pz8VX7yBrsHb&o07IB?WMLz<%^mXfE`$*+?-TgY3PL;wNY3Swdzj3dt6}a0?T%MIP3_mS*E7&Lvbf z3PZEX(1H6$L0abMB*l22J`SvHWC7!^)5S4B>pE3h#C6{r5V-PGh%Nl5QfIegh5KL} zZy1ev;fhgNbPh^7DqCh$R+R%~y`B!{ph-uaHz_?A=wGMlxoF`y?amcJ8pV z*R9Y(vnYOyXxw-jW?9e+l9=J7mYT{j0IFa2Kr$=tshg<$OVcT z3qBfc(ekm7p9`|3VES_`Wc3n_$`ccDi0-RAuwtpblTBbP?k>pqHbb6%*GvnHiQf>OX z(R98@ybe*HQw#~5NqdV$4iu6ef{3O5Pl|AwH6FSsRx+K%Q-6ecfAEnSC;>m)^^CWuB6-CbE~ucFaexENPnp(Y8y zf{HCAmV#0zZKFLL7vwo#L~*6NtfCQ}njixIjYhyeQ%Ar*%hk}gBWvN1CFg^+*bmuj zl86e=0v271CZ+YTS@UzHE#C>t9**mbvT*!Mga`cth%&$x61#Vj=#5R3Qn9BFakMn7 zR!c)b4Aqq7n&qktlS&@xk@6d9i~LS^Mci5^NL7W1YzPUx?}{;nvYr&?`-CSN5n#R0 zz$b)Xqw%gR`C&_GK`kk&@i#BhvrmY~(95o@CpL4ISzuI_)Bqw9KHjM5+!HV#%jxbD zB1o-pg>`CvPNY!MQ=oIfld$0`^gh;`?C9e;SL!ucG^0DX94&l0Y(t~YK}F@*C)&e` zYj~|Cx;#%es_*xdh*W2~V)<^uQy9&&>Gh}JSM8x=_zFA&1`Ni13bo2%>1C!aZvfSM zS~6LLs&g?Qw8;1TXx(HHpe}O7mQR`bdNS^7TkeXBRAkCy3c9ey6)L#J6zHD0h7ebh zF2t2arHhQ0OO2OHjhD-fm#d7ItBjXx3@KXY==aWAyj^Et_R=&F9Iycfbb3in9F(gV&~F-`iKyp?$X+cx*TD z*skN@zEeueI#+~>bm-Ghi)eMfEAE|zMPZ zbr=o=oRfW+?5bQe`Y_{J=(uWGgX^vL?9XRKM9o{@t0?0-gey1XHx|`gYi{SV&w5V8 z$&H})S(ur2P~t1l_=hNDjy^|PXNxp-eRFevif^HY(UHE~jXs$TXZ8-wUoS!h%Rf$U zt%vKE@I2;=^|btXAwx<5FNlHg0LQ%m571HNb$V+vrfsh|@K^QfpU2$#`W&$s#KZ=s zILe#Lx{kJA1sOv~GJ?2w9Ign4(1#N15pECO-% z$wt!9R>b1kG@Z8?GvjsIw-`3U4pIp{bi@t*VN)0O4h7S05-#dJSInxFFJWufh$^+A z>f&Z3V<~=#cnuVTyAeoNm!LyS=*?x&GP@~$Db&M88nqOxy+ZSsf(=(_{Bq0~KQ0xq zz#-s8(H*mM_zL*uD_=xs{v8o8C+XjCXo0Gno6Zu!2Hp9bxCHHVTc(Ev{yT2edbt<_ z0xnxFrWx2278miTXHo0b zBHmFsEnE#b@uKl-VC3ri-t^~a?(0T2x!KL%zIzQ~4(Ph;>q3Jt!{BO3pS~_y@?bZ5 z*@j(Nax0r75##vA&c(Ix2xrplwUCwr^z&MD2MwqK+-fydSXv)xqhjp}hj z6W@S^??ory5F-H4_Dwi6h8;>jtbz{N^(Nfb+EjVODahAm3s+;9%AHCZ){Ec8Mw~Mp zP=rmCdp7_ThdH~E>b)g;!2*9+ei>EK=Wij}cADOMTVVf{VMF7X^JWoAFKq6X6Kbmq2Bs!&#vrT#EL^+=s-%0(C43E=>D%ho@>Q(b@A09&TgB7B<@2p* zWr02IUGxE)?dk$VXuUr6p|y5VRChC8NBUvA@J7?sZWKBm|DKqkW;(9-OXAHA*|AY? z3d6ET!45c6hK0)S=o&GYI`0&%WAD{5&Txmo{l*!?;V|ht)2bsPNjv*QgIE{0+F?8Q z2aC8HMck{4$d*44O=+hG7C(HAXL&>do2cabsQ4q;H#KN_J$vN@{LFexRsI{*hoQkWJyUAR$!>>1wDJn5r%%#QF9NQRMjuHF9j=x+7 zfLY$vmur~m*+yW@D4DI_F!(>YX^^oD{cb^dS*rHaa`%6|b&zMwpf}pU0b8y6vGhwD zD1`Mip)JBB*Xc%Ek(QBHuHQdsH16mj?wFM~6Po_*NDzBi z+Tc!|6w&3R!?&Ro2V8<_^0VA6yqX$%9~0_qvBfs-NDMaU0?C$-;EwF%d9TuSQ-HWMF>*nKdX$mk`_eKTI}RJcjWQ3DHo4AG>0Ror;>daPspe6+hHsOdV=0zJ zafh_6puE6rDUc@~^g9pW78T&o;WeY^pW)re4?Rq9WWZQxhhYs2E{V^rPmrq?8Wo6jDV7!sH5iX)HtkhswJx zjr-nUrPo|aDXWv$xZx5p^Ta&dq-oH-WQ-odl5_;D++=RBAy=PT8Vo!ukC?2qk+&(t8vjTv`<4l2WyGq^N2i5Bb;J={{D(Nq)eXxoR-!*6>~?+l9F zE1Eaz=*E&AmmfQd$m`iHrA3A5ZkXyy_li~?Gnij@xkp>UsZZ1vKnM0>e5V`FJ|Bvg zJi5#3J>~YQOyljL4`DB58PDzZ!AKoIwtXTBU-N(gzSiy&Dfn{gWHy8v?-#S+EN$2i z1LqQ5*e|YQmiqD|@dMPxo{zlb~k9r>z*Dy(U`~+sw zMweYr4WKta6;b{p-3)?SaqpfpG&z#a z9Rii^eG1!h1BD$D3EmbrhT94yRX|dU%nzdCL!z;}6&>dz-4vVN6aNB7b>nMQS0KSt z8*boEp`BKzs*XD|4fANN;f@5YxxWz&qZ!< zwdGIV(7MkM5noClekNl0A~)LI2fM1hj$)@dc6oe&n5DcQnEK*{`*MlLTsLJEO*sm) zZyCLR6l)j<=&z%gt*_A3V+fEgpd-g%R2(9o|A0$#XvlwHpKt3+k-w=y^!k6W_;i~- z`;X`k8?W)_2u3-$vxcsHE?V<-Zq#qP8b)1@gA^NTIM#HNqt9Dw^?4J}QB7wMPu?mK zLvp)Lpl*)6syl1J?vxO!vZsy>u>V0DU_ansHteUXU%+@OJ^|7kq~}k-g+E4HPCx)p zxZwiDFAU{PZ=!s_%48jN!g|MiA{j2ZKMJemW;w1jmD0 zU=`+9OTNOQFpXGoy+(fS7D_rV;sg9m2<*U!t4MQ90U(dRqnbJAMK6lF2;Fk+ym&|r zmmBfZzC$!EmRekZRUS{hFCg;y>348g+EM)r2#MFuiNSKpjh{tQ(?~}Lqic0AQtyq= zHYHki52;v3qZcmdJ&V35hWjV!K=ERWlA=E)j>M*6T6__Mwu%D3hx@RWHhnLiz>rM% z0bb1v%Kt&&dVSjc0~YlTka|gUhvJ<@eJ{abyi2n#Vfe13uP=$YVCcBZSRXt|J1=9n zR}udauFy2H{wP}TX<2l`>=Hf#nYQ zO#WAdAMb9$twLe6^eFZ>47wt|MTIF>bwA|2tC)0-Qp2A?QrtW8GlCqB#xnKB!n1Iv z8knwR)goM$q*s<(l z_K^HClmBm`nOvLs4XZJCX~}PZG`g?aOvY^xL)8Kk>K^$!Rzc5V%a926|A${eQVMix z1+{Z%&y-pRs>eHOilLUbMbqBpCQN1eWhy15lTF62DabPx7$6gDxOou4ZRd>>IOd%y zXV{uwT2K@em%}}=!lYEts@o#fzxHA9$&%UtnXaSLe5OO{XV+rhOud4$i9X6~35?`i zlk--b@pqtREcE6b(NuV1GPIGRuXe~UPEsR<2a{*7q_lPU(YpN}DuxHF;J09j7&Nze)t;#4^P zKa#Cl)JIJVh0?9QHm6N8^vW99dy|i%tXuTDI^AP~P7EK#N7;m*F2VhU>-FCQLU46A zQwOTsO%R6=uHuL5s54gsBX$B_k$?CelY$TGLfQTD#X%FMv}d?#LszeHwW%TAF`-k!X`MNN_S z5gc&E_sYd?YAWScHJ5qbJ{g@+nXO+D0n#Gn>?sF}F%>AZ*PBF~8a=&5#uiPGFl?Ft4Kd8sWN z<0AZ`?9OEzY|wk5RN#Dx{&d5Xic2fM2PD5`B5!ZlMseP1e^fHn8@*Uf-*~Ib>)p{| zlYMZfw%>7)jbyxGA2AGqq`P9uHPSafT)kJ`p(h7!b@8NT>9Y@?b%pZlnj zBi!BDi2jxec@9*XZ>+E4NHC1F#j3Gm6S?Q4;=8Z=E{2*yxi#s zvg&W(EKL8Iqf~6E^L3Y(3dnswZ5ycg(G`0|14*-ubiAS30i9{!r_*PkpV|hh^mDE^wv^gXctcjIxZ>jO_ zHHYKlkoQ5D+5^#Hw{YO&MZ?0??#^nGXm7aM#kdN?jrkPfIH_^9Tv{VkmqK~+OMio0 z_~7~avryW(lW$Li*Dg0w1AIHWvncs%9>y;!De4w#5P=JftLLiR2-O0QXH*l&_}K_` zIQAcRG^3R$AjiOV$5Pv1xtGFHoYp(eJQR$~q`%B+ zU|^QKb4dQ-1KbsS*YCi#vjV zV;h65`t1(k^w~nS0l0y;@>j^3DI?u$$GUDl5FNXzTe%i&n*w93vVj56hkG>D-=o$K zqsbTHcz+J>naw~WCQ5AyGW=1c?!?-hPMO4LHL%fmca}V)a5OHN?O#-skNAwj%s5e& zmu)Svl)F>lVz6$!0lz;QJt?oDS=M-WgJ>21K(q>X)$AmsN$t&ipy9^5V>X{G$teHu z>Fx?Xl8nfhNt;@$k>QRX?~*aKszixV-=eY}@^Uc1&7ze{)$i#2rs_p#hRZLi9qnhE zsjKiaYxK!-HBES^*o-j)8;nOaSEH!s3M_30$3X#j(T){rGxF%U9Jz3QPiHm(l!JfmtK|{jdUhS zmFI67wbB(_PAm0COga5qV^lljclQ4&?M>ioI@j4vH_nxH2~WSkn+i^ zujoieVo{9ii1pJp22KeyI@c_z)ZZndD@I7jCI!cy>PTyH%Qn((SNifT zxpeagMs5on@OYP-!f6v@x%|TYiJm-Bi+I~l&B7Q;Ev9;ZZ#)^;BYf0jTw`e^} z#>tPk6%6cxS*t0FT3Xc0h5JU(5g-)vBQVwH@`4CZI+)f)&^{1*^yx2c2Q-8jXhmhI}48FcJZibNKqY z)Jw160JBoQB$5smyvR@(g1K>ro-{I@YR)gTAK8TCB3FLmW9eW^1P+;H#FCCH$- z4C|dT7VCu%6m~LVM<=DEB!?IfWKi6|37z=F0f~edbQWvoIQg~xop4BZtuJ*mbwDBq z(X~1fzM>z{i{Q=rQ7>G2_rro3!BhHC4_xN;Lu()BCH<&tcl8^RP!-Ckf((f?n8fE~ zb3a#nG=75kX#51>FK-dUoN!mXtVi*d(bT=sAaxiboNRKkH9aH7Ao&U!tN38Ye2wB0 zqA5aB@}g+^PTxwO_en^^K#PZDd`g973_=u5LIl%v74UC1Nfu!N1~QUxoTvAvJqAY` zBvTIrGb7OkQ?MO;|SW>ZL1*=Cpn#yCRt^B{0wQkfw=R$(U|<9BdM1$-yp5C$=bLy3M|OXkrY8b z`Pz{fLPz*xq`^RTkEIPYTMe>UcStOC(QH@l=fu+5P4f+v$>Hv|$>DBbjybbipfyXg zw^Dsw57_EkRH?pPilXu7VuyQ&m|CKi@MWQhd7$88EtGXzTcF`QK zT=2hakxo@Ki=Ou%Eid*Tj+Qs9sBA9{WTPmnF*l8;1|ATPF8AiwM^Fp5##1+!bB18F zV^<}D2#(w`z$)b7MaN73Y+w(quRMeM$n#3_6DMgxGa5PICP1>Eo@HDyNKE3V|8WCAF!0wF+!RZA|?7 zSddx_BpnX$VwI!9%I8q7f|O<4GDr_>V@$YDORy#gdL`OKtmpq)>yDMG4U%@N$`HH# z_7J_ke{as&3D)~wXT^eJL-iJ#yHZ*k(P3RT5 z*OZJ3En)DCZD*b(Bkwncj*`lG??l?wAYwd1%xoljem%z~6{zWC%jaAvpOcY~3WZ9_ z%(39!J^1%yL6FKa2Gb1v(jtTcrX$Yz5Y>RG^29h#$W-4h*#i zZx zNyt1g9hq11lC}=+1>dGaNek=4@X2%nia0SDm08A}-lZqv0>vm8oS2d%pT&~^ngFLr z;yl=9$|UbkEn*~OB-kcXL{>b4KWB7_ONCy5Ow~whIx2iL9A4V#1J0IHGc1U=I4PB1 zc$e09ZHo2;E7(*^TF7^P;`p^Z7xT|=F({T#7EPl;M)2ie#@b-X1iST17VSnm0EUpF zzI?zG>czs1g6jCc4@$py3iX8qqhbKP%?O96FI{Z{hmcA~Ivv#4ZvPfLG+cdOKf*Sa zqAHE02&G1mMu;rriadDFLC^o1N<+K{fpM^DEnw-e^tXZo=E#KnG zx6Ob|XD+`w14L*)cb^F{3v4Q8LA1JbCiTILJUA0mu}oYnyu~cYq~P{y7FMR~N~+&y z(fUZGpAEs{Hr{lmfe86M|rHB08y%#lbUvk~L#JUz7*L z!}-oUTC3(pa3(@DR$-MOrVjkn<|6{M{chGVaL9l)~cJ2 zcKBa1$=$r>3XG)uiabXCeIpFq-C_bZ;w>A~I#KyHBD5D{(=LOw3v>6{Nel$McDZD} z5p?DNXp{U$Q)DFghqb|s7e^G5Aq&lqD<4H;z(SZ)FM7&|9kIs>te!PiVu+klap)6m zlXH~(3l1g!fg4Mhh-8rmM>RJ$zH7m`t%H1rm? ztg}l)eH>hq4`RnHw6|k+4)KnHkTx#KKL9@1a9)^O0T6E30GOcy z;E4@@nJNID;Q*MW0^l4DfY~Yl{^0OvKupt?u}D5!p@0%TOP$ww+g!F90;P;kvt0Sc;1RDgo&QWc<} zx=aNqs4lMn1SzPlPypFz_#g#Wt|n1%U8w?;W?iKM6jVP}0Sc<0r~n1k)ha+ib&U!T zsKTY)S{0(;`e_BAje_es6`-KHUIi$qex?ExR6kb%3aT4afP(5q8IUbTUK<71O==Pa z*Uc(GY1S<&KtXkD1)!~h>K7_NLG?c>KtXkz3IM9v7+2d>h=S{vDnP+?hYCAP~EEn6jZ-a z0Sc=7R6sDz787f~3Q=%9Pyq;0a6PC36jTqX00q@T6`-J6qyiLFzf}PWs^0;StIDnM!0?^S?;>QOr&z)wN-mvswEWw;p7wTeuj8wE5tXzU%~Y!HHm`jSrwo(>p2ympn6^f zD5zdg0Sc-YRe*x(B^8jZ;QF%)QE>gG0w6qt0@uqbKtc723Q$nJssa>Luc-h9)$1xi zLA8`*+g6`|00q|@Y7zz4UsZsD>P;1(pn9tUU|X<$QvnL9zpDTR)v^jec54OK+ZB-3 z3a)>s00q}SRe*x(9TlLUdRGM~sNPcn3aa-j0Ja6|LADA}a4lB>3a$@TfP(5H6`-K{ zSOqAkK2ZS*s!vsbg6cCnAUhyX!S%Tv5)i21`l140Te1F90Sc;rs{jSnmnuL(^_2=x zP<^ce6ja$8D4*Jxl^c6#Ju`dkKkU zJqAsjFfrxbiIqGqijt#6;-4Y;!lfbaa}Yfd!`B?d&Ub`xigWBBZQ?(|RP{_?y9Sb% zV6;RWJ}CduSWN`~u*=)735HRE_aWLpGRB1C`HA8Hb7H3K0GlLNsYaR!^%!TXMw%$f zR*!LVodrZQ$wVfZcr;Ak`7ejC-D=7^6;dxc#ROT$m_iz$pCVF48_6`jzK~k7)x%1~ zePP8j$*t1Vd*61oCY%MLL1tIMab9H{=e>pFJd@6SOlmCLJB3DMS>q@19z{@1S;Z5J zApBm$M}3DAvphcKJL;KT^>BAlMMlp-*g15MgMEh%Q3i1Ukr0=jP=U7OZAHLs5l%$) zuu1Z&RAu?wqh>h}MOBtpe8gu6@AfVAlyZ6ew-5y7^4Z^FLzT-n;;GYH`kkw)G{Kt6 zO|a&zCRoEmifG;7JP9XQzSgY7Oc>S)gOyd1L!Znn-??OeJr- zKPst#qVaFH$fa8^^6XXS*T;ux8@~fpnyN@NRmIFKs?=7tsR@??Vrn)!0?FJozVHZj zH&{{?o#hPqxercOuNDCA_NJpCwbOzp{g!k6RS zqqI)bD^-vyeH*z_1-Vila*T#Hy;UVSG@$+=p_?VwaT?IPyh=e&-u~_r<-1Spndu2S9_GzyCuq}Vuc~Bz@pk4HN@j>)Po99BVGw_H z0`nGn6=CvOo9aCms|9naOps@x+qYxv$OIX+u@kcG%Gl8(v2w~Ojsir&e>8wCofE<^ z!YwgzcG3;CokV6XZBA=B3o}C^Ep#6+1%ep(e$MAV{{R(}Mx366ux=1-ngY z5JZ>qk51C&Xt4tV_=4X%N&RRDbg-A^GZ)_W6s=7obdY2XIYq)co}(iPB4j6jbcUuli?d;J8S1+pvM zIr`Z4$m^d6#t(SZdFY5EPTF~zj)tvv0Vg{z`O*teso2ABUjSK%<4rH3n>V+VT*fHBO*k=L`K;rJie!f{bnPjp|KrWlh7!@GE`7M_;A=9oA@y_`a*OVfHR6Qw9=tZTt`8RymIP1WPn&`zwF>e%_Ot z5bKk$*X_e}!F4T;7kddnNUZK4Zu z3~|I5xyg6lqLB^}j*U_ zNKhM0U|2<)&1HPxZMwfUj{MlK6`<;?D230Zd;V$KLDhx9h@m(6AM>>OINWRb z1Pt_LKI94dMgCwCfBl5IV14j9&fIykr&yTeuO{=OPiZn}PTOa+lX0VC7$FIp|NHfI zC%)hr)DN}-7mNS|Qhi1*NskK_J*QgnNsqrEh%R^m#kRu*xW6XhD}Vn@TRN3$EcOQ0 zJ?HISf&eV$@4ch}Aiq0bf(+UyjL#mfeMPfj<}mja6fA+*%GW6EHvj82O|{dVMQ=cN zw)1^&(8tf0*I+r)vgONJW9iQFgKRC-xnd<2BNY|wlh`McbhjYJfh`n~Maw8VjBeP$ znD8xqhq0;JOQ?sg1utjJlh4;OKa7|ITGms#Qebdon}uP=E*)!8uLPl00wYpW;>UHh zIU(?~>=Z44pXm;F(6draYOR7YJwr&FbzEa)A=)y`BXn1Uk+p@swcPqC94D!35Jdr% z-eY8SwYNldgP2pRQHV*UTnJVl8!M4Yf~1F?0DJxc6%0 zAZ?>|1t<(8TZhY)#2=hBwX4B=vHT|1U;!9VYiqDx(9gP4gALZ|br`j?5Nne)Ktrdw zus0ZG8Lli!=Oo_jvP5z}4_2H1=E~r(Pgf=;X*)j8jqO5}g{-m& z`h+4(&&IQ5_O*{UZ^-&MMChFO`wf{z7byz5h~^G|iRI`}Lv&a)ztfOqHji|Wj_JCB z01NKOnjr6)$5_)vN1NkYj66C)EG*&&Mj+3d4F(k}^JWdPbv8A^We;D83pX@jP_k;o zOxhTH$vlf^HeypTUdtP?P%Qp_joC0-D+T zhq=^=c92f`SQOia$b{`0ODYV3ldwa?V%yG#byK>7FYsZbs~xYsHPeo$c^Q|QvT5Ke za+|XD4$q^m^6#3m6AtKIzN8s?|EAml1q+(9dLrr{dZP|M>dO!>iqCJs`hWuc(t;I% z^;**sbADUFA1xUbmICFimtR=dD<2fbzjMY16UIU zG`Zkn0J|adx(@`hAyRIETM&bW?jpXY4a>$kY`eB>C0?Fu%LZYkXc5fDiRKArt!Rvh z&V4GF)zUvUi`LggNuv2(xkCuc!uXvY!scRG)VE`;9bYT#4v%if5`kvvc_b@o$1bAe zZSC0-(E9LD*4O#sjr9vFu|bIIw>cDZs*X&*#W%!{&IK!*VYQu`^3;yd^a#Qq^ZXH6 z5%J3O5Xsi@*p93(YMI}WwUvpQIY?P7be-7u)&KD=UfPNIc?!};q&%2YdO|l7CV68e z`^`4)9|rojn)eQ4TQJn0gt2_6w`>h()5Y-lm<1M$?94_=I;AyC@>oPj={J%Kzu$$q zVhPZ8#h_l!gSxT;5QzI-Sp<6k8gr9(hyY<%3gKTyFf+QmD1r^OgZg#DFxbY^y0N7I zb?C!_cxZQ4U0PGnr#n!BT6JO%_NAb(wR>TN+6v0)CFfe-i*;hNK!%PL-0sEp30p`M z)QX>vVhKuVdx6@EKFn9UUQCROyj5RNt8KifFMElODeT9hpi*IuW-}d6S|T$niJ3fS z2s_Eg^=BTsjk>MK)FJG)Zo4iYg}N8=w4uP{EO&@uZEy*VVUhS?B!;m2Wu6zq zgjygnwB{4uVeSqau{_Uzhi$6-*%o}vF!qCCx6TzG#Skqn=ro*7ltk?G{1I#{5Un$k zh1qb1qp*C}v zlIS9MY#a#J@1s}>nky!brE4#VtPAT|1mgcijDYfIou!QZPrEyXj@UclePk7V0~jN=}k@S0$>njbjx==wFzPGXCK%X5leYSdas7 z;Y+8m42K*S2dO zF*%=)exJ<*4^j3$$g&q7H;uK&wB0m~g<&1PJq?8AI(MJWdg)4ZFp4I08BdwcIx7`g z$@flY%b_C}oy`_j{|7PUPqVQ|w&1mMSYxd}vYK*uj~pi4b%9Pa=g)FjHIO@PE-3#Z zo|em8vc0r=4=)E2Hr4#-9YV&Zo;c>@+8MxJ+s)pZ#mSvs>cdJW*3r=by>A)IfSl6^FvkSD7f ze*bVkAw7Q|zoXM8?kB<@kAPiA?Eu@xs$?63KF@lbbtCA|}sA^9QF%q-)!IU(cT_k+r*% zT?5xkr1i*8-Nx@jzVD81jJP0?0QW~>rH>_Y)!5J}##KWSS35sB5u_p6+xvZXcyNq{ ze0SozGyYe*E&6Q(w;0le|gIw~TFQAPMEC`cD4dK-%aJPW~># zNV2T4*B&)DkqwSdHhz8IMEXCi^ZSuQPUPpbeW|~%u11`0*O-3ygKPvqe0ODbL9Utn zdCz)3V1YBKk@z}b_{JKf_4CdPI+eJP1skWj{8inJ)M-Ad_?yu+iBsLS#owK%MUoQ! z8a^S?gEVe%G`#Nh+Jp|<>pgt2Cu!JW=F@M7)g#B=^_-&ZY9W3uudY7r*?@epVB)OY zbZ;`FaK+)T_BSRqKmY5`g6!r^$&3~KdzKb8C!5-Av2Mt1Ns4cr?YB1BpR6`~++@Yv zKyvf19baXiYfFCnEvn7*A?-=EUgwj4ckV>y=1(i=rt3m>PP?Bzs$+K&c-4DF(4Jo8 z?1FReIZo|IiVs-s51TuP?0L{FODcPZn4izT=dyMb30|^ffV6WAS-t$`%j^#uCX-z? zlFip%XAqxV9b+cV)z<4m&i zker}#BfRSqY2A01FHLA;mWs1RXO~Uy=Ov9Q>tFooG}u&)@f}+8bT`S|q<8DEA;YAc zUN_$TtZAC$H)C&$m+#D#a?VV4d`E)K)D!2J=7Ia9F#pWhp{5H`POGGQF&iFBVQ;2< z(%;=xGiuVPX-($@X-2)ey=s#aM)$4XJ@bmEYYMM5nsoZ%Ce6C+OOxh(T%uVwHk+*J z{ou96a=GdHfcmW*EN}WxFbo>)kTdth=QF=u>2Q7U%)f_!a>gO7?u8M{Yhrl&PY+o) zF`5?cOslb`bOp`XwJ>i<{&kvDR-@;3?^dkP@kHv3*)te<-{tV&hQF||nJHz7{X?{c zsnv74C9TnhJy_kZRqx=;I%Da}kdXJ040Xn4;=l8b}y zc^q^i^%iefX8EKVF&`RI%`m4r`FZ@Box8Km< zU9!o!2XyjyCpU6^)w>$asG7vwVNCmLM{AL*9b1GC?dC!5{IdP4iG;w9=495KO-En82d{+>VhcYR>rZ};e|9%uMs^^1kl*RR?jPHdhk1w1-TSpCotxDT z4K;KkzTRG~ETjwBwzTuvuYq+Sfpw5o=h7=p2vUi^6`ysL>Mt8HRsfQnAkhAR;-^dDij|4xCyEEX~46-gg zVQ>CG{{^JS@&BGpc(9a^?At33v|mHa?4w#sJVCv$?a1!7I-iu8<{Hl*-cN=e_+i@R zbr{|yi`uShe~$Q_8}`6+{SA`Zv#@scs}JmA&~3%M#zOWhSR-R7t6flI5gY0N<}`UR zD+iwvm&Xu->H+Vt6ua{f-eDQG?+XhSECYK3e!SjgY=PGC376R{tdCn)V13LfXwDhL zI(vBFO12tI=1(iJPCn+%uCgz{0~M`egWSW#QWs_kmyh!-$?&lQBTWzz!O9P?Eq*S( zo#Da2njqAo5k`(O^B_HMd5v|jFOID~0ZWm{!#`m^+d+}5nHyXo#I6RfZCgTntO2IB z`vYsR6)5Is*RW{V)cUMtdK*XHoX393YQkJC>r>XJ>4a&a5MJ8$ z;bBISGx38=$>pT&SHL!6&jB9NeG}MPuqT_q3TzZy#A05wiFxz&n^;Zl_6k5?^%uIm zcp}nnDusiq5eSY&swr2;9P2Lb7Gu!s5{pKWqWdb-duk z7VHC|NNoKA?Wa8@N-h=*W^b@-r~d;^VRDg|Gjv|D;Q^4Nyb2HQOLUc zh_BcO0Z>y>Y%xEyk9CnExx;>N@gsQK{VZG?C*I8EIs2I(JuU^x@=!0mG>=J(FgC3G zxBb|NA|T2ER?m_rB_cJkJAfLX#AVFDDV#==Y_R3!;}0;W>Uk0d5Rvkkv=_ys@edEM z6o=zLRfuDFql3)V@wg;X6!ESHnU5B)!a7$MZ|jBlL?p%GBrP5-h~R&SSy={FTROs| zBe*sqU3;Wt!jyl2FzAPlHoTD%={STl5LjP02xKqu=LcCU?G#b5W4zTN*3sb-B)OS~ zSVIIw<@J7prt^+N*o7fb${`H5le|tL>!iCRy^9C`75b z{B|KbTr6Laa(O^f2bl1Ev3x53|iw&SyEo&YHhHopZtmz7>?8`K*$!#rF`a zF64Fhv4#%PdIRrp2IfjXf6r>xG{e0g{I#Hu1o6|5jY>xwjxsBD+o$;Cqil$_L;&HV z^C)Y`BoN)ZD~@Aw!X!sX5Z4~Z-s(9o?}(l8^W&gW*A;lw3EbNx`>!*pGuNG9Zv5B@ zhy*SwLL}V}tW6DB9An29S9trBB~0UfU_n?H*8RXJ@bD^-)BPG^`_JIRPO=`4>rgWdHyKIaS? zZwfzh2D5KA-nc&I_s&4}w2ZI%i8Xd_q?MjX!^0HmW5nPnTeQx9;Fs>6qHWy(6 z)eLLoh_hJ#w(xalF?km&Z(f{*sAz+7-|-ye?T3~7c^}|__Oo-WzVgylF{`?H4qdZN zNr6r^@|Nd8bP*X-Nb+REtE}_P3ty7Iy5l^`URi+qe&TE;@FH4k8J~6$%iv;u^dith ztTKTfOsZUfDh#E3^k%c5@KA_RUQNFQxu7hsSctW4?a!b$|JQ3i$C|%}J72{jT6v|9 z;I*$|bz9C`Ttjo(R$+PF-paRMtGaG$wnId`ntfwWhK0MD=7^CGU4x^Lstb768{j&Q z^Sm3(!!B?uy@4*ZrE2{vB=DCx*7sn(;8zG%3;EA$ak0G?OFg}UKIQLy%DQ?!(MlaO zuK!r=GbbkDu)boo=UDA8@zcM{lT|*l9bCq0Yq38S(@y}}r-DtfB*HmzOR3ZtNbKk7 z!fUO3uI zAE$T~?+P`k^a0lN$q1dJlqM7K+eV(&8S;T`l}kZNk<2EpwK*vt3l*w~vcns>DA|v> zH9;wgh_#?dcNeWg|KF74XRntLnt3w8GM5{<`51_IxnveM4fv#E%*}x6n!UvFQ6rvr zjP=Zx>N-l%8px)MK{P==LREARnq=55a1iLJB|U<8;8ym+=-op$N`(64JJ$4+0T4Y| z(_a~9g~?EeqT&aGk%Xb0WHJZKuz^`N2s4@eWJq`GL~BN3hTas26uz)>1`I`&;q$jZnHp#OPUVc@CW-Z4L4!reD?#ej;C|(-pFYnP zQ1m!oRL+J6971qC!s@i0Z+`?Cb%<#YKlX@?pip&#)%#;myGE(T&#t&O1tHL`Xs+-#j@oV@(}P|?l7=tG@T7M~Lg@d-c&fjE8vQ9ML=FtvX5Bt+yp6Q?+Ev+lKsBNv;@=B@8OWs4Loq;-_F7x>yJ*xMTuhnZsuy;`{ z-oT*kj{ETj?IbK?Hw@ZDe6^2Jn+4!eqjm|H!r>-uJLFnr(oPHvG5Nx4x;@tWB37Xc zokPTnc&jpUOqDgFdAO6-HKs^aoX#OWN?O7G`&1NR8_55kW(b0e+hz#!jf;;*oOJ9e zGBR@^{(a%3ZDkHId1qzDj+rE)IzdI-iMOk!ZDeFl-d4%dc~W9h0xx&bx^utkTE^#9 z(}rXBbgG*60-Anvb?ui9dZ!}=!_8VB2Mq8JT(qq;PEPzA7wr>phF`gA+u;m(ptBSC EKSNM=A^-pY delta 56819 zcmb?^2V9g#^YHENa|awKAnoXf6hT2i0YOngMa2p#c7zj7CDMzEv8LD?KG97xYI-#> zB)PmM8cjE*nQDwRJ#UJdUd=Z3U+;XL)2J3GR`F-`8cF`!Av)dX#5( zOw9M(hu=RuXW@5-R|0;o@k+yQyO)G}&#NcKi8pI(g614o22Y!* zMe2{6qcGOStPeVqR6MmwqJmlhnMXW5$InNG8{j{mg2qP8FwbBh2GIuwgN9#yUjX)B`{{sP49Ttt z8L7Tu`o|$xVR)Qn6Mj!xrrp4`QfA9D==`W{E$9Qad8Gf%#-z2K7u=MC7>tO5CBy#yH^GJjd8~t`}xRs8mVxz6?oB%alVYGjllRFUgebJ)GGh;(YhJEJUB2m4ulq zvPN_yp3drmk+%1lMK|_CbnWH+l4Lin%bA8nKFN_?T+n~Bh_}DnU-s0axmmKu`VCZ~ zIdGT{00=>!Y_G^o)XRn^w0}47bqRH7@K8i&%#-7&Y?_b03@Ddoyg}Uauuh9a# z8i;3eUFS6Yp+b!!jh}sy1n4h~T;!G!r_U*rny;-evI_u#pnFLQ+QmAyV6Wj_EIJZ67Op@8DQpOlW^|Tvvj!r>Bn& z)PESCj#v_k&fwRhc#0S-Bzv;0x~kIFT-R9CXrI$$kR!FJI7(vOI$;!opPbN)-@#j> z^!kZ@7+yJ13h5&gBLrUz1{3_NAD#FE=Ds-TcKlYAoE6{p(UZqZl($S-j2XdG=iztx z)HeM3PrC)be$ylL!_%ZB`%RY`K6UyjXmi&YcO%5(Gvwe3n%QUs)cIDuOL?sR&`eBi z?^61+6klWc4sXn^m{(O@nWFoa#^|q>e~Bobu-V18Jz{o-tW|LZ4oN-#$y+hw)RRdv zV}l(BSNneZJWOa$n0uehd2^nu_}Tqd#3_X7mMXIfhv@sO?k48;%Bu!S@R);Fbpw(l zqR8GjyQ;d{;DhoWR*fToAKc9nrJmGd4hHIPS4ShF-8BLFn}^K0UkwTgkE*9>N+s0R zNJf5HQ-z=tYvovat@as=Z>%d8-}cjWY5?wOxI-lHLn}b6>Kk#AXn&(IT(aw{=4%kV zw&fd{@XVqf`n8J&Ag*T?{fXcGtr&0rwY5#QYW>xpVMgPUCHOtJMDnp>>2i#JymTRc zXDpLy^~kcrBHq4j`BI4>VC5bJcy{GU;MT5d8YJ;<*T0X+TUG_?7q9Q{7B=fsR(*x> zp{qyZck}8M`1M;O)kO80i5Ne)<|_PFubH4PUF#v`z4PR6px6lq*F@=#wNgD*uPIhj zxJa#8*9&pnv`*suW?dibMdCLyJuA&Q{`HjgsR&lOz6XA3Sd+$ zus1fVtVEF|Qw-D)INa83t9CDi2?i!9`&jJ@YRW3=8ts90fnL(oAKZXOrG9+F)7SvM zae7arJ8Wp(!rUHB&9>&Miezh3bK@X`*sR0xaI@knzVHY zm@*;_S|UG2s+w!j>o)~TK5ddp?c}DAsJ|m8E3S9l+!H2tJ$rMmA3~}Q!2VmYSxy=+ zZZ3Dvl$O|v&4K#xEwXdhZCNFd__bLFyCdnawh4(7Q`g8onOTDj#1Ay1Et>=mX>GPQ zIh#Qg^H8N;xs;D^O^&>Q^zIm%O zpkLgIgIvF`b(kwRL?5R|AffqsnoxJdk2j3ag89Ys)I)ztj|;?xTq0lG?>ic#Yd6GR zQRvZ>(sOT+L-mmx62x+Z5TBOxERbjj>t}E1hcrXCNgZ>;wpAj|%YUHB`iSkQJZ0pA z?b%pYz3q%e@5KkA0bno~vG4VI-iMUyckp_|7I>qyoEG0~)mPt`D=FL@4dJf(g&Rj< zJolzW_NBiQNy`{n+w+89A+=4aG$*uS3^(!^~!CPfDMPBZX^;i(XMqiYU zGdpaUa%M-oKKC|B7Q*HV8%S_p{>Te4Ar_K2sek{;HdqrBRvL(pt-e*TMgQ!D zURpOTl;~|Q2I@&K+KmB-we7{R#7}QX434ud5M|1$DlfrcwKX-_MY`ZzdL*+%pdliV zlH`1mmyZdCKt$N*r3C%$+Xj&!z1z;|Bv`N6nR+EvbN|j{V+a=bV5brjTRn@=2kc5m zvzcTx)#Lc?-(RXIDYyE=FQq8)Nu8-hbqQ>4t+zKtG};&18Y}hhU+OMU68>tV7N+mm z)fX9dbk{KaUbxF@Mw!XC*4h{Hm8mR1FWxN~xoNi(CPo@?Kkb%FsY$mFR)u4FB-ev+ zVQ;hpzncgpW5(Cp8=W?XO2!r)zrDz0mMgj5cSw76>KzG)X89e`sD1U0A~hMGhzeo={5{fh@A&r=@U=Eg4l+=EiiiyzwUo*cbL+Os)(`d&$% z7VnXI>%KkG*p7bqVP%ILeOM|8ks?iiMe|T@K{@dQZ`mRT#^wEz-^fyv96J}+W8c0TcV^xK{tl8E$*WTRZMM+wbNSGw! zphPIllleGLdg;3#z1G_d3Dln&{HY&bSKGcw|hdsV5ItUtJ^fH8s zkJ%6@KHi2H@$rEI9SsYoNpyQH3xW?P^H`ex*LB@!iVO$)Q*EN~6~Jh*hzV=bAcG-Y z=Jm@|c{y%*nSfvOj2FzyfgpwWK=Cyg^2NtuD4_h!7FhIeoBb5Z*=r8j`R)d>&>vQ- zeyK^UC(KQ3fAy(gLJO&GpC^s3|6kVe0@GN@{Qqho_b?Sp$bV!bN9gmOOC*JQ+jHZ| zSpDpC)3DX2>*AA&sb(2pFP4nLkSPJd@&jAP4r1sxv989h8A^a-VAYgBsd#7x~IJP12OZX>*%o120^)n z8sHB)IXm0XDiX2{OZEGX&J^>xlw_~Bq$=9|cJCn~(cnWYwRMd(wrT{?CK*U_9cpH1 zyIW#hjja}!h+;mZ1mMsB(%+hZXh^o?R_+vg)!cc_U^YR4MPoIQ!ATKiCj>qqew|iQ#*d$meIj!}f)u0D+Tl)3^F&Bk)zb#cAdq>VfdGAQe zY5qGAh-A$>aw+i1I|B;@GIzU_O1l(TBv1)X;YWtiV?_N_4)a9i16l2p-c@{G{~kvY zvG4E2@4N5I70}bi`iW#=krtnf(?32@ zD}(P~PQocP$vJtE_SILP>M9a>TOPIOdrsjz#{DPLP!GQfTQ%?*F_fLgrJyYG$7w90 zd!HGs2ny_*&m@Xjz%sG5so7qm8ET|#96DR7cRw4|AuNZ^&eV6EjdV{~;2xQ&^N%h8 z5BfNwGeq0R;hhtFK8Z5LF!a<4{Odlkn&La6=1;Ar{Eq0lPrG$<_fQvfWO;sOHI40v zuKBF5siY$s{&~7-pr)vl>JNP$X=><*_WB~q)as1R)bIPkD(cvgkn|-wpgR)wT$<4L z-#t1P+4t{6_k>b?=vS8@eeSDhcZiw#kgqREIP~=;Me@IiHrb6XULAz!(vIlhZxOsB z;hArd*BuG{&td0vBsk8+h&ps6WS_@scO)DP6r6 zFoimkO7&ykg$XLogqcBOnwpcX6IyDUt7>50%#edlKOGRP|N4Cwvk=9KM!T)q&V4;e zlvkjwvIc!~DBSv(ALMxU`6Wf){=?&92(*v+QMtTU|Ma>jUrSK zhlv;&`ujg;;6U>EMOva`evy{WU%w|Bdy5g?e)lg8Qq@|1JA$B}{Dw}c_OZXukr|Ku zfkRD?{c|G{-}|TZ3$=fEF`MEcwLo0On)8Qa9i zd6HnGDGfmQRg5%a!8d=2;#(;3;>%3L-xD~{4670|kJboUdfcxM3FFH&ViC}sYor|m zqM3+~FE*09F)7AGGA~0Zi#?o8!ud`=;^Fw0iCm4fchyKj9PlNB4&hlB%8^$&LxBS1#j}Nzb$a03)$jUAa5`+BCMbW zF^-@s$}u3EL}Lf&V}6X}iy~wt_!ki*&b{?sj*Lh$0ayP+tL?T%p5Mj-_|7PT4jTS* z6p=HmAek3U9u!cY^L# zluNUvs;Q|(w*J2`M`VMt@X>$!*^l25OVDY@--so{-RslAabyj@j9DC*)yr`vj?AIh zB_n!}YcSxFR>!YB$fuH>&TgbIP@nD%LnXSW8aO+867&u6_j{80SYC9VV@5AEikxC( zn_ zU7gtGa1HWc$DvdbEJx$9G$OU33s=u{f<_Zxl`aQ{&^idi2lpW}v1YgSAyUD<-iM%B z<9MjAQz5+4pY-5YWs*^1%ua*_owZpn`Yo6r%_Nhsa6*=1OL-QNi+Lw)90~d(KLzp6 zvj}Q@uJx0nNy>dBj#!``!FTpk;~J`v&X4sY)5TKL%2WH2Bwm_L&>6sC(4%;Bs9ysA zEt{Z!7LhrIY{bt0%q63P zp#*XB@5=pKDz;E9Vv6I-2a-s{ghEs{m;@OO5m1P~K9C&2jGG6M4IL1jRV2XQ){!Sl z^W;1^Yw+E9WPn(c%_!$92a-VkeV&^DIY#7@!?KzFLuIcyh7N^hAhw2KWMBtcn36pB z8^ctK&kQ5w(jPJrL68HF6p)WP3OqQRgkkKZ;UrlE^y1^)dGH9*2U812D1Ns(18=OQ z!TgyKWRA#pB#a~t#GRif3khx^@`O>OP^b#Il6zw`K}Q1RT_=(#es~mFM$LqqOUNL; zdNdi<84^jG#*iKEFx`O6%o1{fzcp4$mgC%5lHG}T&3KX~oZZy3uu_;d)Zj;~b#vy} zYb#OtzzR?}1pS(->zW~(KQo>L3)KzF>ydUFzI8wYy@tS{A!pH z?UfUuLQU%6051K~a|mWVq$gxo6j+<>X>O{l)nVFu`zyHLlxwW?DmPT0X zd%>;)%fr>58G@Q8VMb=~=WAz@cvXd*;z;Hhq1?89 zlk2KL+6;ymzMxdjUwnV5oXq*Br6e0!2#Z1~D391+=Bb@Ux?^(NEU8(g%AYkGtVaJb zBD<@)Obtp=mcLm>?s66x$lJ>mg7?bFG0}5nplOfTlr8b2O{q!LV1QLlif3ml$ys@? z8uvvNu4fgNo0T+n!?kLw-EyU!s}puO|wsQIRTj#A=c@@30Z&we<^KA7;^nMr2tPL;DuOKviTkI4nQ_m>iK2$s*m>7%XI+< z@a;%(bpv?`1LGUX)fhO^sF;MUifbb1rsi9lNGUM&e3LS(fQ3DI)YWPl1}@^+7b$WF znu#}P@c`NafK#u}Y_wN`sesEmIsUSf-Tr(q-f{!jvwTiw^$va)Pck?ze($!>qekC_}_KWV{?< zD?xrRbHp`jIEza2UDqf+yBE&l$FC(|FFE|LBZaaQcFJ|v6Lgn}ZVYie49D;Ybj`k1 za$@B%t5rLutR~~Kp#w<9SU7GdwlT*qtQ9j=VvVhJw!I9Fu*@6CNUn0-!N%7}NEu}4 zmJ5aW2dl|YQBz0c8Zui_U$It=@%FW9nz*o5nRC6?k?YieW=YIXPwyGTeb$p;)alwt zlEM?$lO$;Ag!N<~#I~#_aWtK|oZ28Szpf`sNe*AQfy9I5u>(FdpXufO!uY8TBoUIx z+celK5cUgdggq<{?(p1=Bplf}b)&L}UfZY^!7xB#9efk9C|TM}u1CnMEo2-9uHT{r z>i`6V6Txatv6dH=^RqXAphUKj0O^Sf7;Z&1~H=LR%Vv$iQ|pRrA40Kzaw z`!;f`WKR(%s}a{RP9}mhCErN$h}}_hBMfDc?r6P<9H4(o_`X|}WSqDa7VJu~7qG3l zA-r;jlGdAUgIP-7LDnFhx}9V!ueyx{VoZz>Em^b}pya^C8S2m5NP`m`%|@wV&g~># zrb1~N{IQeZuCZ`<%IOfszJ=egOG(BfyOeGUzk^KWWxJInB`BILa@$GJ#W8vb-W2}* zZnYF~O>f|uu<#kT!)A;q3%{aHB=3Ldx(ku@}SZL zWe=&9yW=5ur4B$j(8Z(nko%DQ4||ls=|bU{`Y;KQf>Hel=$>N!#3SStS=YUC>Tp;d zRf}MLv7L;-yy1^2Arj1VeEt|YC2e*C$Ak#y5EDG0y(3zTINPu-`wY|K98t|&ep z?AW-EoRrk(KTQ&m)D2IQxuA*ucv=aHWj{#~GsQ5z_n;g`l9jr}jSNj3RpAdG zQnq^hvm{-$9ta3Y5v}Ze?_N*Qe1SesNzDI>5CNCKP0fgXYG+_NN_ zmNIb~gC{;m!j{{>$RrkF$r5WH4$(pAM2(y4tG=;d)Ak6@O2oWj( zLInUEcN1+DB1mI21Nx_4kw$>-Lu!53ysH1j*&A?Wzzkh_Wh>lo?E zuYZ?pLBzrD$sH74@}9CRTtLps=kQtYlOT+xegF%FyWc1NA|{$^^gt*1$@j?x7dQrX zd`RL&zyU?n@@VOC^68ano&QnnN9w*_S zx)Y?A%T|=@le_Q&>F)R|lKdmObh%++atg(&nJEPpPzGq1jhz%Tv3Nm&Tvn#*lEa@wdIf1+I z^Jk^$=1l3zZ~2J4=nm5vVJsj23F+6ZKqFRhItAxDe-w-DpD2&l{!hqHSmUbS$QnoP zXE66;)b_b@0&MwQnMmh8m&Ur2xF`SiMrP)_e3{0FLI+{7nlGdw17cmsQ@;hD7=FTe>$fBjtkX^3k_7lX{w?Va7SOS8VO>(f zFMdms!i!-~ZfITYoT|Cw>vLh^sDL|LgABpLfM1Thb0k!@V)}Wt7XX0-$HnuowIV1w zioXMk0BJ)d`tifxOP8~wZZPrdhn+bX(Bd^;GKL?{~2xS-lVs1GUSHxZgd zZ2UPw<#3!tsqpUIP3d}B^FA7lSC&e*e4&&8B{dX?ke{JY=$~YMOrx>DKMenSA&up~ zYcxfSA2?622p`8m7bhc zz7!plj%R$SP2!31r}bnhPYcu{jmCMR7|)98Y(e3oW=`PtLeTo zEc{?1HR>0?_vGut!DbdU!-Z#L1eK1lPb26Zn7lR;+x>1Ny$a)bQM4BZ21e67{$Lc1 zpmwVJ&I-XqTu%NTMWtd2j;0AtSa72`Zi%LoSP;lo@(|$)XqDonp*M@hQt2rKycWJO zmgWMtUx}r1OHA|<|0|Y0is=66K_mFbxJ*{jl(Kj#SKA1vCD1IuH6Vf7u=I`u zwP1cLL5d$ourpyq-$h9_mSZBCcaS>B|_{-HYNb5`VoHoetQJ_NLa$IJzX6 zO8(xE3<}E3cfSG?+?UC8E`*CysC1Ex1x#{ZJ+!y#qk`U49;9mO4e}z9U&b>!Ml?oC zmGbOtMF6i)rM_6j6{%EilRTYDB`40L(hZVy7+;-6aYvqarq6BZG)|Ee>ZDVb3$%jh zL!z&brc>!kit8f>5HIaRpGV5w`_jI``BFG%+gTdGds}HZU)7hw28-ipU-}af?yIU= z8yqEHz{>{#t{qv_gY`C;`Grg+0*kZgCd73~^=9{@395SV=_F`IO{fF@Q9tm}i$Kpf zn#%iSQ`{64{Bbm9Q{`Xlj1|E@&A|~PIubBX=ugqh4dr6_k^b}$!fYG>%Qk`g=K*vk z20A0+59PX7@5fwv3qrLGq{}hjKZxRa0}g>0zGM*16+3^xxFr7ZAT|6BWz$|fX)s0e zkPjG4TdzQgYRc^(YEzOYd)fixZJE?BenaSZNm2N!#6-of9zy@Xq(ws&hi)4R16yRl z_z&Y?SMVXCGJhta+uG~(DM=AIu$+c9uwfzqI#7N`LkI-IT%y2{FrE@ZL% z#o`3lXlP9OmOh zL#nrqp+AdDhdr(0#y&{bex6|sLT>3(9bajrT0ViU!6z`FrGV>Cg2p# z`%j`nMUrFLBw8!ERy<9O6u=RK;DQ&9(UYmX635q0p=p@DZwk!>wCAVLVX`*mvq3jj z*cyxt8Vdi_@gEa^LAtC28S0^yxHT zR`1;z^cO@YTv6Wks^)q2#{Oa{|3s-%utR6jTXDMBt~05!z*G$9f6k(2Ea_QBqcG5; zjP}65_%fP^fkkD?eDW$+DSgV7k}E4$>{wY&lMwiUa+-sIKW<fhV`2Q& zZ46J}Ya%MAl3Q%5a}#INFMu=t72xg=?Y_2xuEhX$bH7S8onSZh7XWWn(uWX0^s85( zeNl6xFc=&lOHFuP6kOnI;C4~3xk}y5ovS9&ka_e+QPR<+ik>2PlfZSAu^XE9vv$IX z{J{D2XCwgUwUeZatE~#u*2Udywc}{D>UxK7E!`-)VMm=(op5Zs50)&hSK8`Ky&85x zZj2#uq5-2DXe~mKX4=#730xNxd--29DuITBGC1!$AiG!+nAk$)QHQn`WwwZ-JbeMZ z7fOneh|Jd8>Oy(WLOQ4;c5)%@!gqr8+9@fmQ>;rbsMS9)TLDZ%8i;kpB6q9@7SS4s z^|ty@KD?FY3ICt8;9p-tCxC@5&i8I#tR{(xi)sB8A^5Y=>{zvmDm=fhrrYGYAPvoL=SGx6KYv>d6xc@k-PUR+D% zE+wQ``G$3B$U|~4Z(m0vJ9V+GHI%2Vr!nHbn?~y4^hRUzY&d+%cem1jKm&}3F8z4>o+U&?2*m1Pi(P~R0`IK+iUq16~d@2 ztW35JgFU~bK?WKJlpSmf?JfJFPaEBgNS5US$;RZDo z-F1U91H-l{of)tl1jEk9Z>O&yk_$H}RR(+gK|Jkdn#fmjngSpXb7i*SAof5z_ajbM z|6Q@8H-bFbIlYO>6K%COsYTS~B%l|j-Arc#^wT%1=^mzrF!NO{m2>SiV0}*Gzu&Bs zO7C0b+Lr^G7{`0J(CcLzXYNqe;kq3ionvvF-a#o5S6bojLkmoct=5(%xFcjOmzM_1 z8tn}&aLBG4&k;ip_TasCDy_9|r{bDWu|ar+6!2)oPxOevTQI<3+2vf{ToK3zw+5!~ zrcWT3kaOryawOmGEI8~Ax>V#kp1p&X$hHVvj`X{niVutV3BAH^yPJ+gR03rCJv18D z`PO@Aci`aAd+0&LqumR(8iwNUqj26u;O>1tl^#G|@c0ZSz>Z^g$XP>y9;| zd0|y^GoH_KA`){qF6xC!R?GTAW5=>yqzc!m_+nW6!;AZBAw23K>M;bOuA4rv>yn0s z4LS?_APVkRECenH5$)rQGK}_>R#53f)FSS3Ln#xc%Zq3b^}uL9XDLsNW@8k58eSL$ zm#!>pHUtWat{QmDxT^|2G7fbh;Qv?9Pz58zx>{sr26(t3>MLX5G&b{#57F@D{*c&B zCIWdli)aXtF`ym_u|SOVk+i{25+vh5I}&n(Weh0CKrBSYfO0&Mpz20|h|LdIMC@6(B4UHU6@hJsC@c7dnCEC9sDfTuw)pZQ}@aGrI;pkO--z@XqU3&NmaFbl?@;4TZnpkOVt zU=aAa+`vLHESSo|Feo_6!Z9e=$s#Z)c*!C$C>Y72Fjydh(HJa*AlMlox?_!(Zb@9` zLjySAG64Z77R5@82KW=Z5{O`$QI4t?9-&K*ab-fqgwioo0 z7k_duwT2og$+K5fHrd<{=Rud+`GvjU*Qw&mo&w+E@JHoB!*S+G=QQWLPdYaF^nEnL zVR?)$ktVCUnDzvnB(>=t2OWeO59Zyz-1;Q#rsx?d7Mb>> zoKgOU>KIbP@7YJAfv3WDGcsJ5e6vqY4lz&BnG&B|Nj?7*%|dF>hWGhfPs;@}cW*}~ zzjr_FCh=u;F$#Rn`*FJ8$zbk(fZDo3;)J@oW~+SUMo&E@9XW8!AlQ&{-buTnpu%<;Yw-~1{~a6=r=7e22{s!h++ zDOh;GYs!R6c!3@lDGun`dt`6F`3BAGOxQtRb}ki%9i}r7e%E0dBjK06M^h30fupM6 z*`stcZ#qKJFVFvDMe&$9hw6O&ceM!BSWlkzrdq!N+4qsyWmFwNRg*R9plB7adi9zZ z{`jk422Xoiak%|$Weh>Hf90p&QOjv3Ei>QnF0~*XcY@Mn1vPx3-2z(wcAbT6w{1?x;XL2wYh9g<~{A%BAJ9-_71G)G0gaHaFUV&}U@{zvx7vhe69@oG zE^fd7K>0kd+<@b>yTtM#_;Om0)1LodYx~=A<(sm8NC${Tj~e(!XPrX$)j(M6ml6_@ zUs(wkb74CptqIB;W#MxKy zTKtb)H1{kWCEsGMQIruPDjd+*}9`132Jn)g!9uCXLupOaB zr<*KEYBA@*@x1R7DtB5B{#zWd6N_nidkf;yXCD124Mz?Q_*6-z?Nf^T$h_Crur-4< zAOD$}3eSB_Z|`ET<}Q>M%b{uf%$KU(Ip4w_;GLh-{)q1M=W4MW`US0x5u7BG)LE;E z@N^L_21i%bR>I|UJm7lg7fLL|@jKt-B3q*kp5?SRHldTu_e-@D9P_1`jezU{B=nzJ z7Rvwpx7tU7R*m4df2G{-&@{Q%xA$x5igG~9)H!GO2H~rAgrtpy=VYo}qtOT6ToFxw z_FLs&4mqcG6Y)|_*|`p;TR1;QBUB%W^H%>if#T4M(p6S=UX6{V=P6#*Fm`@*$d5mN zo(A}Xc_tqo63=;H-vNdwu3ex(dEf|%bGuM+h00uR3JM_Sbis=+&~)LOG|CNH5$d#- z6C&?pvEY>#cfEFLoBs=$qZd@0eZNyKC9y{4>rKpG%t=Omn~6m#BaT1t9UMA?RPO&h z%>zECQ8tWk|6cBWaj;p`euTg<{}1You<&S-+y)kfcS}9(EAnEo+qMBd)q6Y7fU+GP9ci_bD z%2loX0jEo`El$#r5Cic8KN4K9SkyWRUI>D{Z5Oi5f6!Fd@fKsAD0=u0`U&FL^QRid zqE(Ky7r|J@^jrT@n-#(_}iF45V%#wi>)k>_cgPl*wk}(A zxlXc!#PS4M)lv%&%FVZ{hJDtZiCcQk%FF2h>LYi^oMlz}Hgc%SXg)Yl)f?Ma7s#YB zehKg`SW~Dn_=1B}flELnkp;m_4oZZ5J6JLAim=;4*x;^k2KSQJy;67=3+nrXclDh!WSTTR5X)2TT`P|O8}2tjjiks+eP74 zCY2;04B`j6GcR6XWpWFx*2?k`YkpUNJYr=rmp0JClVX@W6(Sg9^cAKk|15?L!E)}T zjb)D_G>(Ad@g1C*!oTs6wQ~TZT4f;}f9z8fy-o!X54P*N1QviX zCq)x)PhfHr8d>&10+Y59pkAI^i4VoWjwd{mvA|viPtTRXS)Q^ATRjNc-#jnp{y<%5 zH&G*b=^8e2^NXfgp*(Ep*7Gy(YQX`9j94q2RjYvu^|0D%!l}BUjafY4=39l`TE}b4 zSYJMM4~rHaH5j2#gL1eMlV2;m-&U~YMb%(QU~R3kS65o$7SSSWdRlyvga$eSdIC7b zs~YWs@8Dt6S{oU@n6yf=?gb!lRW|mL8xJW}0`FsN zL-KqNle_1B53^jpsE5kGzXy}sTCTw&>dEINvaVQ6j1dg%Nn|U<_)Ah~?n~-W&~iXS z!G4{~oJ|AeaJVNE#|5F_Fnn&0XZB)!QjMm6>|``}nf$nTw2)U%)%^IxWR~2`Y$Be4 z!>bnAD>Z|^R5hEEnK8IkVTq#uv6nGxSUQ`HfqT-` z+&;A*i{sP#upOBEOCPpg1RU4(Wm_fwylF5;-ImRK9l4oIUc2IeIF#G6*lQH(^+XR|RF$S;D^Bjuolkz`SSHbxqPJ93qs19MS*CrE#O z??6_LNgzH!j;KMv25`yF8q7*Hs5jwansmH9m^~&b3n&gyK77YuxVZD%?PkYQ`7DgU zE$jD&ux#nD3o*;b#bD@5H()@T+C?ja2mhK}?>;8-;DOuk<~E&JE@#hO(cq zN^j<|Tw{|RF6{Dd1?*W&d$&OL81FZneI`;IQ6reTax`Nk+loowj%17kK&A=TxMUCQI9YWo;+GAa!1~1rncF(k71h;JYg*R3Imse^P+JK&%^K& zqd~L2G)~Q;e~x3vu*iGkJ0=`ja&&S)CuX}=5gjD>E)A$w}%P^HnSa?yh2R~q z4eaLJp>U8mMv#i)akE*tDPF?D3zf0lcMj`nN|6b+3YOBvV#A+Ha7*GRXEQH%7#>o= z{M-|~{i^Hc)^!xgbj$4Br5e1XwM}-F9W#feka$iiVLT`CziL=8d_c<%O-kvc%At~% zKA0E}Iv4z)>8O;0GEGt|m$+%=OvzBIokhU~l)-iu=Ek#RXLutp6ta=`Z`zsVZyADh z9f;)kx0TGZOR*cRe9?wj{^T5XJt&z$b6H$uzKLWHsaupgTo^ZE*()BoRu6pU^W}3{ zWY`rz3w*h>qf8;ny-20oAOPDv10atc(M3GyhMC6O@?W*QLE;$ z7JLMP!vH}M!*SugDBy^;Tg+*7HNU|WL-gAQ+dQEjLU>i2oNLH+CfkknZ ztXaubECKew#6%p@pxAU<|jzPr29|#bAN$-Bv+wC_i)+jF}1544WtQT^R0YL@>|67*eir6r?B40!Wkqy8Z4?eYybqm9a zr{y=oZy7Yh?^%d9N{DBj@UHU}bu6@_%HsK2zNQ)8?s~qCNpCcw`l*gpVSOQ{ruHkg zNqBaJP~u0R$I^=%7`}=qS&1~xHNaZ!U;_)egf^t((}tZvyZTPD%^hQ}o!bnL4B+zP zf8*PKD1{XbYi9V$p&NBzMxcKMOq6wHv+-%c&UumUS_F3KRr?!ESW86uLo+CNHwkz0 zF^bP?VNvcmV(UtEN7Q{3@J3yfJT7_v}Jm*=^fhi+a5(z(T{QaBA@f z2ssj5u~^NA-z;X^5dpZ!!Z@6wmFwZ+B}|?fx_JqkjQJOqC@ZGNQsvECgU#FUVag}nyJ-AM}drq!n$q1OV9;}XCtDS^7s1v_s7raiZj-2~V4N;k2&2=>AzrJeuS#D2yU0ncN% zuzeUiwMB_d|272(E)P62$IrE?H5--~vz0wc2>)v<>qX%qw6t%*l`PJ9!}6tAXNkni zu~=tArRW~Gf$4~S$t0k)avMv9M(y3k#ElgAg!4@{xJ8HIFdn&GIe7+dSMs-OyK36U z+gUB*nZVW2@}*qW@-f~qjyD6U6*sb(2zv5HwLr}mOS(7PSX9@}?iB9Mu&G$aIi|ar zU5C9ZsLDF0L!Pl?q_|)rd%g;S;Q|h zm_=g8J{VXU|6?%_>b(y@rHta!gNuupu#6YsM8U{^aM=3D!qk3n768;<|#tki-j~fY~&KZ+wF7^-dS4e8iEs zOkU_<)v!W%!T}0#ApgU`;@}hWBnySlfG5E=1<%6+Y$(n5fES1@{PibU9SYc>e<`iG zA_?BbTm3I~0+TEEvClCu<|)>Ifdfw|AI{9DS+e|{1it=hHKt#GS~^+yf&Hui!L+8MU2Rv$8r+cCJ@mAm-FfaI)-|BY<5Emjyz~$Y zqg5Vw&aCYav%-?#(L<~|t?}Tsy}$$a?IBp%HV8U){^mht`gA$OuH$b$%aX*rDWyRC zsw5A5j)h?Jlb>S=LK%4Q3&Y^tfAe!nZGp7H>uhT^4@?qLBQUpmpfPv)Ii=;oo>yBZ zGoEM55a03V)jZeZ1vXe9&gX}AkpO=63(A7H{{^L;&%U5c9_x!t-hgO$k==txL{DO% z|4XWGYhO|pgR6JN<0^`aBGl2tva0g^dEC<$6~{#Q2ieaDz05pDUa1tt6`aQ<9#xMk z=@r1LjwG#oSyl4!m(|MZUgidAFZGdYBdZ!zlnOWWj!N-5hE6Bg%wV*l4lRaH7QS!JHdkVTJz#F`pyK$0c6L zM47(il}w}{gqZI}xEpb8l9?Chgr8?a+#@^)96HFJD(?d-)s6?RDl2r6Z!=0P8p7O}XjpD1Vcwi`YV} z1hb&)G#`V-icPt2RP|o`TS}pnyv1f=^&Wdm&8k1VrR;T=Ueo3&9 zmh@Z#C}?|5)9^PIJ-GP2NdD5>U>YUy^KZ)~pd6*%@31*?Tq4Z+cTk%@@eb=1o&=%* za)7U%8Ax37JUDDN4}N4-aOJmmSV|D_gcZHGYXO(qQ5^wW3E%QQOr0g~;w-l7T~=oD z^2AvI{BxsW3L5_&m=~eE?madqGLw-+@L?>dl4lADyn~ESD2pvGcgR>H3;{1se1I;| z>?wKS@7XaH&G4p;<|)px8vG$hAs!?uGL7$i7it4{%!gPa5e7GI4KWx_n+E6LJ>fyi zaNcrE*?Y&1DKn}51GX4@=c^Btb=TuKymBQP-+El_b3S#P6{tCdeW>i~0Us(Yv*AOw z5y8VwsGZcSPN;e3p%ZFJ-}R(i*o@`h_!>j_gp;fSi-`WGNwUFLp08nZ`4p>z>2bp; zCSDr5>lEuj(>>t{z6k#BQ%t(K-#e|=p3}~#_0J<`*l48i#~HPlL{gcORAeDMkqVqN zGLw;nP4jf64lorb%&r^Gh|+{PiUZMIYd0zg%jVCfOR6sV=vq zyS-Ua>W22;EUAml6Q*)}_p7m~iof}978Ns)!q0ueMKRYUF&JL}CX`B=-P2%~*zsYF zV1RY0tt!EN0IZP!y&KesX>se-2E+pmOY<|d2zW?n^%OpJZ0Yf@SdLZ-S7mgvB!Kt) z8vN$d_?WL*s%dEl&>dg1tB_$`zfpZS?i;y?;6Hq$=FvXis;tIu)u4II8Tjd2wK^Jb zPOXctImebc$J2S0Ir2QN*cLhC`_HpQCU_-8bmZ&s@(G`PfhCI`lHIcP0_!0waHTZ0}Dx!g@v{jOvjJH2RDo^P3Cw0pqzkR ze`Gyi%$%vy62v99%gXvW%c4DkTAz3Q38tsEA6Zo}Fd#z+lJjvCHT?m=Ovx+p!?lie zKf$pc!3)QZpTY7*uDtz=8e(3*Du?QjU)dw7kAD1>U5`*#|EBD;Cw^0lQ1ZJRqmEmD zXHz9A{wJ))y8o%v&gMU*+sX04pUfx$PG3|q6Zx0YljVP@16^VuilYmcwcF5wmXzoZ zs34cXR3L%VO=Ect`%+n&;Ph;vO?C`0z)Y@)5bL~Q&n5gSk5hidZN z&rGUi1p)>G{D7c54=^7N-9ZAsooe`kttXFRTDZhGh-tBNA(QyP{p;FFxFrWmpSXOu z3|CVRKN|uM-ki*{Froju@K2fMhn@2i)9}E6BTLg%S8O(F@=Vwfqc#wMyi8ga2J%dr zbdz6a(&Ry)117B))}?+P+8&e93&-8>K3W1XI==MKqQo|{e;+L!f9%Zc1<$l7`psV2 zc*OX;mnOFqfA!Mj$)r@X_Ke7KoHJ|kXG-{Q-dYcY7Cj9M*P%Yz!=@lf?I$0t7Z?uR zyJ$bc6?i?l%*wsr0$=u!u38wDDebDs!(exI)r#Sa-Ztqs77%U`v$VMCCjOxV zy$tXt^pwSrFKHd^rgeu^>JQzt5irZ<259LJ!&)=>qsh6}} z>{no#9hn9oz_lvDHSrIv@iM@l;2LB!aDR)IEbb?y71h;MkE?4Q4rignID;g|c#HP3 z)Kd4a(*`<9!nED;P{!JgTCV&_cwW3&3+3Y@H4au#>n1Hx{stqzbCZ@Xf7p~C+obh3 z$_u_ho3$Jx9#|IT3XI(Z8Gh4d_!*5BJ~&#FZjSsdfChhUlvi)jM)K}fZ7%XBqD`A2 ze^r!2(8_Oa(=z$M80`?|wr$n&jHrG1J6p9h-q>A}Gt;i_nmpjyple0OXr%ePt|jwX zv067Q+7PP^!N6m&+P^WdGfwFUlv1O;e*FMY|RATx^@yTPu$RD-;cl32>gU5w2%QLj%WHA;G!Xi`T7%ng*;eXIbT4AL)&M98_no}q3J;9*90@StqzN|u^J*MG}9#J^~ zit=|lUF+eGG3Xt!I*`eLFWcAMREHcKM56@A-x2vg4J6g<6MeM#Vm<6$E6mCemxsK> zTBE6D&YY@6BF6Q;n)IPKB|4?&RTqYUuf9YjPX&?rcr2Bm8r;Yh0ZQPVmQbG79Vajx!&|w7l_2q zn8PWbrWhWPr&-3vo8jlotLy4&;AoK`Aut)@&7M|!^Ss$2-I)uw_{}5_t-&E<#*ZIc zHnDJe0honJP>Km3qNgE+FVEA&!~XZ>X)*9Qk_R?II{!8gel0tld**8e;_+zLEz3kv z4LEZPL^^7rDrc4tg^sD4i#Ey1d@X#8Xf%v6i~LcY9COFd?WDmrfb;5TQ$A#f)d>6q zF0s_r)W9vS0y9Y#N%H4;0AmjSEMJqm#Qle8)2F!6Ppqs0xvhXJSFP@qwbZtV=lb1~ zu6%vbDsGgvG}$Wwlz%)#8##TTnfQ!^UlukDH2Y)&Tk#Tg8UEh3pZMJcnTZPx>Sk}} ztL`uw3PdQ!Y$z08==8DT8)-Ha^OZxjGL*WrL$!Vw5W+%Ac>iHqPM2u_hwB!S0mp@w z4O8ahL&G$Agzc;fID!ha+vU&`#i`BApZSP(=YI^>M!1l6u_HEdw}lw0c-;t1Zk>KJ zLfef%n@4JUF_2%V%>Si@Y5)tY-Zfah!E6CrsG&$p4{9+>jnvxFVTKkSI!d*qc$AhQ zhhdx^vps;{I!fyr(khzXVm2&wHVx1TMhk>Op(~Ukw}-HYXmcN=SCT_}Tef{I?KpLkd>8bBH7Sjm1j;3iSMnJ`aGC8)Etd ztvj{{8a^6jTHr|Fy(hyZ(!LY5Zt&n~`6u9Sn>kU77BiPQ8+bXa!!aw^2V12jT0l<> zUczd#$q-1K7Yf8QEBSqPq893*+{8R)k`{z@=r>85B+N83-#AHIEJI!;+FXOfdW9r$fG+!|xx;Xa}Q~ zOx4n*urzA%eB2Bz8vO{Jy5^tswc>l@G;N3(I46F`3{L*=sA8oGzL}==aJ!ll!84|7 ze!>IwzfyW`x+d;HYBSV?KUmd2tANaf8l zwI@-EQc9IJsw`EDt=mgAxzQOjOPNb^XK6bS*jR=pOTRKLALFfM%2U%`rrm}q6UtTA z4dn{mTjkoFn6=QR$@4+GUWXsJJ7&}5L9LA0S_|giKU*PNvt8@w2(QoMbsc`67=(DCI znN(e+4L7C8a8<3=n}1TJMS~@xT?I~yc;0puXtT?njZPBj* zncy@q;0&|KvSxbAtbyJgS(&olIo^gGRo%7owH)DI1yij^-k<_44!5MPf)kw5B{vYt zP$-zMO0a5efm;J}Oa-zv`>M5JrjAzT!E@VKk)%RZk+E(SDU=lvgbiZ_0Z0H>%2m=A zdXi?otyx}!k;R}LGW5RTT^8y!Yv;YrrKgKXkRi{U-Hpq>kskBsOz(H+|@2k~D zxaWfVB(qLg+-?qLV#lhAMU(ik5~)4iu5wo)&RE`1uZ5awWP3N&Yq_Qd8GgN9>kCWx z|5pEoOCSO+YhjD3{NV;|3OE~L8sR}3s1ygCl|WlDGk`B{)CS=83;d>IeVO=K6?l;l zE^>(pe0zZqo3#ukcA#?mqwo_s%9|8KG0> zWHXGFKboZHkjFQxAp`-~K5AAoffG_XRGqOvKC(qQz~;3mv+GBzax7o72=0Aty;|D}vrPOFt-_7a&LwIIc4CRLSFB65pOKJdnX*a- zEYlWX%GolO#y?u7ZNXU6a^<*bcLu&+?q<6RB1%|ht^ikNK95 z)82n`d{x?dKu0dCgoo8hIgY=7y(Z7;oV#9bTX^#`!D`}xBJeoVD&-e+4(pya(L$Gg z07-OB-O5vq`JE4ZTh6drzL82l;D7^)$$vEZy{7zYlS_yenzrT*G# z%Bmej9YApj8B@>JmdH5$JC>doJ5VPP?WIPRPi{S|!29DK(g z^Wp0>+}d}5|M-;4bu68+s4Kv6Jb*`R(ymuy9o)up5%~XF`x5x5ilp)PhF4)S8DIhd z5=dYI2?R(;GRfosLMD)e1c}_IKoY_P0y!WD1~3e|uDhRzc+z<6Dx!FRD2EJkDFUMG zs=(rb;DrZ^$9f;DyZTjC_au|N{rm0yzi)p1-gNitqq@7gy1Tl%8kxqDae*vjxod;r z<+6|1#auV1H?%Q~B})d`#ZT}jWDm~^SeQ@z9lMZ4Ecv`=Z&TlqH#`brs3!^J4oem& z@`g8Xa9U=`PDX_mx7=Z@OO`ce#L@q+J-S`i-kQ6RKYnbJks=dfXScfy-l+={?3{j= z!MnHYWMZg3oW08!L^IAX-Hw}>5^v-ky-{}?Z=q)O@9#Dybf&Y=T3iXT9?Pp!U8s-{ zxA=m+NGoASFH}v~(F>I&cJxAxi5 zyWKuhExOI{yUp;s&DHNVgP&mrKchYPKEk^UGyEB5_%qD#XPB!$!wi0g8T^a@_`Wvm z&oINEX@)8Y1eGm;WEweXPV*948Y$8ex@1xEHn679l-Y? z{8?uBv&`^knc>eeSAUin{46v0S*_svT8U4V8UAcD{MjAgNAR=F;Afk`&o+afjo|w_ zR6jE4JGMx+8UE~6_*=oxHi7R-F@f(&=?K2B+LdC0-<4v5-<4v5-<4vjepiYKd{>GI zd{;^v_&!DZT`6YxNjY!(>T#uZgumLAY6d^m41TH^{8R!TFHZ~_Zd|Em_*2dBr?$Z# z06*0XzRL{0%LKm9>EL%Ut~~Gx#nu_^u%EeRAk^nTKANdFXYenc#P& znZZvpgP&#wKaIinwX6O#GyG|0_|t;mSKz0atKU5Iy4nxDG<3Oq=AqYR9(rBoq1R;| zdR^wB*JU1hU4fyOM_wP#d|c+C*JU1hUFM~WIv9xK!)5}2~WeKcadJ4zm#zYiKLQo26&+Ole zmW3;xD7@9uf`G<|*B&>S+cZZ@y(OQ zl;UhVZmHMOZdz?4tJ2p>+Ce|rj=(QguurDM6zGe&sN`drZr7&UB`h45T@@kT%ofmTwWM%pw;a%oU{aJ-N1~fC8P`T(aPJ^Gk*CMWrN;!&{hRQTV;Z_ z%5IIUTvqB8A-fH^qEFgw#PzAM>(SG3uW?*Cs%cG>dNE6@P`+TfSi0MY?iOnc-bbww z8+RN1t_T8HkMmYmBKHv$0|fbM%i9&B$&4;d2q2l676#uDmV5^sIkIhK$NHM~%whWg0jd((tj-Z;6LPFSDTH?C!(wxC2_*jleoc0?tdC@;)pTYVV zk43F@&^i z|A)zl$b&`-@+gZB8qq$KjqtE+M4P;X-1Nmn+o29(4rYbuXr}z+-&*$IVMRu0y)t8J zU5(T>(iR#qfv|!_ta!-nm!dR>NbWM_898-j1Bxz7cB1_d%9DhPj6=pyEJFDqwQYIJ zAticy=#Z4A6_*2_A`crWA@Nf9e!^iRDI`_eTMiqZE;bEs4+sE0piuXW+6-9#jLP%iGe$CTmaO74wBa-%=2^oX5+$X)W;|=8g~Utydh%Z` z?R-e_t!E9^fWcn3=UID*9!De>H1zi6)(DY*Lcn;fnvY7fD3OddczUNSSqFio{AGv6W z!qbyRbVwC@+`jy_o&t^`e!Q|#P9$JGwrqT|LroI&0(WbSe3_~(spTD`=G6RPnlPZ&~1 z#FHnCdj3A}1+{Oq^##RG{_zDQQ1iry7gc^YzG%EcLH%=18l!c++<(`f3>@rdd>xYcpJCDY2580>R&e2(Xj)I$J5+` zP~s0=Xhhg6#uRFDsxDFXiZPIeKDR#3|@gL1K@(M=_4%t3TZb816RJf^6U zqg_@sxdjs_6xv2X{gD3nPbtf9@%R@p5ML^U^u_l?$}^V&X1;Ks$D~$&EH6bpz8zoF z=1XstV{`nxiPEFLDpJl^>88O1OMGp&Q3jLBoeDzw+_{)A;b-*j7!`f zYEP@(sJl+9-MllWjf-&@#-bVNB~`Vg0~7a@tLhe}I90lsDs5c)&zv#TwYVu~jRCZV zvgp@nNL6Q_HHvVJ@xWQ*6Ff0_^Q*>SJcb|NS#_X8uVSZ6?d%qzugP;QqVhEq%FXUP zNyL6`^z`?6-Iyw6#%kX%PEp zKSsUq^SBE??M=1YxB5-vcULv5G^jde2y8osQl#u@XPNr|LTK zBcsM1QG`cQ8+6^UXyxLM7mXxqQ=o=UUo-{|z!+R^M-fg*ao|D;-}35wsqZw>LkQz{ zyl+&?nrit#ZE-&Ef!gCe{R`eU74l(VPXD25U4*DwocYk`f#b~bbr30j{!mRO5U4j9 z=+2jnTJwu)^*oCcBlC|20rABrN>)7iQ+4uU!KZ4Io9TN31={ne6omJue`a*k5%&DQ zDfz?)|7I*>uqm)`f37Hh`RB$o_TKxsYT?W;R9(#fLP?wa^9y4(!#?v%;~s|5|MgeK zO%mF*-x$X@fr4)p60H4Jwdzmb;%Oa%s^mMl%k1Cuo$;`Y=J~-$;-=Fa=>^N`Di-HA zq2LUj3r=x5>3$^qF)pn8!FZ3bw3EN~?}oa8`i38kY#aG01U~*_V3&;Aa>Fl1zjUhe z&Y@bgx^i0&SfV5N_5q&%C@gZakF%~)Y@UH?W>)=Vgj3=H9J}==wU4$u3VMi3KN*AQ zYhYOG@ed`rxa}WCf4S@Tr=N{c!3lKv#TXDnQ3xhG$=cWF7?UX+<`-n`6X;zSXksny$&LQz!%#=|D zbdfS$9T-GhF*MPAyc&(--5m;&=&Z8AD55K9WF0Vhd)5X;bQ*93io4@4;MZFW34>uO zxJ->{()=*EL_+|Y8vN;xa0Z&&VC^VR;ly-H2E2x-gI&JIu zAqAX)@brMbl-yDp{^`fn7yCZ0)K>R^F-ZFl_ke+T@a!V~Nu22k!z1EwQGsd<8>TPQ zwE|3@Yql@~B(*;h0dm9p=LnF}X>)qQj6m!Mp(KD>vGUH*)x97&fM2fI5{4|H^`Im| zXK^k=-38UiMq%)N=mmwrO(@3ph6RKwB;(N-C<()~yEn9O(y5U!lG?EZA5j+xCut!$ zB2jfVKZrxI z@IC!t70#lQ`@;o}V0VH%JelW&|FRA-R9&5N!eIW6-YfjIv2anQGI=1()NA~Y4ul7E zl$e?j4?Yg|=Xlt}7VjXCg2)F3!D9A_8w|0D`9)5dt|ibm24;$1i`Sl>h4V7P;W z<9W2-vt@k(q|xwZHsVAARB@QpA@C_%`VEEK*s^mdOe7}4#mzUho0(Jf`@@I9RGp3p zwi;y4$R9UcLn35RzSK(K}`-+{1zA zV${3!7Chn|jieqA@-ET?7K|mX9S)Jy*v@HU=LJ+S^Tcqt9ecspWRSx2-zI|;)co=~ zNcTUI0`qkuh7N*_=_dDv6JKIfw+kW|%JD8mb+2}TpM8?kpnzt6YKpTm4Mwm(B`W@! z1`c-pJq@IiF!p{d8^Xk`=^(|^kNgIPiBsvSRp*TYx2SbPH;U(98Usr> zQWc7q$fb)vcPtE%k*e~cfg`<@51XhY&f-RARfFhX3`vyVeWIukdIx37Bg~>g1@ZTV zkipT1kAq@rL~8-|JPzX<2M=~kaApxi5^-R-nY_89ZeIjCN6_5|RA%Hp~S@F)jNEP=_Yf*I+%?SoWD!Wg`8#JdoMVjASZ zxaUe>5(n>br5e!-uY{sj@NT^l*7N876QMphH8BxVi7FDD0Rrn3pG^cQ3FMii+V18_ zutP8K=in{I76L;To~iJ2zZ^cI8JSXqbL_hMl{ouoT zsYFbC0arKAO;^*352piPH;VVj_F&VD*em?a5MTzAe>Xhdkb);bpHYf6-gD)bHGYN57i?Q zr!GUi0zng?$&xxU;AItRsQ7&a%pf1D|J@1**Tq*0VG6rNp%?hbyQud9vTDRmFO0N? zhN_Z(x)fOtVU-XS4C2sA7?p*I8M;l6%O69xMo^p6B@$!G8@#x%`n6f-&U?Wrc2$C# z5Mi<|KCZ;>sx@^NWs6`W^)B5(i)3;CA~@D%o{^8maa1JHl3vs;hGh}bYazN@jZJ*A z7#a!0eCa1Dsvwu~W=oZ#HiMUd57Fh}B_QSK-d_S9Mn$DCAZMwfrIVM!6 zni{y40cI-Orxv>6ba+TDEM{ho-cvWy$CNK>9hULXLugcNC(W~prYdtZZOJnHKl^A| zfPs=t@haJ+rl2W!h%g5|7vW=X41_~R)6CUDE*Fi^cxZ6qJp7+Z%pAOPIIh4;-9pov ztqy&G3_$FrQ3Y(z9$x1=u``g!K=fnp@%UaM9qgWsZ)!K<8sN3Y_(n5U{%Kk+E%}Jd zYFe7~n}EkYG%5!gl7pS;(6trPiSLG3U8Ay~p%SL)+RD+=iSI&PYwkgD&|IZ!_GtW{ zv0T^kGyk^tMzk}z#Q&Ozbatf?e)S|^Wuhk@qLS&Fi!X@wpq-ug3L9vf9bwU`&`Jw& zG;Ryc`zJ}qjM?l$NA$RUKDNhQxrh=A_@i~Q49h;39^ORrO14M3h`W{CiPDp%=5rLQ zThK|HrRJ=(#Srv)F;yZe>XCt|ybfjqpL~e0ak8ONH!Z@4u!FzgfBnkhfUChntf6EU zM<#L*NgOeD;lDJh{z2>R&dP}x!HSmg%g}MeEDX^yDwC))SefBTUTCBOzctc9ZNne& zUttDn8$!nwsz~g(uw#`B&ce1$!_cv4ppD3gk5ZgS&2G~&C@ZoyglWy*Qna8M#@kqw zO{=kMQ_xP;ar_w@<+U6is)DYX4d2}fG`wn?xP7X4e1Hp`UVNyI!?o_z!mhbg|J@lO z$DlhGpB}1pR?)n&TTiX;u(DJ87xdC>F`4KgO>d1grOjPh9Hk8+yv~ckS0Bxw_Klm1 zuV`&x4*p4VRXgbgr`A#i`(v@cX0FClTN3Hazk5ieW^VlwY4bpnaFZdodM17nx zUiu9qcLqLGDm25}A``aOq>`H|WH3Hx(%ZhHi)tn_kbg_^9MC&uPM#>(#2n>ylAH5qbURqNXm?9fK#Nd1hWk ze$*U<#6ykbiPDzKAlD+k>x__)Lk6 zu#`2GwG5&D=e7_em+#tYYol%Gfo2U=BAWOn`A<%&FXcoV`7EOHPQZuUPJCgihg|)W zJCS|LQrq+eH1MH0xdmU(@mh6;^uY@A(U(r17<|verxy~q)HT^?t7UcTXjx7~5RD=K zI=q!{cWTwRWWYD!2DOnipj|^qH-l&sc<@D|Q`MAgI^4Xh8|7a}H55XhCehf~S&mEY*QhrVktcd@)B53C8mil_+_7eMrA)eM_*x>r z;oHXqkCH({fQQrftIF_2W$aF_3Vc-k2WXzLVu`IMeM57##ZuNwbL3Qxle$t$x<}6K#((kEN-cHK;2RS&%#+3gm%I-Gx zjFdYRH|(xE6npUU9gv3Ok%+z%q7*t~mK_YyLXmr?#5Zy5P6f!3#!W8c!WR}#I*DKD=b(>%|f4;B@ zZV4)tzy2=R#9X6Lzx^Iqqo-kFhQ3mFrr=t;s^Z_<>A^MkxGos6)!4*8?}f$6tH1R2 zFZlz+)4m|?X-0`h{|Kjvd?25@C-VwEuhtPDzeM)UP+8?wOD4`DA#tF zqiJH&F{68&b81snMHRC80;ym?)w2Sy%@Z{b0gL_+#0>k!tq?&JUROay->r~9xJ4m6 zW4ckGeqzy9=+cus9kftHZcA&4#kE_3FDt@r5j-w_|5lJ};%Bx(veg@?)^E1LXle$| z*8MQ<_}IkkhasQa=#LMpUh>AnkV_0vPF!{K{*OQ^5eY7WnDz)H;B8bbkKi^+jVON< zcT}Hv1a_jV6WS%~e8r=XNJEn>bEJnazV3iAk@&sURJU&Egp0%5VYCQ)47SrWdXdMA zZ>$&j;~skV129m0{21(I$Tx3OWCIcEaNEoaV~O3{;VdQc%36FS$gM+6he-z~vj1^l zeF-9R3!wUH3}q8}M{)nTVh8l<6OEe4r6vd(VR+#msLKsIz)N*WwIaUX0W+z!0w1S6 z0Rwv}ts1N#gQHVXGEmw4y8&O6FJT;@wwJNWr$r=px3Rg1GoZ zzHT;1pGHdCb*T*~)g~{(x#kH)1obBsiQ;bQPk z7|qql8z8H8LIzcs+)52pdeD9$2Iwt5+bQwOZ{Gz!>&P7r+oRa7o;@J-R-nZx9^WI` z$%0*9wR2@Y1yTSTzeS1_Pk}QmD$J^LR!({RfA>?65Ec`rTdaC0*YgKYK?=j#b1xKz z#$s?g`!CoFSJ5UW`r@`7_@S68*D_m7_CqvBsP%)3{pN`+eznJmegnj1Kg1AmwU%RQ zafCer8TN9Ieat=uK3)tL-wnyX7h8#fIPJNZaa>FkF0ktiQt_X2=Gai|bI0!@9B2PZ3iWdmr5RV*`(;UGmoIBW- zdW1jb5U2}3=NyJYPG<9AHDkJbI2dZw8_?YtPNhMm00~`rI6;>*V$Cz~h};BNXF*D_ z=UK^*|92;myE*5Mv&G>e?zm#pyN@e8#tGUe4!rYt$H^aizw|sDU<=LUx;q0@A4QXZ z=t7tXzX9ZNZJz1{PYB1;_)9o2!8yH_u8_xF$o4bT%`d2}KaLy!qN-P%K4yv4FM<@< zUjI8~;XpK(WO!;$!Z@1fh3EyA2-8Hev9`K_H^$p0l75^>=F2Hx%*&9*V%~DR?AS|wkl~LenAG+9iD(*|LPBt2YJp2XsDk^5+#2aOKD7+(! zeWx`C`=zkoIB%`Dp{jvGrOQzAd{&i@HNS<)>w)0|vfe+KeG;_W;hym$uQ2`P}W3fuppI^gSn!39gWeTZ0b7H;QO zvb~BVG}|5}ie7~!Hk;kCu)MK6+g>aVz6!@V#C5NMTQ3p&UQ<(g=j-qQe>nO&sfibI`k}-0sC&F)Hx1 zNTWB-QCVMC^M9K`?{fP}yOv(jR8J?5NPl6)QffYN-J6R3?0OS&sD5N^ef=h+6W7G9 zd0J(0ODn6YQ4+$iH#g#eu{<&MJj`p0@!)wyJwH4T*Fh8`!jcPe4n%!HY`XyOam%cK zOHF=GyajcHClD^O--aw&9NDdn&EfV0hOd`u4@d3`ClQA@omOY5#i(Vx;~bioYzF~DmsK@mqeaY@ozf5>0q4p|NNTvn^1 zZ!fFSXz<4{E-Bn@ulCkb|FUcO%bUFQD;fV5dP!qzvU!T;mOfk7wp zQ#IuOe?V9G89cAkG98Ve>L4_CF2X}vwN6xTB{qKm%~&N^H8+X{U#P+D(JvrZ)ssm2 z5*Zve(ex!qty`absrVSvzv7rLf2HJQ%D+~EAoqR^wZ15OVvr(D%oBnRJEBvg&lO&Y z^7eLT9*dUNV#SvRMW;?0d{~m=C&>7;c1s9KT6NNq|66K6qg)#`fW-0&yor_;i4BeA zj0kUk1IgW^>~YPFrIk%|X)5jNnc-je={o{{~{A$({fJ diff --git a/tangle-subxt/src/tangle_testnet_runtime.rs b/tangle-subxt/src/tangle_testnet_runtime.rs index 5df05515..7e7bbecf 100644 --- a/tangle-subxt/src/tangle_testnet_runtime.rs +++ b/tangle-subxt/src/tangle_testnet_runtime.rs @@ -1,4 +1,4 @@ -#[allow(dead_code, unused_imports, non_camel_case_types, unreachable_patterns)] +#[allow(dead_code, unused_imports, non_camel_case_types)] #[allow(clippy::all)] #[allow(rustdoc::broken_intra_doc_links)] pub mod api { @@ -6,7 +6,7 @@ pub mod api { mod root_mod { pub use super::*; } - pub static PALLETS: [&str; 43usize] = [ + pub static PALLETS: [&str; 44usize] = [ "System", "Timestamp", "Sudo", @@ -50,6 +50,7 @@ pub mod api { "MultiAssetDelegation", "Services", "Lst", + "Rewards", ]; pub static RUNTIME_APIS: [&str; 16usize] = [ "Core", @@ -69,13 +70,13 @@ pub mod api { "TxPoolRuntimeApi", "GenesisBuilder", ]; - #[doc = r" The error type that is returned when there is a runtime issue."] + #[doc = r" The error type returned when there is a runtime issue."] pub type DispatchError = runtime_types::sp_runtime::DispatchError; #[doc = r" The outer event enum."] pub type Event = runtime_types::tangle_testnet_runtime::RuntimeEvent; #[doc = r" The outer extrinsic enum."] pub type Call = runtime_types::tangle_testnet_runtime::RuntimeCall; - #[doc = r" The outer error enum represents the DispatchError's Module variant."] + #[doc = r" The outer error enum representing the DispatchError's Module variant."] pub type Error = runtime_types::tangle_testnet_runtime::RuntimeError; pub fn constants() -> ConstantsApi { ConstantsApi @@ -237,7 +238,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Version {} @@ -260,7 +260,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExecuteBlock { @@ -286,7 +285,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct InitializeBlock { @@ -383,7 +381,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Metadata {} @@ -407,7 +404,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MetadataAtVersion { @@ -431,7 +427,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MetadataVersions {} @@ -545,7 +540,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ApplyExtrinsic { @@ -571,7 +565,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct FinalizeBlock {} @@ -594,7 +587,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct InherentExtrinsics { @@ -620,7 +612,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckInherents { @@ -681,7 +672,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct QueryServicesWithBlueprintsByOperator { @@ -1083,7 +1073,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ChainId {} @@ -1106,7 +1095,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccountBasic { @@ -1130,7 +1118,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GasPrice {} @@ -1153,7 +1140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccountCodeAt { @@ -1177,7 +1163,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Author {} @@ -1201,7 +1186,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct StorageAt { @@ -1248,7 +1232,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Call { @@ -1300,7 +1283,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Create { @@ -1336,7 +1318,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentBlock {} @@ -1362,7 +1343,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentReceipts {} @@ -1386,7 +1366,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentTransactionStatuses {} @@ -1424,7 +1403,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentAll {} @@ -1449,7 +1427,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExtrinsicFilter { @@ -1475,7 +1452,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Elasticity {} @@ -1497,7 +1473,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GasLimitMultiplierSupport {} @@ -1531,7 +1506,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PendingBlock { @@ -1557,7 +1531,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct InitializePendingBlock { @@ -1610,7 +1583,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ConvertTransaction { @@ -1678,7 +1650,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ValidateTransaction { @@ -1736,7 +1707,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OffchainWorker { @@ -1821,7 +1791,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GenerateSessionKeys { @@ -1851,7 +1820,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct DecodeSessionKeys { @@ -2023,7 +1991,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Configuration {} @@ -2045,7 +2012,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentEpochStart {} @@ -2067,7 +2033,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentEpoch {} @@ -2089,7 +2054,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NextEpoch {} @@ -2115,7 +2079,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GenerateKeyOwnershipProof { @@ -2149,7 +2112,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SubmitReportEquivocationUnsignedExtrinsic { @@ -2208,7 +2170,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccountNonce { @@ -2323,7 +2284,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct QueryInfo { @@ -2353,7 +2313,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct QueryFeeDetails { @@ -2379,7 +2338,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct QueryWeightToFee { @@ -2404,7 +2362,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct QueryLengthToFee { @@ -2553,7 +2510,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GrandpaAuthorities {} @@ -2581,7 +2537,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SubmitReportEquivocationUnsignedExtrinsic { @@ -2611,7 +2566,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GenerateKeyOwnershipProof { @@ -2636,7 +2590,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CurrentSetId {} @@ -2753,7 +2706,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TraceTransaction { @@ -2785,7 +2737,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TraceBlock { @@ -2830,7 +2781,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TraceCall { @@ -2894,7 +2844,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExtrinsicFilter { @@ -3014,7 +2963,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BuildState { @@ -3041,7 +2989,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GetPreset { @@ -3066,7 +3013,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PresetNames {} @@ -3302,6 +3248,9 @@ pub mod api { pub fn lst(&self) -> lst::storage::StorageApi { lst::storage::StorageApi } + pub fn rewards(&self) -> rewards::storage::StorageApi { + rewards::storage::StorageApi + } } pub struct TransactionApi; impl TransactionApi { @@ -3418,6 +3367,9 @@ pub mod api { pub fn lst(&self) -> lst::calls::TransactionApi { lst::calls::TransactionApi } + pub fn rewards(&self) -> rewards::calls::TransactionApi { + rewards::calls::TransactionApi + } } #[doc = r" check whether the metadata provided is aligned with this statically generated code."] pub fn is_codegen_valid_for(metadata: &::subxt_core::Metadata) -> bool { @@ -3428,9 +3380,9 @@ pub mod api { .hash(); runtime_metadata_hash == [ - 16u8, 52u8, 194u8, 223u8, 160u8, 251u8, 199u8, 104u8, 70u8, 232u8, 82u8, 80u8, - 163u8, 50u8, 140u8, 21u8, 236u8, 64u8, 132u8, 72u8, 118u8, 27u8, 91u8, 195u8, - 240u8, 29u8, 231u8, 116u8, 119u8, 147u8, 226u8, 170u8, + 97u8, 106u8, 210u8, 161u8, 133u8, 87u8, 56u8, 120u8, 94u8, 250u8, 106u8, 137u8, + 172u8, 7u8, 138u8, 164u8, 222u8, 19u8, 172u8, 132u8, 102u8, 174u8, 34u8, 137u8, + 128u8, 69u8, 160u8, 42u8, 193u8, 185u8, 33u8, 93u8, ] } pub mod system { @@ -3457,7 +3409,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Make some on-chain remark."] @@ -3485,7 +3436,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the number of pages in the WebAssembly environment's heap."] @@ -3511,7 +3461,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the new runtime code."] @@ -3537,7 +3486,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the new runtime code without doing any checks of the given `code`."] @@ -3566,7 +3514,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set some items of storage."] @@ -3595,7 +3542,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Kill some items from storage."] @@ -3623,7 +3569,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Kill all storage items with a key that starts with the given prefix."] @@ -3654,7 +3599,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Make some on-chain remark and emit event."] @@ -3680,7 +3624,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied"] @@ -3709,7 +3652,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied"] @@ -3742,7 +3684,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Provide the preimage (runtime binary) `code` for an upgrade that has been authorized."] @@ -3997,7 +3938,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An extrinsic completed successfully."] @@ -4023,7 +3963,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An extrinsic failed."] @@ -4051,7 +3990,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "`:code` was updated."] @@ -4071,7 +4009,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new account was created."] @@ -4097,7 +4034,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account was reaped."] @@ -4123,7 +4059,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "On on-chain remark happened."] @@ -4151,7 +4086,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An upgrade was authorized."] @@ -4566,9 +4500,10 @@ pub mod api { "Events", (), [ - 37u8, 18u8, 99u8, 14u8, 225u8, 158u8, 233u8, 70u8, 73u8, 126u8, 8u8, - 15u8, 172u8, 132u8, 97u8, 19u8, 109u8, 32u8, 5u8, 250u8, 100u8, 58u8, - 201u8, 228u8, 184u8, 76u8, 192u8, 255u8, 190u8, 111u8, 216u8, 3u8, + 66u8, 225u8, 157u8, 197u8, 20u8, 49u8, 178u8, 155u8, 55u8, 247u8, + 244u8, 27u8, 204u8, 232u8, 170u8, 209u8, 107u8, 126u8, 128u8, 38u8, + 194u8, 244u8, 116u8, 216u8, 187u8, 237u8, 159u8, 35u8, 247u8, 158u8, + 91u8, 69u8, ], ) } @@ -4892,7 +4827,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the current time."] @@ -5079,7 +5013,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authenticates the sudo key and dispatches a function call with `Root` origin."] @@ -5105,7 +5038,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authenticates the sudo key and dispatches a function call with `Root` origin."] @@ -5137,7 +5069,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authenticates the current sudo key and sets the given AccountId (`new`) as the new sudo"] @@ -5167,7 +5098,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Authenticates the sudo key and dispatches a function call with `Signed` origin from"] @@ -5201,7 +5131,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Permanently removes the sudo key."] @@ -5225,10 +5154,9 @@ pub mod api { "sudo", types::Sudo { call: ::subxt_core::alloc::boxed::Box::new(call) }, [ - 63u8, 236u8, 33u8, 140u8, 66u8, 52u8, 171u8, 126u8, 132u8, 239u8, 52u8, - 230u8, 167u8, 124u8, 236u8, 255u8, 223u8, 26u8, 2u8, 252u8, 96u8, - 144u8, 167u8, 127u8, 192u8, 151u8, 54u8, 126u8, 181u8, 147u8, 61u8, - 84u8, + 104u8, 243u8, 183u8, 73u8, 83u8, 234u8, 164u8, 179u8, 6u8, 107u8, 67u8, + 149u8, 235u8, 16u8, 42u8, 90u8, 249u8, 201u8, 222u8, 150u8, 170u8, + 30u8, 43u8, 196u8, 37u8, 157u8, 170u8, 67u8, 59u8, 221u8, 169u8, 188u8, ], ) } @@ -5250,9 +5178,9 @@ pub mod api { weight, }, [ - 149u8, 130u8, 21u8, 8u8, 53u8, 54u8, 76u8, 254u8, 96u8, 250u8, 21u8, - 188u8, 237u8, 163u8, 26u8, 229u8, 63u8, 105u8, 62u8, 183u8, 183u8, - 60u8, 214u8, 186u8, 138u8, 23u8, 35u8, 170u8, 171u8, 19u8, 11u8, 55u8, + 215u8, 34u8, 23u8, 153u8, 100u8, 61u8, 32u8, 12u8, 189u8, 228u8, 72u8, + 213u8, 232u8, 117u8, 226u8, 202u8, 5u8, 38u8, 106u8, 93u8, 8u8, 90u8, + 249u8, 226u8, 10u8, 112u8, 234u8, 229u8, 102u8, 33u8, 5u8, 100u8, ], ) } @@ -5288,10 +5216,9 @@ pub mod api { "sudo_as", types::SudoAs { who, call: ::subxt_core::alloc::boxed::Box::new(call) }, [ - 22u8, 72u8, 255u8, 17u8, 244u8, 151u8, 81u8, 212u8, 43u8, 9u8, 25u8, - 196u8, 240u8, 47u8, 84u8, 200u8, 146u8, 78u8, 234u8, 170u8, 89u8, - 197u8, 167u8, 70u8, 80u8, 71u8, 246u8, 195u8, 147u8, 158u8, 118u8, - 151u8, + 44u8, 47u8, 139u8, 71u8, 178u8, 40u8, 185u8, 191u8, 46u8, 165u8, 200u8, + 70u8, 32u8, 77u8, 82u8, 205u8, 30u8, 69u8, 11u8, 254u8, 44u8, 116u8, + 105u8, 77u8, 199u8, 188u8, 54u8, 13u8, 79u8, 115u8, 51u8, 242u8, ], ) } @@ -5330,7 +5257,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A sudo call just took place."] @@ -5357,7 +5283,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The sudo key has been updated."] @@ -5385,7 +5310,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The key was permanently removed."] @@ -5405,7 +5329,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A [sudo_as](Pallet::sudo_as) call just took place."] @@ -5525,7 +5448,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Issue a new class of fungible assets from a public origin."] @@ -5577,7 +5499,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Issue a new class of fungible assets from a privileged origin."] @@ -5632,7 +5553,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Start the process of destroying a fungible asset class."] @@ -5669,7 +5589,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Destroy all accounts associated with a given asset."] @@ -5707,7 +5626,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Destroy all approvals associated with a given asset up to the max (T::RemoveItemsLimit)."] @@ -5745,7 +5663,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Complete destroying asset and unreserve currency."] @@ -5781,7 +5698,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Mint assets of a particular class."] @@ -5827,7 +5743,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Reduce the balance of `who` by as much as possible up to `amount` assets of `id`."] @@ -5876,7 +5791,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Move some assets from the sender account to another."] @@ -5928,7 +5842,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Move some assets from the sender account to another, keeping the sender account alive."] @@ -5980,7 +5893,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Move some assets from one account to another."] @@ -6038,7 +5950,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Disallow further unprivileged transfers of an asset `id` from an account `who`. `who`"] @@ -6081,7 +5992,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allow unprivileged transfers to and from an account again."] @@ -6122,7 +6032,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Disallow further unprivileged transfers for the asset class."] @@ -6157,7 +6066,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allow unprivileged transfers for the asset again."] @@ -6192,7 +6100,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Change the Owner of an asset."] @@ -6233,7 +6140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Change the Issuer, Admin and Freezer of an asset."] @@ -6286,7 +6192,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the metadata for an asset."] @@ -6334,7 +6239,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clear the metadata for an asset."] @@ -6371,7 +6275,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force the metadata for an asset to some value."] @@ -6419,7 +6322,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clear the metadata for an asset."] @@ -6456,7 +6358,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Alter the attributes of a given asset."] @@ -6531,7 +6432,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Approve an amount of asset for transfer by a delegated third-party account."] @@ -6585,7 +6485,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel all of some asset approved for delegated transfer by a third-party account."] @@ -6629,7 +6528,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel all of some asset approved for delegated transfer by a third-party account."] @@ -6678,7 +6576,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Transfer some asset balance from a previously delegated account to some third-party"] @@ -6735,7 +6632,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create an asset account for non-provider assets."] @@ -6770,7 +6666,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Return the deposit (if any) of an asset account or a consumer reference (if any) of an"] @@ -6808,7 +6703,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Sets the minimum balance of an asset."] @@ -6848,7 +6742,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create an asset account for `who`."] @@ -6889,7 +6782,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Return the deposit (if any) of a target asset account. Useful if you are the depositor."] @@ -6930,7 +6822,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Disallow further unprivileged transfers of an asset `id` to and from an account `who`."] @@ -7956,7 +7847,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some asset class was created."] @@ -7986,7 +7876,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some assets were issued."] @@ -8016,7 +7905,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some assets were transferred."] @@ -8048,7 +7936,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some assets were destroyed."] @@ -8078,7 +7965,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The management team changed."] @@ -8110,7 +7996,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The owner changed."] @@ -8138,7 +8023,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some account `who` was frozen."] @@ -8166,7 +8050,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some account `who` was thawed."] @@ -8194,7 +8077,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some asset `asset_id` was frozen."] @@ -8220,7 +8102,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some asset `asset_id` was thawed."] @@ -8246,7 +8127,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Accounts were destroyed for given asset."] @@ -8276,7 +8156,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Approvals were destroyed for given asset."] @@ -8306,7 +8185,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An asset class is in the process of being destroyed."] @@ -8332,7 +8210,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An asset class was destroyed."] @@ -8358,7 +8235,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some asset class was force-created."] @@ -8386,7 +8262,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "New metadata has been set for an asset."] @@ -8420,7 +8295,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Metadata has been cleared for an asset."] @@ -8446,7 +8320,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "(Additional) funds have been approved for transfer to a destination account."] @@ -8478,7 +8351,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An approval for account `delegate` was cancelled by `owner`."] @@ -8508,7 +8380,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An `amount` was transferred in its entirety from `owner` to `destination` by"] @@ -8543,7 +8414,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An asset has had its attributes changed by the `Force` origin."] @@ -8569,7 +8439,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The min_balance of an asset has been updated by the asset owner."] @@ -8597,7 +8466,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some account `who` was created with a deposit from `depositor`."] @@ -8627,7 +8495,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some account `who` was blocked."] @@ -8655,7 +8522,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some assets were deposited (e.g. for transaction fees)."] @@ -8685,7 +8551,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some assets were withdrawn from the account (e.g. for transaction fees)."] @@ -9198,7 +9063,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Transfer some liquid free balance to another account."] @@ -9236,7 +9100,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Exactly as `transfer_allow_death`, except the origin must be root and the source account"] @@ -9274,7 +9137,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Same as the [`transfer_allow_death`] call, but with a check that the transfer will not"] @@ -9311,7 +9173,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Transfer the entire transferable balance from the caller account."] @@ -9356,7 +9217,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unreserve some balance from a user by force."] @@ -9389,7 +9249,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Upgrade a specified account."] @@ -9422,7 +9281,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the regular balance of a given account."] @@ -9456,7 +9314,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Adjust the total issuance in a saturating way."] @@ -9489,7 +9346,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Burn the specified liquid free balance from the origin account."] @@ -9738,7 +9594,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account was created with some free balance."] @@ -9766,7 +9621,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account was removed whose balance was non-zero but below ExistentialDeposit,"] @@ -9795,7 +9649,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Transfer succeeded."] @@ -9825,7 +9678,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A balance was set by root."] @@ -9853,7 +9705,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was reserved (moved from free to reserved)."] @@ -9881,7 +9732,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was unreserved (moved from reserved to free)."] @@ -9909,7 +9759,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was moved from the reserve of the first account to the second account."] @@ -9943,7 +9792,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was deposited (e.g. for transaction fees)."] @@ -9971,7 +9819,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was withdrawn from the account (e.g. for transaction fees)."] @@ -9999,7 +9846,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was removed from the account (e.g. for misbehavior)."] @@ -10027,7 +9873,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was minted into an account."] @@ -10055,7 +9900,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was burned from an account."] @@ -10083,7 +9927,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was suspended from an account (it can be restored later)."] @@ -10111,7 +9954,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some amount was restored into an account."] @@ -10139,7 +9981,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account was upgraded."] @@ -10165,7 +10006,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Total issuance was increased by `amount`, creating a credit to be balanced."] @@ -10191,7 +10031,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Total issuance was decreased by `amount`, creating a debt to be balanced."] @@ -10217,7 +10056,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was locked."] @@ -10245,7 +10083,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was unlocked."] @@ -10273,7 +10110,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was frozen."] @@ -10301,7 +10137,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some balance was thawed."] @@ -10329,7 +10164,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `TotalIssuance` was forcefully changed."] @@ -10822,7 +10656,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A transaction fee `actual_fee`, of which `tip` was added to the minimum inclusion fee,"] @@ -11008,7 +10841,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Report authority equivocation/misbehavior. This method will verify"] @@ -11046,7 +10878,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Report authority equivocation/misbehavior. This method will verify"] @@ -11089,7 +10920,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Plan an epoch config change. The epoch config change is recorded and will be enacted on"] @@ -11813,7 +11643,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Report voter equivocation/misbehavior. This method will verify the"] @@ -11849,7 +11678,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Report voter equivocation/misbehavior. This method will verify the"] @@ -11891,7 +11719,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Note that the current authority set of the GRANDPA finality gadget has stalled."] @@ -12024,7 +11851,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "New authority set has been applied."] @@ -12053,7 +11879,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Current authority set has been paused."] @@ -12073,7 +11898,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Current authority set has been resumed."] @@ -12399,7 +12223,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Assign an previously unassigned index."] @@ -12436,7 +12259,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Assign an index already owned by the sender to another account. The balance reservation"] @@ -12478,7 +12300,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Free up an index owned by the sender."] @@ -12515,7 +12336,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force an index to an account. This doesn't require a deposit. If the index is already"] @@ -12560,7 +12380,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Freeze an index so it will always point to the sender account. This consumes the"] @@ -12749,7 +12568,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A account index was assigned."] @@ -12777,7 +12595,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A account index has been freed up (unassigned)."] @@ -12803,7 +12620,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A account index has been frozen to its current account ID."] @@ -12929,7 +12745,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose a sensitive action to be taken."] @@ -12969,7 +12784,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Signals agreement with a particular proposal."] @@ -13001,7 +12815,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Vote in a referendum. If `vote.is_aye()`, the vote is to enact the proposal;"] @@ -13037,7 +12850,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule an emergency cancellation of a referendum. Cannot happen twice to the same"] @@ -13070,7 +12882,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a referendum to be tabled once it is legal to schedule an external"] @@ -13104,7 +12915,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a majority-carries referendum to be tabled next once it is legal to schedule"] @@ -13143,7 +12953,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a negative-turnout-bias referendum to be tabled next once it is legal to"] @@ -13182,7 +12991,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule the currently externally-proposed majority-carries referendum to be tabled"] @@ -13227,7 +13035,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Veto and blacklist the external proposal hash."] @@ -13261,7 +13068,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a referendum."] @@ -13294,7 +13100,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Delegate the voting power (with some given conviction) of the sending account."] @@ -13346,7 +13151,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Undelegate the voting power of the sending account."] @@ -13377,7 +13181,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clears all public proposals."] @@ -13401,7 +13204,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unlock tokens that have an expired lock."] @@ -13436,7 +13238,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a vote for a referendum."] @@ -13488,7 +13289,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a vote for a referendum."] @@ -13533,7 +13333,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Permanently place a proposal into the blacklist. This prevents it from ever being"] @@ -13575,7 +13374,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a proposal."] @@ -13608,7 +13406,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set or clear a metadata of a proposal or a referendum."] @@ -14173,7 +13970,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion has been proposed by a public account."] @@ -14201,7 +13997,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A public proposal has been tabled for referendum vote."] @@ -14229,7 +14024,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An external proposal has been tabled."] @@ -14249,7 +14043,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A referendum has begun."] @@ -14277,7 +14070,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proposal has been approved by referendum."] @@ -14303,7 +14095,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proposal has been rejected by referendum."] @@ -14329,7 +14120,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A referendum has been cancelled."] @@ -14355,7 +14145,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has delegated their vote to another account."] @@ -14383,7 +14172,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has cancelled a previous delegation operation."] @@ -14409,7 +14197,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An external proposal has been vetoed."] @@ -14439,7 +14226,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proposal_hash has been blacklisted permanently."] @@ -14465,7 +14251,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has voted in a referendum"] @@ -14496,7 +14281,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has seconded a proposal"] @@ -14524,7 +14308,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proposal got canceled."] @@ -14550,7 +14333,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Metadata for a proposal or a referendum has been set."] @@ -14578,7 +14360,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Metadata for a proposal or a referendum has been cleared."] @@ -14606,7 +14387,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Metadata has been transferred to new owner."] @@ -15374,7 +15154,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the collective's membership."] @@ -15428,7 +15207,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatch a proposal from a member using the `Member` origin."] @@ -15465,7 +15243,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add a new proposal to either be voted on or executed directly."] @@ -15510,7 +15287,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add an aye or nay vote for the sender to the given proposal."] @@ -15549,7 +15325,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Disapprove a proposal, close, and remove it from the system, regardless of its current"] @@ -15584,7 +15359,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Close a vote that is either approved, disapproved or whose voting period has ended."] @@ -15697,9 +15471,10 @@ pub mod api { length_bound, }, [ - 56u8, 142u8, 73u8, 187u8, 202u8, 107u8, 198u8, 64u8, 249u8, 99u8, 66u8, - 192u8, 191u8, 100u8, 77u8, 82u8, 202u8, 181u8, 252u8, 77u8, 137u8, - 205u8, 164u8, 76u8, 26u8, 82u8, 186u8, 84u8, 24u8, 114u8, 138u8, 162u8, + 177u8, 185u8, 60u8, 203u8, 108u8, 119u8, 224u8, 73u8, 94u8, 154u8, 7u8, + 37u8, 77u8, 100u8, 193u8, 219u8, 235u8, 133u8, 224u8, 150u8, 208u8, + 253u8, 134u8, 7u8, 121u8, 145u8, 163u8, 72u8, 119u8, 237u8, 139u8, + 165u8, ], ) } @@ -15732,10 +15507,9 @@ pub mod api { length_bound, }, [ - 170u8, 66u8, 235u8, 187u8, 97u8, 63u8, 88u8, 193u8, 129u8, 225u8, - 100u8, 113u8, 111u8, 184u8, 160u8, 156u8, 108u8, 81u8, 218u8, 105u8, - 183u8, 55u8, 13u8, 25u8, 1u8, 72u8, 74u8, 228u8, 24u8, 186u8, 62u8, - 175u8, + 78u8, 80u8, 61u8, 233u8, 178u8, 156u8, 126u8, 234u8, 121u8, 226u8, + 143u8, 185u8, 190u8, 210u8, 79u8, 141u8, 93u8, 193u8, 24u8, 233u8, 0u8, + 50u8, 65u8, 31u8, 51u8, 218u8, 113u8, 69u8, 121u8, 82u8, 92u8, 239u8, ], ) } @@ -15850,7 +15624,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion (given hash) has been proposed (by given account) with a threshold (given"] @@ -15883,7 +15656,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion (given hash) has been voted on by given account, leaving"] @@ -15918,7 +15690,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion was approved by the required threshold."] @@ -15944,7 +15715,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion was not approved by the required threshold."] @@ -15970,7 +15740,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A motion was executed; result will be `Ok` if it returned without error."] @@ -15999,7 +15768,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A single member did some action; result will be `Ok` if it returned without error."] @@ -16028,7 +15796,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proposal was closed because its threshold was reached or after its duration was up."] @@ -16124,10 +15891,10 @@ pub mod api { "ProposalOf", (), [ - 105u8, 80u8, 28u8, 109u8, 122u8, 113u8, 36u8, 149u8, 113u8, 155u8, - 102u8, 177u8, 84u8, 88u8, 116u8, 172u8, 200u8, 119u8, 54u8, 231u8, - 222u8, 138u8, 196u8, 170u8, 254u8, 115u8, 74u8, 6u8, 189u8, 66u8, - 245u8, 48u8, + 185u8, 49u8, 29u8, 63u8, 134u8, 160u8, 131u8, 52u8, 195u8, 14u8, 233u8, + 173u8, 155u8, 140u8, 220u8, 255u8, 111u8, 249u8, 87u8, 92u8, 171u8, + 142u8, 229u8, 54u8, 181u8, 176u8, 137u8, 203u8, 106u8, 175u8, 39u8, + 62u8, ], ) } @@ -16147,10 +15914,10 @@ pub mod api { "ProposalOf", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 105u8, 80u8, 28u8, 109u8, 122u8, 113u8, 36u8, 149u8, 113u8, 155u8, - 102u8, 177u8, 84u8, 88u8, 116u8, 172u8, 200u8, 119u8, 54u8, 231u8, - 222u8, 138u8, 196u8, 170u8, 254u8, 115u8, 74u8, 6u8, 189u8, 66u8, - 245u8, 48u8, + 185u8, 49u8, 29u8, 63u8, 134u8, 160u8, 131u8, 52u8, 195u8, 14u8, 233u8, + 173u8, 155u8, 140u8, 220u8, 255u8, 111u8, 249u8, 87u8, 92u8, 171u8, + 142u8, 229u8, 54u8, 181u8, 176u8, 137u8, 203u8, 106u8, 175u8, 39u8, + 62u8, ], ) } @@ -16310,7 +16077,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unlock any vested funds of the sender account."] @@ -16338,7 +16104,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unlock any vested funds of a `target` account."] @@ -16377,7 +16142,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a vested transfer."] @@ -16423,7 +16187,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force a vested transfer."] @@ -16475,7 +16238,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Merge two vesting schedules together, creating a new vesting schedule that unlocks over"] @@ -16523,7 +16285,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force remove a vesting schedule"] @@ -16738,7 +16499,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The amount vested has been updated. This could indicate a change in funds available."] @@ -16767,7 +16527,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An \\[account\\] has become fully vested."] @@ -16931,7 +16690,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Vote for a set of candidates for the upcoming round of election. This can be called to"] @@ -16979,7 +16737,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove `origin` as a voter."] @@ -17003,7 +16760,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Submit oneself for candidacy. A fixed amount of deposit is recorded."] @@ -17044,7 +16800,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Renounce one's intention to be a candidate for the next election round. 3 potential"] @@ -17089,7 +16844,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a particular member from the set. This is effective immediately and the bond of"] @@ -17137,7 +16891,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clean all voters who are defunct (i.e. they do not serve any purpose at all). The"] @@ -17363,7 +17116,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new term with new_members. This indicates that enough candidates existed to run"] @@ -17396,7 +17148,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "No (or not enough) candidates existed for this round. This is different from"] @@ -17417,7 +17168,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Internal error happened while trying to perform election."] @@ -17437,7 +17187,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has been removed. This should always be followed by either `NewTerm` or"] @@ -17464,7 +17213,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Someone has renounced their candidacy."] @@ -17490,7 +17238,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A candidate was slashed by amount due to failing to obtain a seat as member or"] @@ -17521,7 +17268,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A seat holder was slashed by amount by being forcefully removed from the set."] @@ -17923,7 +17669,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Submit a solution for the unsigned phase."] @@ -17968,7 +17713,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a new value for `MinimumUntrustedScore`."] @@ -17999,7 +17743,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a solution in the queue, to be handed out to the client of this pallet in the next"] @@ -18035,7 +17778,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Submit a solution for the signed phase."] @@ -18072,7 +17814,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Trigger the governance fallback."] @@ -18237,7 +17978,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A solution was stored with the given compute."] @@ -18274,7 +18014,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The election has been finalized, with the given computation and score."] @@ -18303,7 +18042,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An election failed."] @@ -18325,7 +18063,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has been rewarded for their signed submission being finalized."] @@ -18353,7 +18090,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has been slashed for submitting an invalid signed submission."] @@ -18381,7 +18117,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "There was a phase transition in a given round."] @@ -19012,7 +18747,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Take the origin account as a stash and lock up `value` of its balance. `controller` will"] @@ -19058,7 +18792,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add some extra amount that have appeared in the stash `free_balance` into the balance up"] @@ -19098,7 +18831,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a portion of the stash to be unlocked ready for transfer out after the bond"] @@ -19143,7 +18875,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove any unlocked chunks from the `unlocking` queue from our management."] @@ -19191,7 +18922,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Declare the desire to validate for the origin controller."] @@ -19221,7 +18951,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Declare the desire to nominate `targets` for the origin controller."] @@ -19261,7 +18990,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Declare no desire to either validate or nominate."] @@ -19290,7 +19018,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "(Re-)set the payment target for a controller."] @@ -19329,7 +19056,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "(Re-)sets the controller of a stash to the stash itself. This function previously"] @@ -19362,7 +19088,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Sets the ideal number of validators."] @@ -19394,7 +19119,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Increments the ideal number of validators up to maximum of"] @@ -19427,7 +19151,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Scale up the ideal number of validators by a factor up to maximum of"] @@ -19459,7 +19182,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force there to be no new eras indefinitely."] @@ -19491,7 +19213,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force there to be a new era at the end of the next session. After this, it will be"] @@ -19524,7 +19245,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the validators who cannot be slashed (if any)."] @@ -19553,7 +19273,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force a current staker to become completely unstaked, immediately."] @@ -19588,7 +19307,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force there to be a new era at the end of sessions indefinitely."] @@ -19616,7 +19334,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel enactment of a deferred slash."] @@ -19648,7 +19365,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pay out next page of the stakers behind a validator for the given era."] @@ -19688,7 +19404,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Rebond a portion of the stash scheduled to be unlocked."] @@ -19721,7 +19436,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove all data structures concerning a staker/stash once it is at a state where it can"] @@ -19766,7 +19480,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove the given nominations from the calling validator."] @@ -19807,7 +19520,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Update the various staking configurations ."] @@ -19882,7 +19594,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Declare a `controller` to stop participating as either a validator or nominator."] @@ -19933,7 +19644,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force a validator to have at least the minimum commission. This will not affect a"] @@ -19961,7 +19671,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Sets the minimum amount of commission that each validators must maintain."] @@ -19990,7 +19699,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pay out a page of the stakers behind a validator for the given era and page."] @@ -20036,7 +19744,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Migrates an account's `RewardDestination::Controller` to"] @@ -20067,7 +19774,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates a batch of controller accounts to their corresponding stash account if they are"] @@ -20102,7 +19808,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Restores the state of a ledger which is in an inconsistent state."] @@ -20979,7 +20684,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The era payout has been set; the first balance is the validator-payout; the second is"] @@ -21010,7 +20714,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The nominator has been rewarded by this amount to this destination."] @@ -21042,7 +20745,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A staker (validator or nominator) has been slashed by the given amount."] @@ -21070,7 +20772,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A slash for the given validator, for the given percentage of their stake, at the given"] @@ -21101,7 +20802,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An old slashing report from a prior era was discarded because it could"] @@ -21128,7 +20828,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new set of stakers was elected."] @@ -21148,7 +20847,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has bonded this amount. \\[stash, amount\\]"] @@ -21179,7 +20877,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has unbonded this amount."] @@ -21207,7 +20904,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has called `withdraw_unbonded` and removed unbonding chunks worth `Balance`"] @@ -21236,7 +20932,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A nominator has been kicked from a validator."] @@ -21264,7 +20959,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The election failed. No new era is planned."] @@ -21284,7 +20978,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An account has stopped participating as either a validator or nominator."] @@ -21310,7 +21003,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The stakers' rewards are getting paid."] @@ -21338,7 +21030,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A validator has set their preferences."] @@ -21366,7 +21057,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Voters size limit reached."] @@ -21392,7 +21082,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Targets size limit reached."] @@ -21418,7 +21107,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new force era mode was set."] @@ -21444,7 +21132,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Report of a controller batch deprecation."] @@ -23884,7 +23571,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Sets the session key(s) of the function caller to `keys`."] @@ -23920,7 +23606,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Removes any session key(s) of the function caller."] @@ -24012,7 +23697,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "New session has happened. Note that the argument is the session index, not the"] @@ -24422,7 +24106,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose and approve a spend of treasury funds."] @@ -24470,7 +24153,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Force a previously approved proposal to be removed from the approval queue."] @@ -24517,7 +24199,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose and approve a spend of treasury funds."] @@ -24575,7 +24256,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim a spend."] @@ -24619,7 +24299,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Check the status of the spend and remove it from the storage if processed."] @@ -24663,7 +24342,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Void previously approved spend."] @@ -24932,7 +24610,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "We have ended a spend period and will now allocate funds."] @@ -24958,7 +24635,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some funds have been allocated."] @@ -24988,7 +24664,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some of our funds have been burnt."] @@ -25014,7 +24689,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Spending has finished; this is the amount that rolls over until next spend."] @@ -25040,7 +24714,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Some funds have been deposited."] @@ -25066,7 +24739,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new spend proposal has been approved."] @@ -25096,7 +24768,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The inactive funds of the pallet have been updated."] @@ -25124,7 +24795,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new asset spend proposal has been approved."] @@ -25160,7 +24830,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An approved spend was voided."] @@ -25186,7 +24855,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A payment happened."] @@ -25214,7 +24882,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A payment failed and can be retried."] @@ -25242,7 +24909,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A spend was processed and removed from the storage. It might have been successfully"] @@ -25590,7 +25256,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose a new bounty."] @@ -25630,7 +25295,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Approve a bounty proposal. At a later time, the bounty will be funded and become active"] @@ -25663,7 +25327,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose a curator to a funded bounty."] @@ -25703,7 +25366,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unassign curator from a bounty."] @@ -25746,7 +25408,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Accept the curator role for a bounty."] @@ -25779,7 +25440,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Award bounty to a beneficiary account. The beneficiary will be able to claim the funds"] @@ -25820,7 +25480,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim the payout from an awarded bounty after payout delay."] @@ -25854,7 +25513,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a proposed or active bounty. All the funds will be sent to treasury and"] @@ -25889,7 +25547,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Extend the expiry time of an active bounty."] @@ -26166,7 +25823,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "New bounty proposal."] @@ -26192,7 +25848,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty proposal was rejected; funds were slashed."] @@ -26220,7 +25875,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty proposal is funded and became active."] @@ -26246,7 +25900,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty is awarded to a beneficiary."] @@ -26274,7 +25927,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty is claimed by beneficiary."] @@ -26304,7 +25956,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty is cancelled."] @@ -26330,7 +25981,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty expiry is extended."] @@ -26356,7 +26006,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty is approved."] @@ -26382,7 +26031,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty curator is proposed."] @@ -26410,7 +26058,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty curator is unassigned."] @@ -26436,7 +26083,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bounty curator is accepted."] @@ -26795,7 +26441,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add a new child-bounty."] @@ -26845,7 +26490,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Propose curator for funded child-bounty."] @@ -26897,7 +26541,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Accept the curator role for the child-bounty."] @@ -26945,7 +26588,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unassign curator from a child-bounty."] @@ -27008,7 +26650,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Award child-bounty to a beneficiary."] @@ -27059,7 +26700,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim the payout from an awarded child-bounty after payout delay."] @@ -27104,7 +26744,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a proposed or active child-bounty. Child-bounty account funds"] @@ -27426,7 +27065,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A child-bounty is added."] @@ -27454,7 +27092,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A child-bounty is awarded to a beneficiary."] @@ -27484,7 +27121,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A child-bounty is claimed by beneficiary."] @@ -27516,7 +27152,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A child-bounty is cancelled."] @@ -27872,7 +27507,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Declare that some `dislocated` account has, through rewards or penalties, sufficiently"] @@ -27910,7 +27544,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Move the caller's Id directly in front of `lighter`."] @@ -27948,7 +27581,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Same as [`Pallet::put_in_front_of`], but it can be called by anyone."] @@ -28063,7 +27695,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Moved an account from one bag to another."] @@ -28093,7 +27724,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updated the score of some account to the given amount."] @@ -28339,7 +27969,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Stake funds with a pool. The amount to bond is transferred from the member to the"] @@ -28377,7 +28006,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Bond `extra` more funds from `origin` into the pool to which they already belong."] @@ -28410,7 +28038,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A bonded member can use this to claim their payout based on the rewards that the pool"] @@ -28437,7 +28064,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unbond up to `unbonding_points` of the `member_account`'s funds from the pool. It"] @@ -28499,7 +28125,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Call `withdraw_unbonded` for the pools account. This call can be made by any account."] @@ -28532,7 +28157,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Withdraw unbonded funds from `member_account`. If no bonded funds can be unbonded, an"] @@ -28584,7 +28208,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a new delegation pool."] @@ -28642,7 +28265,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a new delegation pool with a previously used pool id"] @@ -28691,7 +28313,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Nominate on behalf of the pool."] @@ -28731,7 +28352,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a new state for the pool."] @@ -28768,7 +28388,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a new metadata for the pool."] @@ -28799,7 +28418,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Update configurations for the nomination pools. The origin for this call must be"] @@ -28852,7 +28470,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Update the roles of the pool."] @@ -28896,7 +28513,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Chill on behalf of the pool."] @@ -28937,7 +28553,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "`origin` bonds funds from `extra` for some pool member `member` into their respective"] @@ -28977,7 +28592,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows a pool member to set a claim permission to allow or disallow permissionless"] @@ -29009,7 +28623,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "`origin` can claim payouts on some pool member `other`'s behalf."] @@ -29038,7 +28651,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the commission of a pool."] @@ -29073,7 +28685,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the maximum commission of a pool."] @@ -29105,7 +28716,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the commission change rate for a pool."] @@ -29139,7 +28749,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim pending commission."] @@ -29169,7 +28778,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Top up the deficit or withdraw the excess ED from the pool."] @@ -29201,7 +28809,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set or remove a pool's commission claim permission."] @@ -29236,7 +28843,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Apply a pending slash on a member."] @@ -29273,7 +28879,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Migrates delegated funds from the pool account to the `member_account`."] @@ -29310,7 +28915,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Migrate pool from [`adapter::StakeStrategyType::Transfer`] to"] @@ -30032,7 +29636,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool has been created."] @@ -30060,7 +29663,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has became bonded in a pool."] @@ -30092,7 +29694,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A payout has been made to a member."] @@ -30122,7 +29723,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has unbonded from their pool."] @@ -30166,7 +29766,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has withdrawn from their pool."] @@ -30203,7 +29802,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool has been destroyed."] @@ -30229,7 +29827,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The state of a pool has changed"] @@ -30257,7 +29854,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has been removed from a pool."] @@ -30287,7 +29883,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The roles of a pool have been updated to the given new roles. Note that the depositor"] @@ -30318,7 +29913,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The active balance of pool `pool_id` has been slashed to `balance`."] @@ -30346,7 +29940,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The unbond pool at `era` of pool `pool_id` has been slashed to `balance`."] @@ -30376,7 +29969,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's commission setting has been changed."] @@ -30407,7 +29999,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's maximum commission setting has been changed."] @@ -30435,7 +30026,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's commission `change_rate` has been changed."] @@ -30465,7 +30055,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pool commission claim permission has been updated."] @@ -30497,7 +30086,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pool commission has been claimed."] @@ -30525,7 +30113,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Topped up deficit in frozen ED of the reward pool."] @@ -30553,7 +30140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claimed excess frozen ED of af the reward pool."] @@ -31409,7 +30995,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Anonymously schedule a task."] @@ -31442,7 +31027,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel an anonymously scheduled task."] @@ -31470,7 +31054,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a named task."] @@ -31505,7 +31088,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a named scheduled task."] @@ -31531,7 +31113,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Anonymously schedule a task after a delay."] @@ -31564,7 +31145,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedule a named task after a delay."] @@ -31599,7 +31179,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a retry configuration for a task so that, in case its scheduled run fails, it will"] @@ -31640,7 +31219,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a retry configuration for a named task so that, in case its scheduled run fails, it"] @@ -31681,7 +31259,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Removes the retry configuration of a task."] @@ -31707,7 +31284,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel the retry configuration of a named task."] @@ -31743,10 +31319,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 92u8, 64u8, 142u8, 1u8, 183u8, 130u8, 66u8, 13u8, 95u8, 165u8, 223u8, - 31u8, 242u8, 234u8, 131u8, 164u8, 159u8, 128u8, 203u8, 7u8, 235u8, - 179u8, 251u8, 96u8, 102u8, 118u8, 47u8, 219u8, 147u8, 146u8, 184u8, - 41u8, + 170u8, 120u8, 244u8, 215u8, 159u8, 130u8, 64u8, 248u8, 162u8, 92u8, + 252u8, 99u8, 196u8, 12u8, 134u8, 221u8, 199u8, 37u8, 48u8, 159u8, 67u8, + 183u8, 154u8, 93u8, 64u8, 51u8, 150u8, 138u8, 42u8, 125u8, 191u8, 21u8, ], ) } @@ -31788,9 +31363,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 217u8, 201u8, 151u8, 3u8, 16u8, 106u8, 9u8, 189u8, 232u8, 235u8, 124u8, - 127u8, 228u8, 144u8, 73u8, 148u8, 138u8, 15u8, 82u8, 4u8, 151u8, 175u8, - 83u8, 166u8, 104u8, 181u8, 88u8, 70u8, 103u8, 25u8, 46u8, 142u8, + 233u8, 84u8, 88u8, 220u8, 250u8, 230u8, 53u8, 70u8, 200u8, 49u8, 34u8, + 90u8, 138u8, 217u8, 219u8, 227u8, 138u8, 45u8, 40u8, 210u8, 48u8, + 152u8, 220u8, 67u8, 99u8, 239u8, 130u8, 0u8, 18u8, 131u8, 175u8, 106u8, ], ) } @@ -31828,10 +31403,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 44u8, 138u8, 111u8, 40u8, 40u8, 171u8, 221u8, 248u8, 101u8, 24u8, - 106u8, 62u8, 4u8, 220u8, 69u8, 52u8, 63u8, 87u8, 123u8, 152u8, 79u8, - 88u8, 142u8, 31u8, 233u8, 214u8, 172u8, 132u8, 50u8, 75u8, 225u8, - 141u8, + 26u8, 48u8, 231u8, 40u8, 187u8, 247u8, 71u8, 102u8, 215u8, 81u8, 45u8, + 11u8, 12u8, 11u8, 140u8, 101u8, 145u8, 60u8, 224u8, 101u8, 50u8, 85u8, + 129u8, 158u8, 93u8, 163u8, 248u8, 179u8, 50u8, 215u8, 60u8, 49u8, ], ) } @@ -31855,9 +31429,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 116u8, 32u8, 96u8, 199u8, 238u8, 193u8, 57u8, 178u8, 81u8, 99u8, 45u8, - 156u8, 63u8, 198u8, 127u8, 162u8, 137u8, 141u8, 13u8, 123u8, 215u8, - 227u8, 208u8, 2u8, 64u8, 179u8, 92u8, 57u8, 185u8, 6u8, 210u8, 79u8, + 86u8, 120u8, 18u8, 16u8, 48u8, 232u8, 57u8, 152u8, 246u8, 123u8, 41u8, + 45u8, 51u8, 85u8, 114u8, 206u8, 146u8, 164u8, 50u8, 195u8, 199u8, + 118u8, 153u8, 118u8, 201u8, 247u8, 57u8, 11u8, 137u8, 93u8, 165u8, + 204u8, ], ) } @@ -31969,7 +31544,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Scheduled some task."] @@ -31997,7 +31571,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Canceled some task."] @@ -32025,7 +31598,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatched some task."] @@ -32056,7 +31628,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a retry configuration for some task."] @@ -32088,7 +31659,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a retry configuration for some task."] @@ -32116,7 +31686,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The call for the provided hash was not found so the task has been aborted."] @@ -32144,7 +31713,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The given task was unable to be renewed since the agenda is full at that block."] @@ -32172,7 +31740,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The given task was unable to be retried since the agenda is full at that block or there"] @@ -32201,7 +31768,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The given task can never be executed since it is overweight."] @@ -32518,7 +32084,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Register a preimage on-chain."] @@ -32547,7 +32112,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clear an unrequested preimage from the runtime storage."] @@ -32578,7 +32142,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Request a preimage be uploaded to the chain without paying any fees or deposits."] @@ -32607,7 +32170,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clear a previously made request for a preimage."] @@ -32635,7 +32197,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Ensure that the a bulk of pre-images is upgraded."] @@ -32770,7 +32331,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A preimage has been noted."] @@ -32796,7 +32356,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A preimage has been requested."] @@ -32822,7 +32381,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A preimage has ben cleared."] @@ -33057,7 +32615,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "There is an offence reported of the given `kind` happened at the `session_index` and"] @@ -33256,7 +32813,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pause a call."] @@ -33292,7 +32848,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Un-pause a call."] @@ -33376,7 +32931,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "This pallet, or a specific call is now paused."] @@ -33409,7 +32963,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "This pallet, or a specific call is now unpaused."] @@ -33575,7 +33128,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "## Complexity:"] @@ -33635,7 +33187,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new heartbeat was received from `AuthorityId`."] @@ -33662,7 +33213,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "At the end of the session, no offence was committed."] @@ -33682,7 +33232,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "At the end of the session, at least one validator was found to be offline."] @@ -34000,7 +33549,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add a registrar to the system."] @@ -34035,7 +33583,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set an account's identity information and reserve the appropriate deposit."] @@ -34070,7 +33617,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the sub-accounts of the sender."] @@ -34107,7 +33653,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Clear an account's identity info and all sub-accounts and return all deposits."] @@ -34134,7 +33679,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Request a judgement from a registrar."] @@ -34179,7 +33723,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a previous request."] @@ -34214,7 +33757,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the fee required for a judgement to be requested from a registrar."] @@ -34250,7 +33792,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Change the account associated with a registrar."] @@ -34288,7 +33829,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the field information for a registrar."] @@ -34323,7 +33863,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Provide a judgement for an account's identity."] @@ -34374,7 +33913,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove an account's identity and sub-account information and slash the deposits."] @@ -34414,7 +33952,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add the given account to the sender's subs."] @@ -34451,7 +33988,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Alter the associated name of the given sub-account."] @@ -34485,7 +34021,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove the given account from the sender's subs."] @@ -34520,7 +34055,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove the sender as a sub-account."] @@ -34549,7 +34083,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Add an `AccountId` with permission to grant usernames with a given `suffix` appended."] @@ -34585,7 +34118,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove `authority` from the username authorities."] @@ -34614,7 +34146,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the username for `who`. Must be called by a username authority."] @@ -34656,7 +34187,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Accept a given username that an `authority` granted. The call must include the full"] @@ -34685,7 +34215,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove an expired username approval. The username was approved by an authority but never"] @@ -34715,7 +34244,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set a given username as the primary. The username should include the suffix."] @@ -34743,7 +34271,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a username that corresponds to an account with no identity. Exists when a user"] @@ -35289,7 +34816,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A name was set or reset (which will remove all judgements)."] @@ -35315,7 +34841,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A name was cleared, and the given balance returned."] @@ -35343,7 +34868,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A name was removed and the given balance slashed."] @@ -35371,7 +34895,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A judgement was asked from a registrar."] @@ -35399,7 +34922,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A judgement request was retracted."] @@ -35427,7 +34949,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A judgement was given by a registrar."] @@ -35455,7 +34976,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A registrar was added."] @@ -35481,7 +35001,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A sub-identity was added to an identity and the deposit paid."] @@ -35511,7 +35030,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A sub-identity was removed from an identity and the deposit freed."] @@ -35541,7 +35059,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A sub-identity was cleared, and the given deposit repatriated from the"] @@ -35572,7 +35089,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A username authority was added."] @@ -35598,7 +35114,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A username authority was removed."] @@ -35624,7 +35139,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A username was set for `who`."] @@ -35654,7 +35168,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A username was queued, but `who` must accept it prior to `expiration`."] @@ -35686,7 +35199,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A queued username passed its expiration without being claimed and was removed."] @@ -35712,7 +35224,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A username was set as a primary and can be looked up from `who`."] @@ -35742,7 +35253,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A dangling username (as in, a username corresponding to an account that has removed its"] @@ -36323,7 +35833,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Send a batch of dispatch calls."] @@ -36368,7 +35877,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Send a call through an indexed pseudonym of the sender."] @@ -36408,7 +35916,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Send a batch of dispatch calls and atomically execute them."] @@ -36448,7 +35955,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatches a function call with a provided origin."] @@ -36481,7 +35987,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Send a batch of dispatch calls."] @@ -36521,7 +36026,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatch a function call with a specified weight."] @@ -36573,10 +36077,9 @@ pub mod api { "batch", types::Batch { calls }, [ - 74u8, 107u8, 179u8, 203u8, 32u8, 60u8, 136u8, 187u8, 145u8, 126u8, - 27u8, 144u8, 160u8, 111u8, 153u8, 225u8, 131u8, 247u8, 116u8, 244u8, - 4u8, 121u8, 38u8, 86u8, 143u8, 18u8, 63u8, 92u8, 156u8, 26u8, 20u8, - 53u8, + 36u8, 112u8, 231u8, 84u8, 153u8, 73u8, 93u8, 209u8, 62u8, 76u8, 85u8, + 41u8, 65u8, 147u8, 23u8, 7u8, 52u8, 218u8, 247u8, 249u8, 127u8, 105u8, + 58u8, 58u8, 86u8, 183u8, 66u8, 148u8, 159u8, 47u8, 1u8, 177u8, ], ) } @@ -36606,9 +36109,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 245u8, 159u8, 183u8, 82u8, 172u8, 226u8, 71u8, 54u8, 252u8, 3u8, 54u8, - 246u8, 40u8, 82u8, 126u8, 209u8, 185u8, 81u8, 227u8, 1u8, 1u8, 3u8, - 4u8, 121u8, 238u8, 68u8, 141u8, 230u8, 45u8, 152u8, 125u8, 156u8, + 100u8, 96u8, 223u8, 113u8, 197u8, 79u8, 127u8, 17u8, 10u8, 109u8, + 119u8, 140u8, 168u8, 255u8, 27u8, 80u8, 52u8, 125u8, 18u8, 99u8, 90u8, + 243u8, 112u8, 79u8, 74u8, 247u8, 191u8, 114u8, 184u8, 67u8, 186u8, + 49u8, ], ) } @@ -36634,10 +36138,10 @@ pub mod api { "batch_all", types::BatchAll { calls }, [ - 212u8, 125u8, 62u8, 250u8, 22u8, 172u8, 113u8, 2u8, 219u8, 70u8, 46u8, - 120u8, 55u8, 251u8, 39u8, 220u8, 111u8, 233u8, 76u8, 132u8, 217u8, - 237u8, 86u8, 253u8, 176u8, 38u8, 16u8, 102u8, 207u8, 219u8, 155u8, - 16u8, + 254u8, 236u8, 247u8, 111u8, 228u8, 2u8, 141u8, 46u8, 149u8, 46u8, + 200u8, 248u8, 143u8, 11u8, 71u8, 47u8, 116u8, 198u8, 101u8, 80u8, + 244u8, 68u8, 1u8, 202u8, 184u8, 221u8, 205u8, 233u8, 140u8, 100u8, + 213u8, 89u8, ], ) } @@ -36660,9 +36164,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 74u8, 19u8, 72u8, 89u8, 244u8, 203u8, 12u8, 254u8, 240u8, 12u8, 253u8, - 241u8, 211u8, 219u8, 25u8, 139u8, 175u8, 220u8, 125u8, 149u8, 14u8, - 26u8, 57u8, 147u8, 71u8, 25u8, 188u8, 39u8, 120u8, 5u8, 218u8, 215u8, + 50u8, 240u8, 106u8, 208u8, 186u8, 70u8, 231u8, 190u8, 151u8, 167u8, + 27u8, 105u8, 189u8, 163u8, 223u8, 39u8, 35u8, 70u8, 130u8, 217u8, 61u8, + 11u8, 201u8, 70u8, 5u8, 64u8, 67u8, 70u8, 81u8, 177u8, 60u8, 213u8, ], ) } @@ -36688,10 +36192,9 @@ pub mod api { "force_batch", types::ForceBatch { calls }, [ - 5u8, 181u8, 101u8, 99u8, 244u8, 248u8, 179u8, 95u8, 159u8, 191u8, 89u8, - 220u8, 196u8, 165u8, 198u8, 7u8, 181u8, 211u8, 131u8, 89u8, 15u8, - 251u8, 20u8, 131u8, 177u8, 221u8, 230u8, 118u8, 220u8, 152u8, 205u8, - 238u8, + 95u8, 201u8, 187u8, 141u8, 50u8, 90u8, 145u8, 42u8, 68u8, 174u8, 13u8, + 90u8, 98u8, 79u8, 63u8, 236u8, 222u8, 224u8, 161u8, 211u8, 71u8, 15u8, + 188u8, 52u8, 133u8, 55u8, 224u8, 99u8, 142u8, 82u8, 130u8, 65u8, ], ) } @@ -36714,10 +36217,9 @@ pub mod api { weight, }, [ - 208u8, 146u8, 123u8, 156u8, 82u8, 134u8, 159u8, 25u8, 131u8, 39u8, - 25u8, 193u8, 88u8, 219u8, 113u8, 196u8, 179u8, 244u8, 61u8, 42u8, 12u8, - 140u8, 238u8, 164u8, 174u8, 125u8, 77u8, 120u8, 118u8, 19u8, 129u8, - 208u8, + 135u8, 148u8, 175u8, 193u8, 215u8, 123u8, 165u8, 22u8, 123u8, 243u8, + 190u8, 183u8, 191u8, 15u8, 48u8, 146u8, 93u8, 56u8, 38u8, 171u8, 16u8, + 253u8, 228u8, 198u8, 46u8, 39u8, 117u8, 19u8, 26u8, 12u8, 70u8, 168u8, ], ) } @@ -36738,7 +36240,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Batch of dispatches did not complete fully. Index of first failing dispatch given, as"] @@ -36767,7 +36268,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Batch of dispatches completed fully with no error."] @@ -36787,7 +36287,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Batch of dispatches completed but has errors."] @@ -36807,7 +36306,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A single item within a Batch of dispatches has completed with no error."] @@ -36827,7 +36325,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A single item within a Batch of dispatches has completed with error."] @@ -36853,7 +36350,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A call was dispatched."] @@ -36916,7 +36412,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Immediately dispatch a multi-signature call using a single approval from the caller."] @@ -36956,7 +36451,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Register approval for a dispatch to be made from a deterministic composite account if"] @@ -37031,7 +36525,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Register approval for a dispatch to be made from a deterministic composite account if"] @@ -37097,7 +36590,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously"] @@ -37168,10 +36660,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 188u8, 135u8, 180u8, 175u8, 211u8, 76u8, 74u8, 19u8, 128u8, 113u8, - 33u8, 85u8, 161u8, 124u8, 126u8, 195u8, 27u8, 37u8, 30u8, 220u8, 24u8, - 0u8, 134u8, 73u8, 90u8, 244u8, 254u8, 120u8, 171u8, 205u8, 236u8, - 234u8, + 108u8, 216u8, 152u8, 4u8, 93u8, 13u8, 249u8, 119u8, 34u8, 61u8, 97u8, + 245u8, 129u8, 62u8, 207u8, 161u8, 43u8, 34u8, 113u8, 75u8, 165u8, 35u8, + 252u8, 215u8, 159u8, 170u8, 40u8, 64u8, 160u8, 3u8, 42u8, 27u8, ], ) } @@ -37233,10 +36724,10 @@ pub mod api { max_weight, }, [ - 162u8, 58u8, 211u8, 135u8, 95u8, 79u8, 109u8, 182u8, 245u8, 48u8, 20u8, - 105u8, 103u8, 149u8, 122u8, 2u8, 154u8, 181u8, 154u8, 247u8, 136u8, - 181u8, 204u8, 80u8, 177u8, 226u8, 59u8, 143u8, 51u8, 55u8, 222u8, - 129u8, + 1u8, 100u8, 146u8, 226u8, 26u8, 79u8, 235u8, 59u8, 210u8, 107u8, 0u8, + 56u8, 165u8, 175u8, 83u8, 234u8, 208u8, 100u8, 101u8, 87u8, 138u8, + 100u8, 189u8, 65u8, 212u8, 101u8, 175u8, 250u8, 138u8, 126u8, 70u8, + 91u8, ], ) } @@ -37352,7 +36843,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new multisig operation has begun."] @@ -37382,7 +36872,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A multisig operation has been approved by someone."] @@ -37415,7 +36904,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A multisig operation has been executed."] @@ -37451,7 +36939,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A multisig operation has been cancelled."] @@ -37649,7 +37136,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Transact an Ethereum transaction."] @@ -37700,7 +37186,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An ethereum transaction was successfully executed."] @@ -37914,7 +37399,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Withdraw balance from EVM into currency/balances pallet."] @@ -37942,7 +37426,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Issue an EVM call operation. This is similar to a message call transaction in Ethereum."] @@ -37988,7 +37471,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Issue an EVM create operation. This is similar to a contract creation transaction in"] @@ -38033,7 +37515,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Issue an EVM create2 operation."] @@ -38208,7 +37689,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Ethereum events from contracts."] @@ -38234,7 +37714,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A contract has been created at given address."] @@ -38260,7 +37739,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A contract was attempted to be created, but the execution failed."] @@ -38286,7 +37764,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A contract has been executed successfully with states applied."] @@ -38312,7 +37789,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A contract has been executed with errors. States are reverted with only gas fees applied."] @@ -38622,7 +38098,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NoteMinGasPriceTarget { @@ -38736,7 +38211,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SetBaseFeePerGas { @@ -38761,7 +38235,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SetElasticity { @@ -38826,7 +38299,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NewBaseFeePerGas { @@ -38851,7 +38323,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BaseFeeOverflow; @@ -38870,7 +38341,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NewElasticity { @@ -38967,7 +38437,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Increment `sufficients` for existing accounts having a nonzero `nonce` but zero `sufficients`, `consumers` and `providers` value."] @@ -39036,7 +38505,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Make a claim to collect your tokens."] @@ -39094,7 +38562,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Mint a new claim to collect native tokens."] @@ -39147,7 +38614,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Make a claim to collect your native tokens by signing a statement."] @@ -39210,7 +38676,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MoveClaim { @@ -39237,7 +38702,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the value for expiryconfig"] @@ -39266,7 +38730,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim from signed origin"] @@ -39476,7 +38939,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Someone claimed some native tokens."] @@ -39757,7 +39219,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatch the given `call` from an account that the sender is authorised for through"] @@ -39799,7 +39260,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Register a proxy account for the sender that is able to make calls on its behalf."] @@ -39840,7 +39300,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unregister a proxy account for the sender."] @@ -39879,7 +39338,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unregister all proxy accounts for the sender."] @@ -39904,7 +39362,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Spawn a fresh new account that is guaranteed to be otherwise inaccessible, and"] @@ -39951,7 +39408,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Removes a previously spawned pure proxy."] @@ -40005,7 +39461,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Publish the hash of a proxy-call that will be made in the future."] @@ -40050,7 +39505,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove a given announcement."] @@ -40090,7 +39544,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Remove the given announcement of a delegate."] @@ -40130,7 +39583,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Dispatch the given `call` from an account that the sender is authorized for through"] @@ -40195,9 +39647,10 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 34u8, 6u8, 198u8, 207u8, 174u8, 120u8, 23u8, 207u8, 235u8, 110u8, 28u8, - 174u8, 66u8, 0u8, 108u8, 42u8, 149u8, 130u8, 133u8, 229u8, 100u8, 53u8, - 255u8, 33u8, 151u8, 17u8, 195u8, 224u8, 219u8, 46u8, 114u8, 111u8, + 27u8, 220u8, 137u8, 175u8, 120u8, 237u8, 245u8, 233u8, 76u8, 183u8, + 229u8, 113u8, 192u8, 39u8, 118u8, 181u8, 211u8, 8u8, 254u8, 117u8, + 127u8, 146u8, 217u8, 214u8, 249u8, 226u8, 17u8, 156u8, 209u8, 34u8, + 180u8, 186u8, ], ) } @@ -40453,10 +39906,9 @@ pub mod api { call: ::subxt_core::alloc::boxed::Box::new(call), }, [ - 112u8, 61u8, 231u8, 124u8, 79u8, 171u8, 75u8, 154u8, 82u8, 157u8, - 138u8, 252u8, 51u8, 202u8, 116u8, 77u8, 1u8, 49u8, 54u8, 181u8, 40u8, - 150u8, 179u8, 36u8, 229u8, 21u8, 159u8, 82u8, 182u8, 219u8, 185u8, - 101u8, + 81u8, 66u8, 67u8, 103u8, 145u8, 192u8, 9u8, 6u8, 49u8, 211u8, 145u8, + 127u8, 122u8, 176u8, 198u8, 228u8, 51u8, 57u8, 62u8, 88u8, 186u8, + 157u8, 207u8, 141u8, 23u8, 64u8, 219u8, 36u8, 229u8, 15u8, 84u8, 49u8, ], ) } @@ -40477,7 +39929,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proxy was executed correctly, with the given."] @@ -40504,7 +39955,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pure account has been created by new proxy with given"] @@ -40537,7 +39987,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An announcement was placed to make a call in the future."] @@ -40567,7 +40016,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proxy was added."] @@ -40599,7 +40047,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A proxy was removed."] @@ -40878,7 +40325,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows an account to join as an operator by staking the required bond amount."] @@ -40918,7 +40364,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedules an operator to leave the system."] @@ -40951,7 +40396,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancels a scheduled leave for an operator."] @@ -40984,7 +40428,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Executes a scheduled leave for an operator."] @@ -41018,7 +40461,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows an operator to increase their stake."] @@ -41058,7 +40500,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedules an operator to decrease their stake."] @@ -41099,7 +40540,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Executes a scheduled stake decrease for an operator."] @@ -41133,7 +40573,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancels a scheduled stake decrease for an operator."] @@ -41166,7 +40605,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows an operator to go offline."] @@ -41199,7 +40637,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows an operator to go online."] @@ -41232,7 +40669,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows a user to deposit an asset."] @@ -41256,6 +40692,7 @@ pub mod api { pub asset_id: deposit::AssetId, pub amount: deposit::Amount, pub evm_address: deposit::EvmAddress, + pub lock_multiplier: deposit::LockMultiplier, } pub mod deposit { use super::runtime_types; @@ -41263,6 +40700,9 @@ pub mod api { runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; pub type Amount = ::core::primitive::u128; pub type EvmAddress = ::core::option::Option<::subxt_core::utils::H160>; + pub type LockMultiplier = ::core::option::Option< + runtime_types::tangle_primitives::types::rewards::LockMultiplier, + >; } impl ::subxt_core::blocks::StaticExtrinsic for Deposit { const PALLET: &'static str = "MultiAssetDelegation"; @@ -41279,7 +40719,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedules a withdraw request."] @@ -41323,7 +40762,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Executes a scheduled withdraw request."] @@ -41363,7 +40801,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancels a scheduled withdraw request."] @@ -41406,7 +40843,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Allows a user to delegate an amount of an asset to an operator."] @@ -41457,7 +40893,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Schedules a request to reduce a delegator's stake."] @@ -41505,7 +40940,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Executes a scheduled request to reduce a delegator's stake."] @@ -41539,7 +40973,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Cancels a scheduled request to reduce a delegator's stake."] @@ -41586,136 +41019,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Sets the APY and cap for a specific asset."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be called by the force origin"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `vault_id` - ID of the vault"] - #[doc = "* `apy` - Annual percentage yield (max 10%)"] - #[doc = "* `cap` - Required deposit amount for full APY"] - #[doc = ""] - #[doc = "# Errors"] - #[doc = ""] - #[doc = "* [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum"] - #[doc = "* [`Error::CapCannotBeZero`] - Cap amount cannot be zero"] - pub struct SetIncentiveApyAndCap { - pub vault_id: set_incentive_apy_and_cap::VaultId, - pub apy: set_incentive_apy_and_cap::Apy, - pub cap: set_incentive_apy_and_cap::Cap, - } - pub mod set_incentive_apy_and_cap { - use super::runtime_types; - pub type VaultId = ::core::primitive::u128; - pub type Apy = runtime_types::sp_arithmetic::per_things::Percent; - pub type Cap = ::core::primitive::u128; - } - impl ::subxt_core::blocks::StaticExtrinsic for SetIncentiveApyAndCap { - const PALLET: &'static str = "MultiAssetDelegation"; - const CALL: &'static str = "set_incentive_apy_and_cap"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Whitelists a blueprint for rewards."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be called by the force origin"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `blueprint_id` - ID of blueprint to whitelist"] - pub struct WhitelistBlueprintForRewards { - pub blueprint_id: whitelist_blueprint_for_rewards::BlueprintId, - } - pub mod whitelist_blueprint_for_rewards { - use super::runtime_types; - pub type BlueprintId = ::core::primitive::u64; - } - impl ::subxt_core::blocks::StaticExtrinsic for WhitelistBlueprintForRewards { - const PALLET: &'static str = "MultiAssetDelegation"; - const CALL: &'static str = "whitelist_blueprint_for_rewards"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Manage asset id to vault rewards."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be signed by an authorized account"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `vault_id` - ID of the vault"] - #[doc = "* `asset_id` - ID of the asset"] - #[doc = "* `action` - Action to perform (Add/Remove)"] - #[doc = ""] - #[doc = "# Errors"] - #[doc = ""] - #[doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] - #[doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] - pub struct ManageAssetInVault { - pub vault_id: manage_asset_in_vault::VaultId, - pub asset_id: manage_asset_in_vault::AssetId, - pub action: manage_asset_in_vault::Action, - } - pub mod manage_asset_in_vault { - use super::runtime_types; - pub type VaultId = ::core::primitive::u128; - pub type AssetId = - runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; - pub type Action = - runtime_types::pallet_multi_asset_delegation::types::rewards::AssetAction; - } - impl ::subxt_core::blocks::StaticExtrinsic for ManageAssetInVault { - const PALLET: &'static str = "MultiAssetDelegation"; - const CALL: &'static str = "manage_asset_in_vault"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Adds a blueprint ID to a delegator's selection."] @@ -41757,7 +41060,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Removes a blueprint ID from a delegator's selection."] @@ -42106,16 +41408,16 @@ pub mod api { asset_id: types::deposit::AssetId, amount: types::deposit::Amount, evm_address: types::deposit::EvmAddress, + lock_multiplier: types::deposit::LockMultiplier, ) -> ::subxt_core::tx::payload::StaticPayload { ::subxt_core::tx::payload::StaticPayload::new_static( "MultiAssetDelegation", "deposit", - types::Deposit { asset_id, amount, evm_address }, + types::Deposit { asset_id, amount, evm_address, lock_multiplier }, [ - 58u8, 72u8, 176u8, 66u8, 51u8, 188u8, 190u8, 38u8, 13u8, 234u8, 239u8, - 113u8, 157u8, 64u8, 109u8, 91u8, 0u8, 242u8, 157u8, 176u8, 126u8, - 250u8, 133u8, 66u8, 172u8, 17u8, 254u8, 231u8, 124u8, 159u8, 248u8, - 101u8, + 205u8, 34u8, 149u8, 5u8, 227u8, 227u8, 104u8, 33u8, 248u8, 217u8, + 209u8, 189u8, 128u8, 242u8, 69u8, 11u8, 174u8, 254u8, 54u8, 10u8, 89u8, + 224u8, 223u8, 69u8, 47u8, 134u8, 175u8, 241u8, 113u8, 4u8, 213u8, 68u8, ], ) } @@ -42349,102 +41651,6 @@ pub mod api { ], ) } - #[doc = "Sets the APY and cap for a specific asset."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be called by the force origin"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `vault_id` - ID of the vault"] - #[doc = "* `apy` - Annual percentage yield (max 10%)"] - #[doc = "* `cap` - Required deposit amount for full APY"] - #[doc = ""] - #[doc = "# Errors"] - #[doc = ""] - #[doc = "* [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum"] - #[doc = "* [`Error::CapCannotBeZero`] - Cap amount cannot be zero"] - pub fn set_incentive_apy_and_cap( - &self, - vault_id: types::set_incentive_apy_and_cap::VaultId, - apy: types::set_incentive_apy_and_cap::Apy, - cap: types::set_incentive_apy_and_cap::Cap, - ) -> ::subxt_core::tx::payload::StaticPayload { - ::subxt_core::tx::payload::StaticPayload::new_static( - "MultiAssetDelegation", - "set_incentive_apy_and_cap", - types::SetIncentiveApyAndCap { vault_id, apy, cap }, - [ - 176u8, 74u8, 10u8, 166u8, 121u8, 38u8, 138u8, 18u8, 107u8, 106u8, - 229u8, 224u8, 59u8, 92u8, 15u8, 203u8, 132u8, 253u8, 4u8, 144u8, 218u8, - 106u8, 239u8, 142u8, 237u8, 241u8, 177u8, 94u8, 61u8, 183u8, 144u8, - 145u8, - ], - ) - } - #[doc = "Whitelists a blueprint for rewards."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be called by the force origin"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `blueprint_id` - ID of blueprint to whitelist"] - pub fn whitelist_blueprint_for_rewards( - &self, - blueprint_id: types::whitelist_blueprint_for_rewards::BlueprintId, - ) -> ::subxt_core::tx::payload::StaticPayload - { - ::subxt_core::tx::payload::StaticPayload::new_static( - "MultiAssetDelegation", - "whitelist_blueprint_for_rewards", - types::WhitelistBlueprintForRewards { blueprint_id }, - [ - 157u8, 245u8, 188u8, 187u8, 236u8, 197u8, 239u8, 8u8, 115u8, 107u8, - 137u8, 206u8, 205u8, 207u8, 192u8, 106u8, 33u8, 219u8, 29u8, 34u8, - 236u8, 117u8, 245u8, 27u8, 131u8, 43u8, 95u8, 5u8, 152u8, 185u8, 220u8, - 153u8, - ], - ) - } - #[doc = "Manage asset id to vault rewards."] - #[doc = ""] - #[doc = "# Permissions"] - #[doc = ""] - #[doc = "* Must be signed by an authorized account"] - #[doc = ""] - #[doc = "# Arguments"] - #[doc = ""] - #[doc = "* `origin` - Origin of the call"] - #[doc = "* `vault_id` - ID of the vault"] - #[doc = "* `asset_id` - ID of the asset"] - #[doc = "* `action` - Action to perform (Add/Remove)"] - #[doc = ""] - #[doc = "# Errors"] - #[doc = ""] - #[doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] - #[doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] - pub fn manage_asset_in_vault( - &self, - vault_id: types::manage_asset_in_vault::VaultId, - asset_id: types::manage_asset_in_vault::AssetId, - action: types::manage_asset_in_vault::Action, - ) -> ::subxt_core::tx::payload::StaticPayload { - ::subxt_core::tx::payload::StaticPayload::new_static( - "MultiAssetDelegation", - "manage_asset_in_vault", - types::ManageAssetInVault { vault_id, asset_id, action }, - [ - 164u8, 251u8, 229u8, 192u8, 83u8, 53u8, 179u8, 154u8, 228u8, 245u8, - 116u8, 154u8, 100u8, 198u8, 182u8, 69u8, 90u8, 178u8, 237u8, 99u8, 0u8, - 160u8, 243u8, 162u8, 69u8, 87u8, 26u8, 61u8, 82u8, 151u8, 100u8, 251u8, - ], - ) - } #[doc = "Adds a blueprint ID to a delegator's selection."] #[doc = ""] #[doc = "# Permissions"] @@ -42526,7 +41732,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has joined."] @@ -42552,7 +41757,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has scheduled to leave."] @@ -42578,7 +41782,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has cancelled their leave request."] @@ -42604,7 +41807,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has executed their leave request."] @@ -42630,7 +41832,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has increased their stake."] @@ -42658,7 +41859,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has scheduled to decrease their stake."] @@ -42686,7 +41886,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has executed their stake decrease."] @@ -42712,7 +41911,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has cancelled their stake decrease request."] @@ -42738,7 +41936,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has gone offline."] @@ -42764,7 +41961,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has gone online."] @@ -42790,7 +41986,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A deposit has been made."] @@ -42821,7 +42016,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An withdraw has been scheduled."] @@ -42852,7 +42046,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An withdraw has been executed."] @@ -42878,7 +42071,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An withdraw has been cancelled."] @@ -42904,7 +42096,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A delegation has been made."] @@ -42937,7 +42128,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A delegator unstake request has been scheduled."] @@ -42970,7 +42160,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A delegator unstake request has been executed."] @@ -42996,7 +42185,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A delegator unstake request has been cancelled."] @@ -43022,97 +42210,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Event emitted when an incentive APY and cap are set for a reward vault"] - pub struct IncentiveAPYAndCapSet { - pub vault_id: incentive_apy_and_cap_set::VaultId, - pub apy: incentive_apy_and_cap_set::Apy, - pub cap: incentive_apy_and_cap_set::Cap, - } - pub mod incentive_apy_and_cap_set { - use super::runtime_types; - pub type VaultId = ::core::primitive::u128; - pub type Apy = runtime_types::sp_arithmetic::per_things::Percent; - pub type Cap = ::core::primitive::u128; - } - impl ::subxt_core::events::StaticEvent for IncentiveAPYAndCapSet { - const PALLET: &'static str = "MultiAssetDelegation"; - const EVENT: &'static str = "IncentiveAPYAndCapSet"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Event emitted when a blueprint is whitelisted for rewards"] - pub struct BlueprintWhitelisted { - pub blueprint_id: blueprint_whitelisted::BlueprintId, - } - pub mod blueprint_whitelisted { - use super::runtime_types; - pub type BlueprintId = ::core::primitive::u64; - } - impl ::subxt_core::events::StaticEvent for BlueprintWhitelisted { - const PALLET: &'static str = "MultiAssetDelegation"; - const EVENT: &'static str = "BlueprintWhitelisted"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - #[doc = "Asset has been updated to reward vault"] - pub struct AssetUpdatedInVault { - pub who: asset_updated_in_vault::Who, - pub vault_id: asset_updated_in_vault::VaultId, - pub asset_id: asset_updated_in_vault::AssetId, - pub action: asset_updated_in_vault::Action, - } - pub mod asset_updated_in_vault { - use super::runtime_types; - pub type Who = ::subxt_core::utils::AccountId32; - pub type VaultId = ::core::primitive::u128; - pub type AssetId = - runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; - pub type Action = - runtime_types::pallet_multi_asset_delegation::types::rewards::AssetAction; - } - impl ::subxt_core::events::StaticEvent for AssetUpdatedInVault { - const PALLET: &'static str = "MultiAssetDelegation"; - const EVENT: &'static str = "AssetUpdatedInVault"; - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Operator has been slashed"] @@ -43140,7 +42237,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Delegator has been slashed"] @@ -43168,7 +42264,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "EVM execution reverted with a reason."] @@ -43211,30 +42306,9 @@ pub mod api { } pub mod delegators { use super::runtime_types; - pub type Delegators = runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorMetadata < :: subxt_core :: utils :: AccountId32 , :: core :: primitive :: u128 , :: core :: primitive :: u128 , runtime_types :: tangle_testnet_runtime :: MaxWithdrawRequests , runtime_types :: tangle_testnet_runtime :: MaxDelegations , runtime_types :: tangle_testnet_runtime :: MaxUnstakeRequests , runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > ; + pub type Delegators = runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorMetadata < :: subxt_core :: utils :: AccountId32 , :: core :: primitive :: u128 , :: core :: primitive :: u128 , runtime_types :: tangle_testnet_runtime :: MaxWithdrawRequests , runtime_types :: tangle_testnet_runtime :: MaxDelegations , runtime_types :: tangle_testnet_runtime :: MaxUnstakeRequests , runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints , :: core :: primitive :: u64 , runtime_types :: tangle_testnet_runtime :: MaxDelegations > ; pub type Param0 = ::subxt_core::utils::AccountId32; } - pub mod reward_vaults { - use super::runtime_types; - pub type RewardVaults = ::subxt_core::alloc::vec::Vec< - runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>, - >; - pub type Param0 = ::core::primitive::u128; - } - pub mod asset_lookup_reward_vaults { - use super::runtime_types; - pub type AssetLookupRewardVaults = ::core::primitive::u128; - pub type Param0 = - runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; - } - pub mod reward_config_storage { - use super::runtime_types; - pub type RewardConfigStorage = - runtime_types::pallet_multi_asset_delegation::types::rewards::RewardConfig< - ::core::primitive::u128, - ::core::primitive::u128, - >; - } } pub struct StorageApi; impl StorageApi { @@ -43393,10 +42467,10 @@ pub mod api { "Delegators", (), [ - 208u8, 190u8, 90u8, 169u8, 30u8, 169u8, 192u8, 170u8, 53u8, 227u8, - 128u8, 145u8, 223u8, 226u8, 166u8, 141u8, 222u8, 141u8, 6u8, 136u8, - 232u8, 114u8, 217u8, 222u8, 129u8, 124u8, 160u8, 239u8, 33u8, 211u8, - 10u8, 156u8, + 45u8, 173u8, 235u8, 188u8, 23u8, 120u8, 225u8, 27u8, 94u8, 59u8, 35u8, + 139u8, 127u8, 59u8, 118u8, 200u8, 174u8, 212u8, 214u8, 128u8, 40u8, + 187u8, 97u8, 19u8, 236u8, 14u8, 122u8, 135u8, 254u8, 198u8, 21u8, + 238u8, ], ) } @@ -43416,125 +42490,10 @@ pub mod api { "Delegators", ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), [ - 208u8, 190u8, 90u8, 169u8, 30u8, 169u8, 192u8, 170u8, 53u8, 227u8, - 128u8, 145u8, 223u8, 226u8, 166u8, 141u8, 222u8, 141u8, 6u8, 136u8, - 232u8, 114u8, 217u8, 222u8, 129u8, 124u8, 160u8, 239u8, 33u8, 211u8, - 10u8, 156u8, - ], - ) - } - #[doc = " Storage for the reward vaults"] - pub fn reward_vaults_iter( - &self, - ) -> ::subxt_core::storage::address::StaticAddress< - (), - types::reward_vaults::RewardVaults, - (), - (), - ::subxt_core::utils::Yes, - > { - ::subxt_core::storage::address::StaticAddress::new_static( - "MultiAssetDelegation", - "RewardVaults", - (), - [ - 30u8, 97u8, 236u8, 132u8, 229u8, 86u8, 124u8, 248u8, 89u8, 52u8, 91u8, - 194u8, 48u8, 44u8, 236u8, 142u8, 251u8, 192u8, 107u8, 103u8, 244u8, - 170u8, 94u8, 57u8, 146u8, 82u8, 122u8, 212u8, 228u8, 119u8, 152u8, - 57u8, - ], - ) - } - #[doc = " Storage for the reward vaults"] - pub fn reward_vaults( - &self, - _0: impl ::core::borrow::Borrow, - ) -> ::subxt_core::storage::address::StaticAddress< - ::subxt_core::storage::address::StaticStorageKey, - types::reward_vaults::RewardVaults, - ::subxt_core::utils::Yes, - (), - (), - > { - ::subxt_core::storage::address::StaticAddress::new_static( - "MultiAssetDelegation", - "RewardVaults", - ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), - [ - 30u8, 97u8, 236u8, 132u8, 229u8, 86u8, 124u8, 248u8, 89u8, 52u8, 91u8, - 194u8, 48u8, 44u8, 236u8, 142u8, 251u8, 192u8, 107u8, 103u8, 244u8, - 170u8, 94u8, 57u8, 146u8, 82u8, 122u8, 212u8, 228u8, 119u8, 152u8, - 57u8, - ], - ) - } - #[doc = " Storage for the reward vaults"] - pub fn asset_lookup_reward_vaults_iter( - &self, - ) -> ::subxt_core::storage::address::StaticAddress< - (), - types::asset_lookup_reward_vaults::AssetLookupRewardVaults, - (), - (), - ::subxt_core::utils::Yes, - > { - ::subxt_core::storage::address::StaticAddress::new_static( - "MultiAssetDelegation", - "AssetLookupRewardVaults", - (), - [ - 128u8, 153u8, 122u8, 108u8, 34u8, 110u8, 223u8, 199u8, 51u8, 251u8, - 55u8, 208u8, 134u8, 89u8, 137u8, 250u8, 251u8, 211u8, 107u8, 114u8, - 38u8, 28u8, 52u8, 98u8, 234u8, 110u8, 226u8, 205u8, 105u8, 195u8, - 149u8, 113u8, - ], - ) - } - #[doc = " Storage for the reward vaults"] - pub fn asset_lookup_reward_vaults( - &self, - _0: impl ::core::borrow::Borrow, - ) -> ::subxt_core::storage::address::StaticAddress< - ::subxt_core::storage::address::StaticStorageKey< - types::asset_lookup_reward_vaults::Param0, - >, - types::asset_lookup_reward_vaults::AssetLookupRewardVaults, - ::subxt_core::utils::Yes, - (), - (), - > { - ::subxt_core::storage::address::StaticAddress::new_static( - "MultiAssetDelegation", - "AssetLookupRewardVaults", - ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), - [ - 128u8, 153u8, 122u8, 108u8, 34u8, 110u8, 223u8, 199u8, 51u8, 251u8, - 55u8, 208u8, 134u8, 89u8, 137u8, 250u8, 251u8, 211u8, 107u8, 114u8, - 38u8, 28u8, 52u8, 98u8, 234u8, 110u8, 226u8, 205u8, 105u8, 195u8, - 149u8, 113u8, - ], - ) - } - #[doc = " Storage for the reward configuration, which includes APY, cap for assets, and whitelisted"] - #[doc = " blueprints."] - pub fn reward_config_storage( - &self, - ) -> ::subxt_core::storage::address::StaticAddress< - (), - types::reward_config_storage::RewardConfigStorage, - ::subxt_core::utils::Yes, - (), - (), - > { - ::subxt_core::storage::address::StaticAddress::new_static( - "MultiAssetDelegation", - "RewardConfigStorage", - (), - [ - 26u8, 64u8, 254u8, 232u8, 78u8, 131u8, 181u8, 79u8, 218u8, 198u8, - 175u8, 163u8, 209u8, 12u8, 223u8, 53u8, 186u8, 34u8, 69u8, 130u8, 71u8, - 250u8, 86u8, 87u8, 189u8, 145u8, 99u8, 81u8, 200u8, 223u8, 226u8, - 191u8, + 45u8, 173u8, 235u8, 188u8, 23u8, 120u8, 225u8, 27u8, 94u8, 59u8, 35u8, + 139u8, 127u8, 59u8, 118u8, 200u8, 174u8, 212u8, 214u8, 128u8, 40u8, + 187u8, 97u8, 19u8, 236u8, 14u8, 122u8, 135u8, 254u8, 198u8, 21u8, + 238u8, ], ) } @@ -43749,7 +42708,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a new service blueprint."] @@ -43803,7 +42761,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pre-register the caller as an operator for a specific blueprint."] @@ -43859,7 +42816,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Register the caller as an operator for a specific blueprint."] @@ -43924,7 +42880,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unregisters a service provider from a specific service blueprint."] @@ -43969,7 +42924,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates the price targets for a registered operator's service blueprint."] @@ -44018,7 +42972,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Request a new service using a blueprint and specified operators."] @@ -44097,7 +43050,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Approve a service request, allowing it to be initiated once all required approvals are received."] @@ -44143,7 +43095,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Reject a service request, preventing its initiation."] @@ -44189,7 +43140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Terminates a running service instance."] @@ -44232,7 +43182,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Call a job in the service with the provided arguments."] @@ -44288,7 +43237,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Submit a result for a previously called job."] @@ -44344,7 +43292,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Slash an operator's stake for a service by scheduling a deferred slashing action."] @@ -44399,7 +43346,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Disputes and removes an [UnappliedSlash] from storage."] @@ -44447,7 +43393,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates the Master Blueprint Service Manager by adding a new revision."] @@ -45049,7 +43994,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new service blueprint has been created."] @@ -45077,7 +44021,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has pre-registered for a service blueprint."] @@ -45105,7 +44048,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An new operator has been registered."] @@ -45142,7 +44084,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An operator has been unregistered."] @@ -45170,7 +44111,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The price targets for an operator has been updated."] @@ -45200,7 +44140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A new service has been requested."] @@ -45237,7 +44176,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A service request has been approved."] @@ -45272,7 +44210,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A service request has been rejected."] @@ -45302,7 +44239,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A service has been initiated."] @@ -45336,7 +44272,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A service has been terminated."] @@ -45366,7 +44301,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A job has been called."] @@ -45404,7 +44338,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A job result has been submitted."] @@ -45442,7 +44375,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "EVM execution reverted with a reason."] @@ -45474,7 +44406,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An Operator has an unapplied slash."] @@ -45510,7 +44441,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "An Unapplied Slash got discarded."] @@ -45546,7 +44476,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The Master Blueprint Service Manager has been revised."] @@ -46787,7 +45716,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Stakes funds with a pool by transferring the bonded amount from member to pool account."] @@ -46837,7 +45765,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Bond additional funds into an existing pool position."] @@ -46892,7 +45819,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Unbond points from a member's pool position, collecting any pending rewards."] @@ -46954,7 +45880,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Withdraws unbonded funds from the pool's staking account."] @@ -47000,7 +45925,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Withdraw unbonded funds from a member account."] @@ -47057,7 +45981,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a new delegation pool."] @@ -47133,7 +46056,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Create a new delegation pool with a previously used pool ID."] @@ -47213,7 +46135,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Nominate validators on behalf of the pool."] @@ -47261,7 +46182,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates the state of a pool. Once a pool is in `Destroying` state, its state cannot be"] @@ -47311,7 +46231,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates the metadata for a given pool."] @@ -47355,7 +46274,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Updates the global configuration parameters for nomination pools."] @@ -47409,7 +46327,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Update the roles of a pool."] @@ -47467,7 +46384,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Chill on behalf of the pool by forwarding the call to the staking pallet."] @@ -47507,7 +46423,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Bond additional funds for a pool member into their respective pool."] @@ -47560,7 +46475,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set or remove the commission rate and payee for a pool."] @@ -47606,7 +46520,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the maximum commission rate for a pool. Initial max can be set to any value, with only"] @@ -47650,7 +46563,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set the commission change rate for a pool."] @@ -47690,7 +46602,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claim pending commission for a pool."] @@ -47725,7 +46636,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Top up the deficit or withdraw the excess ED from the pool."] @@ -47762,7 +46672,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Set or remove a pool's commission claim permission."] @@ -48541,7 +47450,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool has been created."] @@ -48569,7 +47477,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has become bonded in a pool."] @@ -48601,7 +47508,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A payout has been made to a member."] @@ -48631,7 +47537,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has unbonded from their pool."] @@ -48675,7 +47580,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has withdrawn from their pool."] @@ -48712,7 +47616,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool has been destroyed."] @@ -48738,7 +47641,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The state of a pool has changed"] @@ -48766,7 +47668,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A member has been removed from a pool."] @@ -48796,7 +47697,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The roles of a pool have been updated to the given new roles. Note that the depositor"] @@ -48827,7 +47727,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The active balance of pool `pool_id` has been slashed to `balance`."] @@ -48855,7 +47754,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The unbond pool at `era` of pool `pool_id` has been slashed to `balance`."] @@ -48885,7 +47783,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's commission setting has been changed."] @@ -48916,7 +47813,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's maximum commission setting has been changed."] @@ -48944,7 +47840,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "A pool's commission `change_rate` has been changed."] @@ -48975,7 +47870,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pool commission claim permission has been updated."] @@ -49007,7 +47901,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Pool commission has been claimed."] @@ -49035,7 +47928,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Topped up deficit in frozen ED of the reward pool."] @@ -49063,7 +47955,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Claimed excess frozen ED of the reward pool."] @@ -49874,6 +48765,757 @@ pub mod api { } } } + pub mod rewards { + use super::root_mod; + use super::runtime_types; + #[doc = "The `Error` enum of this pallet."] + pub type Error = runtime_types::pallet_rewards::pallet::Error; + #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] + pub type Call = runtime_types::pallet_rewards::pallet::Call; + pub mod calls { + use super::root_mod; + use super::runtime_types; + type DispatchError = runtime_types::sp_runtime::DispatchError; + pub mod types { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Claim rewards for a specific asset and reward type"] + pub struct ClaimRewards { + pub asset: claim_rewards::Asset, + } + pub mod claim_rewards { + use super::runtime_types; + pub type Asset = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + } + impl ::subxt_core::blocks::StaticExtrinsic for ClaimRewards { + const PALLET: &'static str = "Rewards"; + const CALL: &'static str = "claim_rewards"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Manage asset id to vault rewards."] + #[doc = ""] + #[doc = "# Permissions"] + #[doc = ""] + #[doc = "* Must be signed by an authorized account"] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = ""] + #[doc = "* `origin` - Origin of the call"] + #[doc = "* `vault_id` - ID of the vault"] + #[doc = "* `asset_id` - ID of the asset"] + #[doc = "* `action` - Action to perform (Add/Remove)"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = ""] + #[doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] + #[doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] + pub struct ManageAssetRewardVault { + pub vault_id: manage_asset_reward_vault::VaultId, + pub asset_id: manage_asset_reward_vault::AssetId, + pub action: manage_asset_reward_vault::Action, + } + pub mod manage_asset_reward_vault { + use super::runtime_types; + pub type VaultId = ::core::primitive::u32; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + pub type Action = runtime_types::pallet_rewards::types::AssetAction; + } + impl ::subxt_core::blocks::StaticExtrinsic for ManageAssetRewardVault { + const PALLET: &'static str = "Rewards"; + const CALL: &'static str = "manage_asset_reward_vault"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Updates the reward configuration for a specific vault."] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = "* `origin` - Origin of the call, must pass `ForceOrigin` check"] + #[doc = "* `vault_id` - The ID of the vault to update"] + #[doc = "* `new_config` - The new reward configuration containing:"] + #[doc = " * `apy` - Annual Percentage Yield for the vault"] + #[doc = " * `deposit_cap` - Maximum amount that can be deposited"] + #[doc = " * `incentive_cap` - Maximum amount of incentives that can be distributed"] + #[doc = " * `boost_multiplier` - Optional multiplier to boost rewards"] + #[doc = ""] + #[doc = "# Events"] + #[doc = "* `VaultRewardConfigUpdated` - Emitted when vault reward config is updated"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = "* `BadOrigin` - If caller is not authorized through `ForceOrigin`"] + pub struct UpdateVaultRewardConfig { + pub vault_id: update_vault_reward_config::VaultId, + pub new_config: update_vault_reward_config::NewConfig, + } + pub mod update_vault_reward_config { + use super::runtime_types; + pub type VaultId = ::core::primitive::u32; + pub type NewConfig = + runtime_types::pallet_rewards::types::RewardConfigForAssetVault< + ::core::primitive::u128, + >; + } + impl ::subxt_core::blocks::StaticExtrinsic for UpdateVaultRewardConfig { + const PALLET: &'static str = "Rewards"; + const CALL: &'static str = "update_vault_reward_config"; + } + } + pub struct TransactionApi; + impl TransactionApi { + #[doc = "Claim rewards for a specific asset and reward type"] + pub fn claim_rewards( + &self, + asset: types::claim_rewards::Asset, + ) -> ::subxt_core::tx::payload::StaticPayload { + ::subxt_core::tx::payload::StaticPayload::new_static( + "Rewards", + "claim_rewards", + types::ClaimRewards { asset }, + [ + 146u8, 247u8, 206u8, 171u8, 49u8, 243u8, 126u8, 119u8, 11u8, 3u8, + 246u8, 122u8, 185u8, 167u8, 37u8, 175u8, 105u8, 52u8, 1u8, 229u8, + 118u8, 141u8, 131u8, 54u8, 72u8, 108u8, 95u8, 76u8, 170u8, 179u8, + 122u8, 84u8, + ], + ) + } + #[doc = "Manage asset id to vault rewards."] + #[doc = ""] + #[doc = "# Permissions"] + #[doc = ""] + #[doc = "* Must be signed by an authorized account"] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = ""] + #[doc = "* `origin` - Origin of the call"] + #[doc = "* `vault_id` - ID of the vault"] + #[doc = "* `asset_id` - ID of the asset"] + #[doc = "* `action` - Action to perform (Add/Remove)"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = ""] + #[doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] + #[doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] + pub fn manage_asset_reward_vault( + &self, + vault_id: types::manage_asset_reward_vault::VaultId, + asset_id: types::manage_asset_reward_vault::AssetId, + action: types::manage_asset_reward_vault::Action, + ) -> ::subxt_core::tx::payload::StaticPayload { + ::subxt_core::tx::payload::StaticPayload::new_static( + "Rewards", + "manage_asset_reward_vault", + types::ManageAssetRewardVault { vault_id, asset_id, action }, + [ + 169u8, 45u8, 33u8, 245u8, 172u8, 210u8, 42u8, 4u8, 5u8, 204u8, 254u8, + 113u8, 244u8, 225u8, 108u8, 202u8, 72u8, 107u8, 151u8, 79u8, 209u8, + 56u8, 211u8, 225u8, 95u8, 76u8, 53u8, 22u8, 16u8, 109u8, 70u8, 197u8, + ], + ) + } + #[doc = "Updates the reward configuration for a specific vault."] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = "* `origin` - Origin of the call, must pass `ForceOrigin` check"] + #[doc = "* `vault_id` - The ID of the vault to update"] + #[doc = "* `new_config` - The new reward configuration containing:"] + #[doc = " * `apy` - Annual Percentage Yield for the vault"] + #[doc = " * `deposit_cap` - Maximum amount that can be deposited"] + #[doc = " * `incentive_cap` - Maximum amount of incentives that can be distributed"] + #[doc = " * `boost_multiplier` - Optional multiplier to boost rewards"] + #[doc = ""] + #[doc = "# Events"] + #[doc = "* `VaultRewardConfigUpdated` - Emitted when vault reward config is updated"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = "* `BadOrigin` - If caller is not authorized through `ForceOrigin`"] + pub fn update_vault_reward_config( + &self, + vault_id: types::update_vault_reward_config::VaultId, + new_config: types::update_vault_reward_config::NewConfig, + ) -> ::subxt_core::tx::payload::StaticPayload { + ::subxt_core::tx::payload::StaticPayload::new_static( + "Rewards", + "update_vault_reward_config", + types::UpdateVaultRewardConfig { vault_id, new_config }, + [ + 229u8, 142u8, 118u8, 205u8, 140u8, 240u8, 239u8, 11u8, 235u8, 52u8, + 134u8, 178u8, 160u8, 171u8, 223u8, 51u8, 185u8, 34u8, 90u8, 54u8, + 199u8, 219u8, 39u8, 58u8, 70u8, 249u8, 155u8, 58u8, 67u8, 220u8, 125u8, + 132u8, + ], + ) + } + } + } + #[doc = "The `Event` enum of this pallet"] + pub type Event = runtime_types::pallet_rewards::pallet::Event; + pub mod events { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Rewards have been claimed by an account"] + pub struct RewardsClaimed { + pub account: rewards_claimed::Account, + pub asset: rewards_claimed::Asset, + pub amount: rewards_claimed::Amount, + } + pub mod rewards_claimed { + use super::runtime_types; + pub type Account = ::subxt_core::utils::AccountId32; + pub type Asset = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + pub type Amount = ::core::primitive::u128; + } + impl ::subxt_core::events::StaticEvent for RewardsClaimed { + const PALLET: &'static str = "Rewards"; + const EVENT: &'static str = "RewardsClaimed"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Event emitted when an incentive APY and cap are set for a reward vault"] + pub struct IncentiveAPYAndCapSet { + pub vault_id: incentive_apy_and_cap_set::VaultId, + pub apy: incentive_apy_and_cap_set::Apy, + pub cap: incentive_apy_and_cap_set::Cap, + } + pub mod incentive_apy_and_cap_set { + use super::runtime_types; + pub type VaultId = ::core::primitive::u32; + pub type Apy = runtime_types::sp_arithmetic::per_things::Percent; + pub type Cap = ::core::primitive::u128; + } + impl ::subxt_core::events::StaticEvent for IncentiveAPYAndCapSet { + const PALLET: &'static str = "Rewards"; + const EVENT: &'static str = "IncentiveAPYAndCapSet"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Event emitted when a blueprint is whitelisted for rewards"] + pub struct BlueprintWhitelisted { + pub blueprint_id: blueprint_whitelisted::BlueprintId, + } + pub mod blueprint_whitelisted { + use super::runtime_types; + pub type BlueprintId = ::core::primitive::u64; + } + impl ::subxt_core::events::StaticEvent for BlueprintWhitelisted { + const PALLET: &'static str = "Rewards"; + const EVENT: &'static str = "BlueprintWhitelisted"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Asset has been updated to reward vault"] + pub struct AssetUpdatedInVault { + pub vault_id: asset_updated_in_vault::VaultId, + pub asset_id: asset_updated_in_vault::AssetId, + pub action: asset_updated_in_vault::Action, + } + pub mod asset_updated_in_vault { + use super::runtime_types; + pub type VaultId = ::core::primitive::u32; + pub type AssetId = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + pub type Action = runtime_types::pallet_rewards::types::AssetAction; + } + impl ::subxt_core::events::StaticEvent for AssetUpdatedInVault { + const PALLET: &'static str = "Rewards"; + const EVENT: &'static str = "AssetUpdatedInVault"; + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub struct VaultRewardConfigUpdated { + pub vault_id: vault_reward_config_updated::VaultId, + } + pub mod vault_reward_config_updated { + use super::runtime_types; + pub type VaultId = ::core::primitive::u32; + } + impl ::subxt_core::events::StaticEvent for VaultRewardConfigUpdated { + const PALLET: &'static str = "Rewards"; + const EVENT: &'static str = "VaultRewardConfigUpdated"; + } + } + pub mod storage { + use super::runtime_types; + pub mod types { + use super::runtime_types; + pub mod total_reward_vault_score { + use super::runtime_types; + pub type TotalRewardVaultScore = ::core::primitive::u128; + pub type Param0 = ::core::primitive::u32; + } + pub mod user_service_reward { + use super::runtime_types; + pub type UserServiceReward = ::core::primitive::u128; + pub type Param0 = ::subxt_core::utils::AccountId32; + pub type Param1 = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + } + pub mod user_claimed_reward { + use super::runtime_types; + pub type UserClaimedReward = (::core::primitive::u64, ::core::primitive::u128); + pub type Param0 = ::subxt_core::utils::AccountId32; + pub type Param1 = ::core::primitive::u32; + } + pub mod reward_vaults { + use super::runtime_types; + pub type RewardVaults = ::subxt_core::alloc::vec::Vec< + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>, + >; + pub type Param0 = ::core::primitive::u32; + } + pub mod asset_lookup_reward_vaults { + use super::runtime_types; + pub type AssetLookupRewardVaults = ::core::primitive::u32; + pub type Param0 = + runtime_types::tangle_primitives::services::Asset<::core::primitive::u128>; + } + pub mod reward_config_storage { + use super::runtime_types; + pub type RewardConfigStorage = + runtime_types::pallet_rewards::types::RewardConfigForAssetVault< + ::core::primitive::u128, + >; + pub type Param0 = ::core::primitive::u32; + } + } + pub struct StorageApi; + impl StorageApi { + #[doc = " Stores the total score for each asset"] + pub fn total_reward_vault_score_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::total_reward_vault_score::TotalRewardVaultScore, + (), + ::subxt_core::utils::Yes, + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "TotalRewardVaultScore", + (), + [ + 81u8, 149u8, 62u8, 176u8, 255u8, 187u8, 21u8, 2u8, 204u8, 121u8, 214u8, + 125u8, 223u8, 182u8, 204u8, 248u8, 232u8, 123u8, 163u8, 177u8, 173u8, + 25u8, 97u8, 90u8, 204u8, 82u8, 152u8, 36u8, 20u8, 13u8, 13u8, 189u8, + ], + ) + } + #[doc = " Stores the total score for each asset"] + pub fn total_reward_vault_score( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::total_reward_vault_score::Param0, + >, + types::total_reward_vault_score::TotalRewardVaultScore, + ::subxt_core::utils::Yes, + ::subxt_core::utils::Yes, + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "TotalRewardVaultScore", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 81u8, 149u8, 62u8, 176u8, 255u8, 187u8, 21u8, 2u8, 204u8, 121u8, 214u8, + 125u8, 223u8, 182u8, 204u8, 248u8, 232u8, 123u8, 163u8, 177u8, 173u8, + 25u8, 97u8, 90u8, 204u8, 82u8, 152u8, 36u8, 20u8, 13u8, 13u8, 189u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_service_reward_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::user_service_reward::UserServiceReward, + (), + ::subxt_core::utils::Yes, + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserServiceReward", + (), + [ + 17u8, 184u8, 103u8, 139u8, 191u8, 239u8, 87u8, 61u8, 131u8, 108u8, + 189u8, 182u8, 114u8, 33u8, 47u8, 131u8, 228u8, 166u8, 129u8, 195u8, + 95u8, 198u8, 106u8, 161u8, 83u8, 38u8, 144u8, 23u8, 243u8, 6u8, 134u8, + 164u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_service_reward_iter1( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::user_service_reward::Param0, + >, + types::user_service_reward::UserServiceReward, + (), + ::subxt_core::utils::Yes, + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserServiceReward", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 17u8, 184u8, 103u8, 139u8, 191u8, 239u8, 87u8, 61u8, 131u8, 108u8, + 189u8, 182u8, 114u8, 33u8, 47u8, 131u8, 228u8, 166u8, 129u8, 195u8, + 95u8, 198u8, 106u8, 161u8, 83u8, 38u8, 144u8, 23u8, 243u8, 6u8, 134u8, + 164u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_service_reward( + &self, + _0: impl ::core::borrow::Borrow, + _1: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ( + ::subxt_core::storage::address::StaticStorageKey< + types::user_service_reward::Param0, + >, + ::subxt_core::storage::address::StaticStorageKey< + types::user_service_reward::Param1, + >, + ), + types::user_service_reward::UserServiceReward, + ::subxt_core::utils::Yes, + ::subxt_core::utils::Yes, + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserServiceReward", + ( + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt_core::storage::address::StaticStorageKey::new(_1.borrow()), + ), + [ + 17u8, 184u8, 103u8, 139u8, 191u8, 239u8, 87u8, 61u8, 131u8, 108u8, + 189u8, 182u8, 114u8, 33u8, 47u8, 131u8, 228u8, 166u8, 129u8, 195u8, + 95u8, 198u8, 106u8, 161u8, 83u8, 38u8, 144u8, 23u8, 243u8, 6u8, 134u8, + 164u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_claimed_reward_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::user_claimed_reward::UserClaimedReward, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserClaimedReward", + (), + [ + 206u8, 242u8, 28u8, 7u8, 152u8, 211u8, 16u8, 91u8, 52u8, 84u8, 0u8, + 224u8, 145u8, 43u8, 26u8, 136u8, 113u8, 169u8, 109u8, 251u8, 145u8, + 75u8, 183u8, 206u8, 220u8, 207u8, 232u8, 152u8, 219u8, 88u8, 209u8, + 94u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_claimed_reward_iter1( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::user_claimed_reward::Param0, + >, + types::user_claimed_reward::UserClaimedReward, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserClaimedReward", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 206u8, 242u8, 28u8, 7u8, 152u8, 211u8, 16u8, 91u8, 52u8, 84u8, 0u8, + 224u8, 145u8, 43u8, 26u8, 136u8, 113u8, 169u8, 109u8, 251u8, 145u8, + 75u8, 183u8, 206u8, 220u8, 207u8, 232u8, 152u8, 219u8, 88u8, 209u8, + 94u8, + ], + ) + } + #[doc = " Stores the service reward for a given user"] + pub fn user_claimed_reward( + &self, + _0: impl ::core::borrow::Borrow, + _1: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ( + ::subxt_core::storage::address::StaticStorageKey< + types::user_claimed_reward::Param0, + >, + ::subxt_core::storage::address::StaticStorageKey< + types::user_claimed_reward::Param1, + >, + ), + types::user_claimed_reward::UserClaimedReward, + ::subxt_core::utils::Yes, + (), + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "UserClaimedReward", + ( + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt_core::storage::address::StaticStorageKey::new(_1.borrow()), + ), + [ + 206u8, 242u8, 28u8, 7u8, 152u8, 211u8, 16u8, 91u8, 52u8, 84u8, 0u8, + 224u8, 145u8, 43u8, 26u8, 136u8, 113u8, 169u8, 109u8, 251u8, 145u8, + 75u8, 183u8, 206u8, 220u8, 207u8, 232u8, 152u8, 219u8, 88u8, 209u8, + 94u8, + ], + ) + } + #[doc = " Storage for the reward vaults"] + pub fn reward_vaults_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::reward_vaults::RewardVaults, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "RewardVaults", + (), + [ + 29u8, 120u8, 143u8, 243u8, 2u8, 41u8, 241u8, 174u8, 61u8, 231u8, 246u8, + 255u8, 254u8, 79u8, 10u8, 248u8, 59u8, 248u8, 189u8, 209u8, 84u8, 90u8, + 111u8, 27u8, 92u8, 110u8, 210u8, 152u8, 231u8, 154u8, 161u8, 112u8, + ], + ) + } + #[doc = " Storage for the reward vaults"] + pub fn reward_vaults( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey, + types::reward_vaults::RewardVaults, + ::subxt_core::utils::Yes, + (), + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "RewardVaults", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 29u8, 120u8, 143u8, 243u8, 2u8, 41u8, 241u8, 174u8, 61u8, 231u8, 246u8, + 255u8, 254u8, 79u8, 10u8, 248u8, 59u8, 248u8, 189u8, 209u8, 84u8, 90u8, + 111u8, 27u8, 92u8, 110u8, 210u8, 152u8, 231u8, 154u8, 161u8, 112u8, + ], + ) + } + #[doc = " Storage for the reward vaults"] + pub fn asset_lookup_reward_vaults_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::asset_lookup_reward_vaults::AssetLookupRewardVaults, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "AssetLookupRewardVaults", + (), + [ + 102u8, 24u8, 170u8, 108u8, 171u8, 54u8, 53u8, 186u8, 3u8, 87u8, 224u8, + 25u8, 113u8, 74u8, 180u8, 59u8, 181u8, 120u8, 89u8, 36u8, 0u8, 245u8, + 81u8, 197u8, 154u8, 157u8, 52u8, 213u8, 151u8, 197u8, 46u8, 173u8, + ], + ) + } + #[doc = " Storage for the reward vaults"] + pub fn asset_lookup_reward_vaults( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::asset_lookup_reward_vaults::Param0, + >, + types::asset_lookup_reward_vaults::AssetLookupRewardVaults, + ::subxt_core::utils::Yes, + (), + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "AssetLookupRewardVaults", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 102u8, 24u8, 170u8, 108u8, 171u8, 54u8, 53u8, 186u8, 3u8, 87u8, 224u8, + 25u8, 113u8, 74u8, 180u8, 59u8, 181u8, 120u8, 89u8, 36u8, 0u8, 245u8, + 81u8, 197u8, 154u8, 157u8, 52u8, 213u8, 151u8, 197u8, 46u8, 173u8, + ], + ) + } + #[doc = " Storage for the reward configuration, which includes APY, cap for assets"] + pub fn reward_config_storage_iter( + &self, + ) -> ::subxt_core::storage::address::StaticAddress< + (), + types::reward_config_storage::RewardConfigStorage, + (), + (), + ::subxt_core::utils::Yes, + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "RewardConfigStorage", + (), + [ + 85u8, 116u8, 237u8, 245u8, 144u8, 61u8, 218u8, 181u8, 11u8, 129u8, + 196u8, 245u8, 46u8, 142u8, 68u8, 87u8, 87u8, 120u8, 122u8, 111u8, 59u8, + 219u8, 226u8, 166u8, 9u8, 21u8, 235u8, 215u8, 165u8, 191u8, 14u8, 64u8, + ], + ) + } + #[doc = " Storage for the reward configuration, which includes APY, cap for assets"] + pub fn reward_config_storage( + &self, + _0: impl ::core::borrow::Borrow, + ) -> ::subxt_core::storage::address::StaticAddress< + ::subxt_core::storage::address::StaticStorageKey< + types::reward_config_storage::Param0, + >, + types::reward_config_storage::RewardConfigStorage, + ::subxt_core::utils::Yes, + (), + (), + > { + ::subxt_core::storage::address::StaticAddress::new_static( + "Rewards", + "RewardConfigStorage", + ::subxt_core::storage::address::StaticStorageKey::new(_0.borrow()), + [ + 85u8, 116u8, 237u8, 245u8, 144u8, 61u8, 218u8, 181u8, 11u8, 129u8, + 196u8, 245u8, 46u8, 142u8, 68u8, 87u8, 87u8, 120u8, 122u8, 111u8, 59u8, + 219u8, 226u8, 166u8, 9u8, 21u8, 235u8, 215u8, 165u8, 191u8, 14u8, 64u8, + ], + ) + } + } + } + } pub mod runtime_types { use super::runtime_types; pub mod bounded_collections { @@ -49891,7 +49533,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BoundedBTreeMap<_0, _1>(pub ::subxt_core::utils::KeyedVec<_0, _1>); @@ -49909,7 +49550,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BoundedBTreeSet<_0>(pub ::subxt_core::alloc::vec::Vec<_0>); @@ -49929,7 +49569,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BoundedVec<_0>(pub ::subxt_core::alloc::vec::Vec<_0>); @@ -49947,7 +49586,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WeakBoundedVec<_0>(pub ::subxt_core::alloc::vec::Vec<_0>); @@ -49966,7 +49604,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Bloom(pub [::core::primitive::u8; 256usize]); @@ -49986,7 +49623,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Block<_0> { @@ -50009,7 +49645,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Header { @@ -50043,7 +49678,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Log { @@ -50065,7 +49699,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EIP658ReceiptData { @@ -50085,7 +49718,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ReceiptV3 { @@ -50110,7 +49742,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccessListItem { @@ -50128,7 +49759,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EIP1559Transaction { @@ -50158,7 +49788,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EIP2930Transaction { @@ -50187,7 +49816,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct LegacyTransaction { @@ -50210,7 +49838,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TransactionAction { @@ -50231,7 +49858,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TransactionRecoveryId(pub ::core::primitive::u64); @@ -50246,7 +49872,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TransactionSignature { @@ -50265,7 +49890,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TransactionV2 { @@ -50293,7 +49917,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct H64(pub [::core::primitive::u8; 8usize]); @@ -50314,7 +49937,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Basic { @@ -50338,7 +49960,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExitError { @@ -50386,7 +50007,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExitFatal { @@ -50410,7 +50030,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExitReason { @@ -50434,7 +50053,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExitRevert { @@ -50452,7 +50070,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExitSucceed { @@ -50478,7 +50095,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Opcode(pub ::core::primitive::u8); @@ -50497,7 +50113,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Equivocation<_0, _1, _2> { @@ -50517,7 +50132,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Precommit<_0, _1> { @@ -50535,7 +50149,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Prevote<_0, _1> { @@ -50556,7 +50169,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExecutionInfoV2<_0> { @@ -50577,7 +50189,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UsedGas { @@ -50595,7 +50206,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WeightInfo { @@ -50618,7 +50228,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TransactionStatus { @@ -50646,7 +50255,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UncheckedExtrinsic<_0, _1, _2, _3>( @@ -50667,7 +50275,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckMetadataHash { @@ -50684,7 +50291,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Mode { @@ -50709,7 +50315,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DispatchClass { @@ -50731,7 +50336,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct DispatchInfo { @@ -50750,7 +50354,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Pays { @@ -50770,7 +50373,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PerDispatchClass<_0> { @@ -50789,7 +50391,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RawOrigin<_0> { @@ -50816,7 +50417,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Bounded<_0, _1> { @@ -50853,7 +50453,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum BalanceStatus { @@ -50873,7 +50472,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct IdAmount<_0, _1> { @@ -50894,7 +50492,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PalletId(pub [::core::primitive::u8; 8usize]); @@ -50916,7 +50513,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckGenesis; @@ -50934,7 +50530,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckMortality(pub runtime_types::sp_runtime::generic::era::Era); @@ -50952,7 +50547,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckNonZeroSender; @@ -50970,7 +50564,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckNonce(#[codec(compact)] pub ::core::primitive::u32); @@ -50988,7 +50581,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckSpecVersion; @@ -51006,7 +50598,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckTxVersion; @@ -51024,7 +50615,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckWeight; @@ -51043,7 +50633,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BlockLength { @@ -51062,7 +50651,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BlockWeights { @@ -51083,7 +50671,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WeightsPerClass { @@ -51109,7 +50696,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -51203,7 +50789,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error for the System pallet"] @@ -51251,7 +50836,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Event for the System pallet."] @@ -51301,7 +50885,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccountInfo<_0, _1> { @@ -51322,7 +50905,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CodeUpgradeAuthorization { @@ -51340,7 +50922,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EventRecord<_0, _1> { @@ -51359,7 +50940,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct LastRuntimeUpgradeInfo { @@ -51378,7 +50958,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Phase { @@ -51405,7 +50984,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -51545,7 +51123,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -51587,7 +51164,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -51616,7 +51192,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EcdsaSignature(pub [::core::primitive::u8; 65usize]); @@ -51631,7 +51206,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EthereumAddress(pub [::core::primitive::u8; 20usize]); @@ -51647,7 +51221,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum MultiAddress { @@ -51663,7 +51236,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum MultiAddressSignature { @@ -51679,7 +51251,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Sr25519Signature(pub [::core::primitive::u8; 64usize]); @@ -51695,7 +51266,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum StatementKind { @@ -51720,7 +51290,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -52462,7 +52031,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -52545,7 +52113,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -52725,7 +52292,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum AccountStatus { @@ -52747,7 +52313,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Approval<_0, _1> { @@ -52765,7 +52330,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AssetAccount<_0, _1, _2, _3> { @@ -52787,7 +52351,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AssetDetails<_0, _1, _2> { @@ -52815,7 +52378,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AssetMetadata<_0, _1> { @@ -52836,7 +52398,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum AssetStatus { @@ -52858,7 +52419,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExistenceReason<_0, _1> { @@ -52890,7 +52450,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -52951,7 +52510,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -52986,7 +52544,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Bag { @@ -53004,7 +52561,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ListError { @@ -53028,7 +52584,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Node { @@ -53052,7 +52607,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -53117,7 +52671,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -53137,7 +52690,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -53173,7 +52725,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -53318,7 +52869,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -53371,7 +52921,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -53520,7 +53069,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AccountData<_0> { @@ -53540,7 +53088,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum AdjustmentDirection { @@ -53560,7 +53107,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BalanceLock<_0> { @@ -53580,7 +53126,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExtraFlags(pub ::core::primitive::u128); @@ -53595,7 +53140,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Reasons { @@ -53617,7 +53161,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ReserveData<_0, _1> { @@ -53641,7 +53184,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -53662,7 +53204,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -53691,7 +53232,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -53850,7 +53390,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -53901,7 +53440,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -53965,7 +53503,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Bounty<_0, _1, _2> { @@ -53987,7 +53524,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum BountyStatus<_0, _1> { @@ -54020,7 +53556,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -54239,7 +53774,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -54265,7 +53799,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -54304,7 +53837,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ChildBounty<_0, _1, _2> { @@ -54325,7 +53857,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ChildBountyStatus<_0, _1> { @@ -54354,7 +53885,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -54504,7 +54034,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -54554,7 +54083,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -54618,7 +54146,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RawOrigin<_0> { @@ -54640,7 +54167,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Votes<_0, _1> { @@ -54666,7 +54192,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Conviction { @@ -54699,7 +54224,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -55032,7 +54556,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -55122,7 +54645,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -55228,7 +54750,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Delegations<_0> { @@ -55246,7 +54767,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum MetadataOwner { @@ -55268,7 +54788,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ReferendumInfo<_0, _1, _2> { @@ -55288,7 +54807,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ReferendumStatus<_0, _1, _2> { @@ -55309,7 +54827,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Tally<_0> { @@ -55331,7 +54848,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum AccountVote<_0> { @@ -55351,7 +54867,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PriorLock<_0, _1>(pub _0, pub _1); @@ -55367,7 +54882,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Vote(pub ::core::primitive::u8); @@ -55382,7 +54896,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Voting<_0, _1, _2> { @@ -55418,7 +54931,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum VoteThreshold { @@ -55446,7 +54958,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -55471,7 +54982,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -55488,7 +54998,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error of the pallet that can be returned in response to dispatches."] @@ -55550,7 +55059,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -55619,7 +55127,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SignedSubmission<_0, _1, _2> { @@ -55641,7 +55148,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ElectionCompute { @@ -55667,7 +55173,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Phase<_0> { @@ -55691,7 +55196,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RawSolution<_0> { @@ -55710,7 +55214,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ReadySolution { @@ -55732,7 +55235,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RoundSnapshot<_0, _1> { @@ -55750,7 +55252,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SolutionOrSnapshotSize { @@ -55775,7 +55276,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -55907,7 +55407,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -55975,7 +55474,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -56034,7 +55532,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Renouncing { @@ -56056,7 +55553,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SeatHolder<_0, _1> { @@ -56075,7 +55571,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Voter<_0, _1> { @@ -56099,7 +55594,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -56119,7 +55613,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -56142,7 +55635,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -56169,7 +55661,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RawOrigin { @@ -56192,7 +55683,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -56263,7 +55753,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -56319,7 +55808,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -56352,7 +55840,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CodeMetadata { @@ -56375,7 +55862,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -56442,7 +55928,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -56482,7 +55967,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -56514,7 +55998,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct StoredPendingChange<_0> { @@ -56538,7 +56021,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum StoredState<_0> { @@ -56567,7 +56049,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -56592,7 +56073,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -56618,7 +56098,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct IdentityInfo { @@ -56649,7 +56128,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Identity pallet declaration."] @@ -56972,7 +56450,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -57067,7 +56544,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -57188,7 +56664,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct AuthorityProperties<_0> { @@ -57206,7 +56681,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Data { @@ -57298,7 +56772,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Judgement<_0> { @@ -57328,7 +56801,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RegistrarInfo<_0, _1, _2> { @@ -57347,7 +56819,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Registration<_0, _2> { @@ -57375,7 +56846,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -57401,7 +56871,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -57424,7 +56893,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -57465,7 +56933,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Public(pub [::core::primitive::u8; 32usize]); @@ -57480,7 +56947,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Signature(pub [::core::primitive::u8; 64usize]); @@ -57497,7 +56963,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Heartbeat<_0> { @@ -57522,7 +56987,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -57623,7 +57087,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -57655,7 +57118,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -57693,12 +57155,11 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The callable functions (extrinsics) of the pallet."] pub enum Call { - # [codec (index = 0)] # [doc = "Allows an account to join as an operator by staking the required bond amount."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the account joining as operator"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `bond_amount` - Amount to stake as operator bond"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::DepositOverflow`] - Bond amount would overflow deposit tracking"] # [doc = "* [`Error::StakeOverflow`] - Bond amount would overflow stake tracking"] join_operators { bond_amount : :: core :: primitive :: u128 , } , # [codec (index = 1)] # [doc = "Schedules an operator to leave the system."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Operator already has a pending unstake request"] schedule_leave_operators , # [codec (index = 2)] # [doc = "Cancels a scheduled leave for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_leave_operators , # [codec (index = 3)] # [doc = "Executes a scheduled leave for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed yet"] execute_leave_operators , # [codec (index = 4)] # [doc = "Allows an operator to increase their stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `additional_bond` - Additional amount to stake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::StakeOverflow`] - Additional bond would overflow stake tracking"] operator_bond_more { additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "Schedules an operator to decrease their stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `unstake_amount` - Amount to unstake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Operator already has a pending unstake request"] # [doc = "* [`Error::InsufficientBalance`] - Operator has insufficient stake to unstake"] schedule_operator_unstake { unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "Executes a scheduled stake decrease for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed yet"] execute_operator_unstake , # [codec (index = 7)] # [doc = "Cancels a scheduled stake decrease for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_operator_unstake , # [codec (index = 8)] # [doc = "Allows an operator to go offline."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::AlreadyOffline`] - Operator is already offline"] go_offline , # [codec (index = 9)] # [doc = "Allows an operator to go online."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::AlreadyOnline`] - Operator is already online"] go_online , # [codec (index = 10)] # [doc = "Allows a user to deposit an asset."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the depositor account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset to deposit"] # [doc = "* `amount` - Amount to deposit"] # [doc = "* `evm_address` - Optional EVM address"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::DepositOverflow`] - Deposit would overflow tracking"] # [doc = "* [`Error::InvalidAsset`] - Asset is not supported"] deposit { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , } , # [codec (index = 11)] # [doc = "Schedules a withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset to withdraw"] # [doc = "* `amount` - Amount to withdraw"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::InsufficientBalance`] - Insufficient balance to withdraw"] # [doc = "* [`Error::PendingWithdrawRequestExists`] - Pending withdraw request exists"] schedule_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 12)] # [doc = "Executes a scheduled withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `evm_address` - Optional EVM address"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NoWithdrawRequestExists`] - No pending withdraw request exists"] # [doc = "* [`Error::WithdrawPeriodNotElapsed`] - Withdraw period has not elapsed"] execute_withdraw { evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , } , # [codec (index = 13)] # [doc = "Cancels a scheduled withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset withdrawal to cancel"] # [doc = "* `amount` - Amount of the withdrawal to cancel"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NoWithdrawRequestExists`] - No pending withdraw request exists"] cancel_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 14)] # [doc = "Allows a user to delegate an amount of an asset to an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to delegate to"] # [doc = "* `asset_id` - ID of asset to delegate"] # [doc = "* `amount` - Amount to delegate"] # [doc = "* `blueprint_selection` - Blueprint selection strategy"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Target account is not an operator"] # [doc = "* [`Error::InsufficientBalance`] - Insufficient balance to delegate"] # [doc = "* [`Error::MaxDelegationsExceeded`] - Would exceed max delegations"] delegate { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > , } , # [codec (index = 15)] # [doc = "Schedules a request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to unstake from"] # [doc = "* `asset_id` - ID of asset to unstake"] # [doc = "* `amount` - Amount to unstake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::InsufficientDelegation`] - Insufficient delegation to unstake"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Pending unstake request exists"] schedule_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 16)] # [doc = "Executes a scheduled request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed"] execute_delegator_unstake , # [codec (index = 17)] # [doc = "Cancels a scheduled request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to cancel unstake from"] # [doc = "* `asset_id` - ID of asset unstake to cancel"] # [doc = "* `amount` - Amount of unstake to cancel"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 18)] # [doc = "Sets the APY and cap for a specific asset."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be called by the force origin"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `vault_id` - ID of the vault"] # [doc = "* `apy` - Annual percentage yield (max 10%)"] # [doc = "* `cap` - Required deposit amount for full APY"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::APYExceedsMaximum`] - APY exceeds 10% maximum"] # [doc = "* [`Error::CapCannotBeZero`] - Cap amount cannot be zero"] set_incentive_apy_and_cap { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Whitelists a blueprint for rewards."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be called by the force origin"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `blueprint_id` - ID of blueprint to whitelist"] whitelist_blueprint_for_rewards { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 20)] # [doc = "Manage asset id to vault rewards."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by an authorized account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `vault_id` - ID of the vault"] # [doc = "* `asset_id` - ID of the asset"] # [doc = "* `action` - Action to perform (Add/Remove)"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] # [doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] manage_asset_in_vault { vault_id : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 22)] # [doc = "Adds a blueprint ID to a delegator's selection."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `blueprint_id` - ID of blueprint to add"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::DuplicateBlueprintId`] - Blueprint ID already exists"] # [doc = "* [`Error::MaxBlueprintsExceeded`] - Would exceed max blueprints"] # [doc = "* [`Error::NotInFixedMode`] - Not in fixed blueprint selection mode"] add_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 23)] # [doc = "Removes a blueprint ID from a delegator's selection."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `blueprint_id` - ID of blueprint to remove"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::BlueprintIdNotFound`] - Blueprint ID not found"] # [doc = "* [`Error::NotInFixedMode`] - Not in fixed blueprint selection mode"] remove_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , } + # [codec (index = 0)] # [doc = "Allows an account to join as an operator by staking the required bond amount."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the account joining as operator"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `bond_amount` - Amount to stake as operator bond"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::DepositOverflow`] - Bond amount would overflow deposit tracking"] # [doc = "* [`Error::StakeOverflow`] - Bond amount would overflow stake tracking"] join_operators { bond_amount : :: core :: primitive :: u128 , } , # [codec (index = 1)] # [doc = "Schedules an operator to leave the system."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Operator already has a pending unstake request"] schedule_leave_operators , # [codec (index = 2)] # [doc = "Cancels a scheduled leave for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_leave_operators , # [codec (index = 3)] # [doc = "Executes a scheduled leave for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed yet"] execute_leave_operators , # [codec (index = 4)] # [doc = "Allows an operator to increase their stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `additional_bond` - Additional amount to stake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::StakeOverflow`] - Additional bond would overflow stake tracking"] operator_bond_more { additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "Schedules an operator to decrease their stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `unstake_amount` - Amount to unstake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Operator already has a pending unstake request"] # [doc = "* [`Error::InsufficientBalance`] - Operator has insufficient stake to unstake"] schedule_operator_unstake { unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "Executes a scheduled stake decrease for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed yet"] execute_operator_unstake , # [codec (index = 7)] # [doc = "Cancels a scheduled stake decrease for an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_operator_unstake , # [codec (index = 8)] # [doc = "Allows an operator to go offline."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::AlreadyOffline`] - Operator is already offline"] go_offline , # [codec (index = 9)] # [doc = "Allows an operator to go online."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the operator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Account is not registered as an operator"] # [doc = "* [`Error::AlreadyOnline`] - Operator is already online"] go_online , # [codec (index = 10)] # [doc = "Allows a user to deposit an asset."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the depositor account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset to deposit"] # [doc = "* `amount` - Amount to deposit"] # [doc = "* `evm_address` - Optional EVM address"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::DepositOverflow`] - Deposit would overflow tracking"] # [doc = "* [`Error::InvalidAsset`] - Asset is not supported"] deposit { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , lock_multiplier : :: core :: option :: Option < runtime_types :: tangle_primitives :: types :: rewards :: LockMultiplier > , } , # [codec (index = 11)] # [doc = "Schedules a withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset to withdraw"] # [doc = "* `amount` - Amount to withdraw"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::InsufficientBalance`] - Insufficient balance to withdraw"] # [doc = "* [`Error::PendingWithdrawRequestExists`] - Pending withdraw request exists"] schedule_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 12)] # [doc = "Executes a scheduled withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `evm_address` - Optional EVM address"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NoWithdrawRequestExists`] - No pending withdraw request exists"] # [doc = "* [`Error::WithdrawPeriodNotElapsed`] - Withdraw period has not elapsed"] execute_withdraw { evm_address : :: core :: option :: Option < :: subxt_core :: utils :: H160 > , } , # [codec (index = 13)] # [doc = "Cancels a scheduled withdraw request."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the withdrawer account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `asset_id` - ID of the asset withdrawal to cancel"] # [doc = "* `amount` - Amount of the withdrawal to cancel"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NoWithdrawRequestExists`] - No pending withdraw request exists"] cancel_withdraw { asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 14)] # [doc = "Allows a user to delegate an amount of an asset to an operator."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to delegate to"] # [doc = "* `asset_id` - ID of asset to delegate"] # [doc = "* `amount` - Amount to delegate"] # [doc = "* `blueprint_selection` - Blueprint selection strategy"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotOperator`] - Target account is not an operator"] # [doc = "* [`Error::InsufficientBalance`] - Insufficient balance to delegate"] # [doc = "* [`Error::MaxDelegationsExceeded`] - Would exceed max delegations"] delegate { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < runtime_types :: tangle_testnet_runtime :: MaxDelegatorBlueprints > , } , # [codec (index = 15)] # [doc = "Schedules a request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to unstake from"] # [doc = "* `asset_id` - ID of asset to unstake"] # [doc = "* `amount` - Amount to unstake"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::InsufficientDelegation`] - Insufficient delegation to unstake"] # [doc = "* [`Error::PendingUnstakeRequestExists`] - Pending unstake request exists"] schedule_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 16)] # [doc = "Executes a scheduled request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] # [doc = "* [`Error::UnstakePeriodNotElapsed`] - Unstake period has not elapsed"] execute_delegator_unstake , # [codec (index = 17)] # [doc = "Cancels a scheduled request to reduce a delegator's stake."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `operator` - Operator to cancel unstake from"] # [doc = "* `asset_id` - ID of asset unstake to cancel"] # [doc = "* `amount` - Amount of unstake to cancel"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::NoUnstakeRequestExists`] - No pending unstake request exists"] cancel_delegator_unstake { operator : :: subxt_core :: utils :: AccountId32 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , amount : :: core :: primitive :: u128 , } , # [codec (index = 22)] # [doc = "Adds a blueprint ID to a delegator's selection."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `blueprint_id` - ID of blueprint to add"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::DuplicateBlueprintId`] - Blueprint ID already exists"] # [doc = "* [`Error::MaxBlueprintsExceeded`] - Would exceed max blueprints"] # [doc = "* [`Error::NotInFixedMode`] - Not in fixed blueprint selection mode"] add_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 23)] # [doc = "Removes a blueprint ID from a delegator's selection."] # [doc = ""] # [doc = "# Permissions"] # [doc = ""] # [doc = "* Must be signed by the delegator account"] # [doc = ""] # [doc = "# Arguments"] # [doc = ""] # [doc = "* `origin` - Origin of the call"] # [doc = "* `blueprint_id` - ID of blueprint to remove"] # [doc = ""] # [doc = "# Errors"] # [doc = ""] # [doc = "* [`Error::NotDelegator`] - Account is not a delegator"] # [doc = "* [`Error::BlueprintIdNotFound`] - Blueprint ID not found"] # [doc = "* [`Error::NotInFixedMode`] - Not in fixed blueprint selection mode"] remove_blueprint_id { blueprint_id : :: core :: primitive :: u64 , } , } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -57710,7 +57171,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Errors emitted by the pallet."] @@ -57865,6 +57325,12 @@ pub mod api { #[codec(index = 49)] #[doc = "EVM decode error"] EVMAbiDecode, + #[codec(index = 50)] + #[doc = "Cannot unstake with locks"] + LockViolation, + #[codec(index = 51)] + #[doc = "Above deposit caps setup"] + DepositExceedsCapForAsset, } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -57877,12 +57343,117 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events emitted by the pallet."] pub enum Event { - # [codec (index = 0)] # [doc = "An operator has joined."] OperatorJoined { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 1)] # [doc = "An operator has scheduled to leave."] OperatorLeavingScheduled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 2)] # [doc = "An operator has cancelled their leave request."] OperatorLeaveCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 3)] # [doc = "An operator has executed their leave request."] OperatorLeaveExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 4)] # [doc = "An operator has increased their stake."] OperatorBondMore { who : :: subxt_core :: utils :: AccountId32 , additional_bond : :: core :: primitive :: u128 , } , # [codec (index = 5)] # [doc = "An operator has scheduled to decrease their stake."] OperatorBondLessScheduled { who : :: subxt_core :: utils :: AccountId32 , unstake_amount : :: core :: primitive :: u128 , } , # [codec (index = 6)] # [doc = "An operator has executed their stake decrease."] OperatorBondLessExecuted { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 7)] # [doc = "An operator has cancelled their stake decrease request."] OperatorBondLessCancelled { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 8)] # [doc = "An operator has gone offline."] OperatorWentOffline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 9)] # [doc = "An operator has gone online."] OperatorWentOnline { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 10)] # [doc = "A deposit has been made."] Deposited { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 11)] # [doc = "An withdraw has been scheduled."] Scheduledwithdraw { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 12)] # [doc = "An withdraw has been executed."] Executedwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 13)] # [doc = "An withdraw has been cancelled."] Cancelledwithdraw { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 14)] # [doc = "A delegation has been made."] Delegated { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 15)] # [doc = "A delegator unstake request has been scheduled."] ScheduledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , operator : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , } , # [codec (index = 16)] # [doc = "A delegator unstake request has been executed."] ExecutedDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 17)] # [doc = "A delegator unstake request has been cancelled."] CancelledDelegatorBondLess { who : :: subxt_core :: utils :: AccountId32 , } , # [codec (index = 18)] # [doc = "Event emitted when an incentive APY and cap are set for a reward vault"] IncentiveAPYAndCapSet { vault_id : :: core :: primitive :: u128 , apy : runtime_types :: sp_arithmetic :: per_things :: Percent , cap : :: core :: primitive :: u128 , } , # [codec (index = 19)] # [doc = "Event emitted when a blueprint is whitelisted for rewards"] BlueprintWhitelisted { blueprint_id : :: core :: primitive :: u64 , } , # [codec (index = 20)] # [doc = "Asset has been updated to reward vault"] AssetUpdatedInVault { who : :: subxt_core :: utils :: AccountId32 , vault_id : :: core :: primitive :: u128 , asset_id : runtime_types :: tangle_primitives :: services :: Asset < :: core :: primitive :: u128 > , action : runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: AssetAction , } , # [codec (index = 21)] # [doc = "Operator has been slashed"] OperatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , # [codec (index = 22)] # [doc = "Delegator has been slashed"] DelegatorSlashed { who : :: subxt_core :: utils :: AccountId32 , amount : :: core :: primitive :: u128 , } , # [codec (index = 23)] # [doc = "EVM execution reverted with a reason."] EvmReverted { from : :: subxt_core :: utils :: H160 , to : :: subxt_core :: utils :: H160 , data : :: subxt_core :: alloc :: vec :: Vec < :: core :: primitive :: u8 > , reason : :: subxt_core :: alloc :: vec :: Vec < :: core :: primitive :: u8 > , } , } + #[codec(index = 0)] + #[doc = "An operator has joined."] + OperatorJoined { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 1)] + #[doc = "An operator has scheduled to leave."] + OperatorLeavingScheduled { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 2)] + #[doc = "An operator has cancelled their leave request."] + OperatorLeaveCancelled { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 3)] + #[doc = "An operator has executed their leave request."] + OperatorLeaveExecuted { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 4)] + #[doc = "An operator has increased their stake."] + OperatorBondMore { + who: ::subxt_core::utils::AccountId32, + additional_bond: ::core::primitive::u128, + }, + #[codec(index = 5)] + #[doc = "An operator has scheduled to decrease their stake."] + OperatorBondLessScheduled { + who: ::subxt_core::utils::AccountId32, + unstake_amount: ::core::primitive::u128, + }, + #[codec(index = 6)] + #[doc = "An operator has executed their stake decrease."] + OperatorBondLessExecuted { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 7)] + #[doc = "An operator has cancelled their stake decrease request."] + OperatorBondLessCancelled { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 8)] + #[doc = "An operator has gone offline."] + OperatorWentOffline { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 9)] + #[doc = "An operator has gone online."] + OperatorWentOnline { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 10)] + #[doc = "A deposit has been made."] + Deposited { + who: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + }, + #[codec(index = 11)] + #[doc = "An withdraw has been scheduled."] + Scheduledwithdraw { + who: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + }, + #[codec(index = 12)] + #[doc = "An withdraw has been executed."] + Executedwithdraw { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 13)] + #[doc = "An withdraw has been cancelled."] + Cancelledwithdraw { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 14)] + #[doc = "A delegation has been made."] + Delegated { + who: ::subxt_core::utils::AccountId32, + operator: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + }, + #[codec(index = 15)] + #[doc = "A delegator unstake request has been scheduled."] + ScheduledDelegatorBondLess { + who: ::subxt_core::utils::AccountId32, + operator: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + }, + #[codec(index = 16)] + #[doc = "A delegator unstake request has been executed."] + ExecutedDelegatorBondLess { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 17)] + #[doc = "A delegator unstake request has been cancelled."] + CancelledDelegatorBondLess { who: ::subxt_core::utils::AccountId32 }, + #[codec(index = 18)] + #[doc = "Operator has been slashed"] + OperatorSlashed { + who: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + }, + #[codec(index = 19)] + #[doc = "Delegator has been slashed"] + DelegatorSlashed { + who: ::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + }, + #[codec(index = 20)] + #[doc = "EVM execution reverted with a reason."] + EvmReverted { + from: ::subxt_core::utils::H160, + to: ::subxt_core::utils::H160, + data: ::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + reason: ::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + }, + } } pub mod types { use super::runtime_types; @@ -57899,7 +57470,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BondInfoDelegator < _0 , _1 , _2 , _3 > { pub operator : _0 , pub amount : _1 , pub asset_id : runtime_types :: tangle_primitives :: services :: Asset < _1 > , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < _2 > } @@ -57914,7 +57484,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BondLessRequest < _0 , _1 , _2 , _3 > { pub operator : _0 , pub asset_id : runtime_types :: tangle_primitives :: services :: Asset < _1 > , pub amount : _2 , pub requested_round : :: core :: primitive :: u32 , pub blueprint_selection : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorBlueprintSelection < _3 > , } @@ -57929,7 +57498,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DelegatorBlueprintSelection<_0> { @@ -57954,10 +57522,9 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct DelegatorMetadata < _0 , _1 , _2 , _3 , _4 , _5 , _6 > { pub deposits : :: subxt_core :: utils :: KeyedVec < runtime_types :: tangle_primitives :: services :: Asset < _1 > , _1 > , pub withdraw_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: WithdrawRequest < _1 , _1 > > , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondInfoDelegator < _0 , _1 , _1 , _6 > > , pub delegator_unstake_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondLessRequest < _0 , _1 , _1 , _6 > > , pub status : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorStatus , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _4 , _3 , _5) > } + pub struct DelegatorMetadata < _0 , _1 , _2 , _3 , _4 , _5 , _6 , _7 , _8 > { pub deposits : :: subxt_core :: utils :: KeyedVec < runtime_types :: tangle_primitives :: services :: Asset < _1 > , runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: Deposit < _1 , _7 , _4 > > , pub withdraw_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: WithdrawRequest < _1 , _1 > > , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondInfoDelegator < _0 , _1 , _1 , _6 > > , pub delegator_unstake_requests : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: BondLessRequest < _0 , _1 , _1 , _6 > > , pub status : runtime_types :: pallet_multi_asset_delegation :: types :: delegator :: DelegatorStatus , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _8 , _3 , _5) > } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -57969,7 +57536,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DelegatorStatus { @@ -57989,7 +57555,30 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub struct Deposit<_0, _1, _2> { + pub amount: _0, + pub delegated_amount: _0, + pub locks: ::core::option::Option< + runtime_types::bounded_collections::bounded_vec::BoundedVec< + runtime_types::tangle_primitives::types::rewards::LockInfo<_0, _1>, + >, + >, + #[codec(skip)] + pub __ignore: ::core::marker::PhantomData<_2>, + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WithdrawRequest<_0, _1> { @@ -58011,7 +57600,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct DelegatorBond<_0, _1, _2> { @@ -58032,7 +57620,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OperatorBondLessRequest<_0> { @@ -58050,7 +57637,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OperatorMetadata < _0 , _1 , _2 , _3 , _4 > { pub stake : _1 , pub delegation_count : :: core :: primitive :: u32 , pub request : :: core :: option :: Option < runtime_types :: pallet_multi_asset_delegation :: types :: operator :: OperatorBondLessRequest < _1 > > , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: operator :: DelegatorBond < _0 , _1 , _1 > > , pub status : runtime_types :: pallet_multi_asset_delegation :: types :: operator :: OperatorStatus , pub blueprint_ids : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < :: core :: primitive :: u32 > , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _3 , _4) > } @@ -58065,7 +57651,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OperatorSnapshot < _0 , _1 , _2 , _3 > { pub stake : _1 , pub delegations : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: pallet_multi_asset_delegation :: types :: operator :: DelegatorBond < _0 , _1 , _1 > > , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < (_2 , _3) > } @@ -58080,7 +57665,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum OperatorStatus { @@ -58092,62 +57676,6 @@ pub mod api { Leaving(::core::primitive::u32), } } - pub mod rewards { - use super::runtime_types; - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub enum AssetAction { - #[codec(index = 0)] - Add, - #[codec(index = 1)] - Remove, - } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct RewardConfig < _0 , _1 > { pub configs : :: subxt_core :: utils :: KeyedVec < _0 , runtime_types :: pallet_multi_asset_delegation :: types :: rewards :: RewardConfigForAssetVault < _0 > > , pub whitelisted_blueprint_ids : :: subxt_core :: alloc :: vec :: Vec < :: core :: primitive :: u64 > , # [codec (skip)] pub __ignore : :: core :: marker :: PhantomData < _1 > } - #[derive( - :: subxt_core :: ext :: codec :: Decode, - :: subxt_core :: ext :: codec :: Encode, - :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Clone, - Debug, - Eq, - PartialEq, - )] - # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] - #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] - #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] - pub struct RewardConfigForAssetVault<_0> { - pub apy: runtime_types::sp_arithmetic::per_things::Percent, - pub cap: _0, - } - } } } pub mod pallet_multisig { @@ -58165,7 +57693,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -58325,7 +57852,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -58384,7 +57910,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -58438,7 +57963,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Multisig<_0, _1, _2> { @@ -58458,7 +57982,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Timepoint<_0> { @@ -58481,7 +58004,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -58929,7 +58451,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DefensiveError { @@ -58959,7 +58480,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -59095,7 +58615,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events of this pallet."] @@ -59254,7 +58773,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum FreezeReason { @@ -59273,7 +58791,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum BondExtra<_0> { @@ -59293,7 +58810,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BondedPoolInner { @@ -59316,7 +58832,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ClaimPermission { @@ -59340,7 +58855,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Commission { @@ -59372,7 +58886,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CommissionChangeRate<_0> { @@ -59390,7 +58903,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum CommissionClaimPermission<_0> { @@ -59410,7 +58922,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ConfigOp<_0> { @@ -59432,7 +58943,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PoolMember { @@ -59457,7 +58967,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PoolRoles<_0> { @@ -59477,7 +58986,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum PoolState { @@ -59499,7 +59007,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RewardPool { @@ -59521,7 +59028,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SubPools { @@ -59543,7 +59049,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UnbondPool { @@ -59566,7 +59071,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events type."] @@ -59597,7 +59101,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -59646,7 +59149,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -59690,7 +59192,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -59716,7 +59217,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum HoldReason { @@ -59735,7 +59235,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum OldRequestStatus<_0, _1> { @@ -59759,7 +59258,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RequestStatus<_0, _1> { @@ -59788,7 +59286,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -60009,7 +59506,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -60050,7 +59546,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -60106,7 +59601,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Announcement<_0, _1, _2> { @@ -60125,7 +59619,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ProxyDefinition<_0, _1, _2> { @@ -60134,6 +59627,222 @@ pub mod api { pub delay: _2, } } + pub mod pallet_rewards { + use super::runtime_types; + pub mod pallet { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] + pub enum Call { + #[codec(index = 1)] + #[doc = "Claim rewards for a specific asset and reward type"] + claim_rewards { + asset: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + }, + #[codec(index = 2)] + #[doc = "Manage asset id to vault rewards."] + #[doc = ""] + #[doc = "# Permissions"] + #[doc = ""] + #[doc = "* Must be signed by an authorized account"] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = ""] + #[doc = "* `origin` - Origin of the call"] + #[doc = "* `vault_id` - ID of the vault"] + #[doc = "* `asset_id` - ID of the asset"] + #[doc = "* `action` - Action to perform (Add/Remove)"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = ""] + #[doc = "* [`Error::AssetAlreadyInVault`] - Asset already exists in vault"] + #[doc = "* [`Error::AssetNotInVault`] - Asset does not exist in vault"] + manage_asset_reward_vault { + vault_id: ::core::primitive::u32, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + action: runtime_types::pallet_rewards::types::AssetAction, + }, + #[codec(index = 3)] + #[doc = "Updates the reward configuration for a specific vault."] + #[doc = ""] + #[doc = "# Arguments"] + #[doc = "* `origin` - Origin of the call, must pass `ForceOrigin` check"] + #[doc = "* `vault_id` - The ID of the vault to update"] + #[doc = "* `new_config` - The new reward configuration containing:"] + #[doc = " * `apy` - Annual Percentage Yield for the vault"] + #[doc = " * `deposit_cap` - Maximum amount that can be deposited"] + #[doc = " * `incentive_cap` - Maximum amount of incentives that can be distributed"] + #[doc = " * `boost_multiplier` - Optional multiplier to boost rewards"] + #[doc = ""] + #[doc = "# Events"] + #[doc = "* `VaultRewardConfigUpdated` - Emitted when vault reward config is updated"] + #[doc = ""] + #[doc = "# Errors"] + #[doc = "* `BadOrigin` - If caller is not authorized through `ForceOrigin`"] + update_vault_reward_config { + vault_id: ::core::primitive::u32, + new_config: runtime_types::pallet_rewards::types::RewardConfigForAssetVault< + ::core::primitive::u128, + >, + }, + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "The `Error` enum of this pallet."] + pub enum Error { + #[codec(index = 0)] + #[doc = "No rewards available to claim"] + NoRewardsAvailable, + #[codec(index = 1)] + #[doc = "Insufficient rewards balance in pallet account"] + InsufficientRewardsBalance, + #[codec(index = 2)] + #[doc = "Asset is not whitelisted for rewards"] + AssetNotWhitelisted, + #[codec(index = 3)] + #[doc = "Asset is already whitelisted"] + AssetAlreadyWhitelisted, + #[codec(index = 4)] + #[doc = "Invalid APY value"] + InvalidAPY, + #[codec(index = 5)] + #[doc = "Asset already exists in a reward vault"] + AssetAlreadyInVault, + #[codec(index = 6)] + #[doc = "Asset not found in reward vault"] + AssetNotInVault, + #[codec(index = 7)] + #[doc = "The reward vault does not exist"] + VaultNotFound, + #[codec(index = 8)] + #[doc = "Error returned when trying to add a blueprint ID that already exists."] + DuplicateBlueprintId, + #[codec(index = 9)] + #[doc = "Error returned when trying to remove a blueprint ID that doesn't exist."] + BlueprintIdNotFound, + #[codec(index = 10)] + #[doc = "Error returned when the reward configuration for the vault is not found."] + RewardConfigNotFound, + #[codec(index = 11)] + #[doc = "Arithmetic operation caused an overflow"] + ArithmeticError, + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + #[doc = "The `Event` enum of this pallet"] + pub enum Event { + #[codec(index = 0)] + #[doc = "Rewards have been claimed by an account"] + RewardsClaimed { + account: ::subxt_core::utils::AccountId32, + asset: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + amount: ::core::primitive::u128, + }, + #[codec(index = 1)] + #[doc = "Event emitted when an incentive APY and cap are set for a reward vault"] + IncentiveAPYAndCapSet { + vault_id: ::core::primitive::u32, + apy: runtime_types::sp_arithmetic::per_things::Percent, + cap: ::core::primitive::u128, + }, + #[codec(index = 2)] + #[doc = "Event emitted when a blueprint is whitelisted for rewards"] + BlueprintWhitelisted { blueprint_id: ::core::primitive::u64 }, + #[codec(index = 3)] + #[doc = "Asset has been updated to reward vault"] + AssetUpdatedInVault { + vault_id: ::core::primitive::u32, + asset_id: runtime_types::tangle_primitives::services::Asset< + ::core::primitive::u128, + >, + action: runtime_types::pallet_rewards::types::AssetAction, + }, + #[codec(index = 4)] + VaultRewardConfigUpdated { vault_id: ::core::primitive::u32 }, + } + } + pub mod types { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub enum AssetAction { + #[codec(index = 0)] + Add, + #[codec(index = 1)] + Remove, + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub struct RewardConfigForAssetVault<_0> { + pub apy: runtime_types::sp_arithmetic::per_things::Percent, + pub incentive_cap: _0, + pub deposit_cap: _0, + pub boost_multiplier: ::core::option::Option<::core::primitive::u32>, + } + } + } pub mod pallet_scheduler { use super::runtime_types; pub mod pallet { @@ -60149,7 +59858,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -60268,7 +59976,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -60300,7 +60007,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events type."] @@ -60371,7 +60077,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RetryConfig<_0> { @@ -60390,7 +60095,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Scheduled<_0, _1, _2, _3, _4> { @@ -60418,7 +60122,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -60854,7 +60557,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -61002,7 +60704,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -61164,7 +60865,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UnappliedSlash<_0, _1> { @@ -61192,7 +60892,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -61237,7 +60936,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error for the session pallet."] @@ -61269,7 +60967,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -61298,7 +60995,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -61819,7 +61515,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ConfigOp<_0> { @@ -61841,7 +61536,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -61955,7 +61649,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -62072,7 +61765,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SlashingSpans { @@ -62092,7 +61784,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SpanRecord<_0> { @@ -62111,7 +61802,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ActiveEraInfo { @@ -62129,7 +61819,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EraRewardPoints<_0> { @@ -62147,7 +61836,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Forcing { @@ -62171,7 +61859,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Nominations { @@ -62192,7 +61879,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RewardDestination<_0> { @@ -62218,7 +61904,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct StakingLedger { @@ -62246,7 +61931,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UnappliedSlash<_0, _1> { @@ -62267,7 +61951,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UnlockChunk<_0> { @@ -62287,7 +61970,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ValidatorPrefs { @@ -62311,7 +61993,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -62375,7 +62056,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error for the Sudo pallet."] @@ -62395,7 +62075,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -62439,7 +62118,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -62456,7 +62134,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DefensiveError { @@ -62482,7 +62159,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -62605,7 +62281,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Events of this pallet."] @@ -62622,7 +62297,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum FreezeReason { @@ -62645,7 +62319,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BondedPoolInner { @@ -62669,7 +62342,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PoolMetadata { @@ -62698,7 +62370,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Commission { pub current : :: core :: option :: Option < (runtime_types :: sp_arithmetic :: per_things :: Perbill , :: subxt_core :: utils :: AccountId32 ,) > , pub max : :: core :: option :: Option < runtime_types :: sp_arithmetic :: per_things :: Perbill > , pub change_rate : :: core :: option :: Option < runtime_types :: pallet_tangle_lst :: types :: commission :: CommissionChangeRate < :: core :: primitive :: u64 > > , pub throttle_from : :: core :: option :: Option < :: core :: primitive :: u64 > , pub claim_permission : :: core :: option :: Option < runtime_types :: pallet_tangle_lst :: types :: commission :: CommissionClaimPermission < :: subxt_core :: utils :: AccountId32 > > , } @@ -62713,7 +62384,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CommissionChangeRate<_0> { @@ -62731,7 +62401,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum CommissionClaimPermission<_0> { @@ -62754,7 +62423,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PoolMember { @@ -62775,7 +62443,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PoolRoles<_0> { @@ -62795,7 +62462,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum PoolState { @@ -62820,7 +62486,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RewardPool { @@ -62842,7 +62507,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SubPools { @@ -62864,7 +62528,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct UnbondPool { @@ -62883,7 +62546,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum BondExtra<_0> { @@ -62901,7 +62563,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ClaimPermission { @@ -62925,7 +62586,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ConfigOp<_0> { @@ -62953,7 +62613,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -63000,7 +62659,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -63028,7 +62686,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct FeeDetails<_0> { @@ -63048,7 +62705,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct InclusionFee<_0> { @@ -63067,7 +62723,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RuntimeDispatchInfo<_0, _1> { @@ -63087,7 +62742,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ChargeTransactionPayment(#[codec(compact)] pub ::core::primitive::u128); @@ -63102,7 +62756,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Releases { @@ -63127,7 +62780,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -63291,7 +62943,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error for the treasury pallet."] @@ -63342,7 +62993,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -63415,7 +63065,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum PaymentState<_0> { @@ -63437,7 +63086,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Proposal<_0, _1> { @@ -63457,7 +63105,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SpendStatus<_0, _1, _2, _3, _4> { @@ -63486,7 +63133,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -63533,7 +63179,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -63561,7 +63206,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -63608,7 +63252,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -63735,7 +63378,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Error` enum of this pallet."] @@ -63755,7 +63397,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -63803,7 +63444,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] @@ -63942,7 +63582,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "Error for the vesting pallet."] @@ -63975,7 +63614,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] #[doc = "The `Event` enum of this pallet"] @@ -64005,7 +63643,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct VestingInfo<_0, _1> { @@ -64025,7 +63662,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Releases { @@ -64048,7 +63684,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct U256(pub [::core::primitive::u64; 4usize]); @@ -64066,7 +63701,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TxPoolResponse { @@ -64094,7 +63728,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct FixedU128(pub ::core::primitive::u128); @@ -64113,7 +63746,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PerU16(pub ::core::primitive::u16); @@ -64129,7 +63761,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Perbill(pub ::core::primitive::u32); @@ -64145,7 +63776,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Percent(pub ::core::primitive::u8); @@ -64161,7 +63791,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Permill(pub ::core::primitive::u32); @@ -64177,7 +63806,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ArithmeticError { @@ -64204,7 +63832,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Public(pub [::core::primitive::u8; 32usize]); @@ -64222,7 +63849,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum NextConfigDescriptor { @@ -64243,7 +63869,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum PreDigest { @@ -64267,7 +63892,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PrimaryPreDigest { @@ -64286,7 +63910,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SecondaryPlainPreDigest { @@ -64304,7 +63927,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SecondaryVRFPreDigest { @@ -64324,7 +63946,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum AllowedSlots { @@ -64346,7 +63967,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BabeConfiguration { @@ -64371,7 +63991,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BabeEpochConfiguration { @@ -64389,7 +64008,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Epoch { @@ -64414,7 +64032,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OpaqueKeyOwnershipProof( @@ -64436,7 +64053,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Public(pub [::core::primitive::u8; 32usize]); @@ -64451,7 +64067,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Signature(pub [::core::primitive::u8; 64usize]); @@ -64467,7 +64082,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Equivocation<_0, _1> { @@ -64499,7 +64113,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EquivocationProof<_0, _1> { @@ -64520,7 +64133,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct EquivocationProof<_0, _1> { @@ -64541,7 +64153,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Slot(pub ::core::primitive::u64); @@ -64561,7 +64172,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct KeyTypeId(pub [::core::primitive::u8; 4usize]); @@ -64581,7 +64191,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct VrfSignature { @@ -64601,7 +64210,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OpaqueMetadata(pub ::subxt_core::alloc::vec::Vec<::core::primitive::u8>); @@ -64616,7 +64224,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Void {} @@ -64634,7 +64241,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct CheckInherentsResult { @@ -64653,7 +64259,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct InherentData { @@ -64676,7 +64281,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ElectionScore { @@ -64695,7 +64299,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Support<_0> { @@ -64720,7 +64323,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Block<_0, _1> { @@ -64741,7 +64343,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Digest { @@ -64760,7 +64361,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DigestItem { @@ -64798,7 +64398,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Era { @@ -65329,7 +64928,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Header<_0> { @@ -65355,7 +64953,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BlakeTwo256; @@ -65373,7 +64970,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum InvalidTransaction { @@ -65411,7 +65007,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TransactionSource { @@ -65433,7 +65028,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TransactionValidityError { @@ -65453,7 +65047,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum UnknownTransaction { @@ -65475,7 +65068,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ValidTransaction { @@ -65501,7 +65093,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum DispatchError { @@ -65545,7 +65136,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ExtrinsicInclusionMode { @@ -65565,7 +65155,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ModuleError { @@ -65583,7 +65172,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum MultiSignature { @@ -65605,7 +65193,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OpaqueValue(pub ::subxt_core::alloc::vec::Vec<::core::primitive::u8>); @@ -65620,7 +65207,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TokenError { @@ -65656,7 +65242,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TransactionalError { @@ -65679,7 +65264,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MembershipProof { @@ -65705,7 +65289,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OffenceDetails<_0, _1> { @@ -65724,7 +65307,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Exposure<_0, _1> { @@ -65747,7 +65329,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ExposurePage<_0, _1> { @@ -65768,7 +65349,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct IndividualExposure<_0, _1> { @@ -65787,7 +65367,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PagedExposureMetadata<_0> { @@ -65812,7 +65391,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RuntimeVersion { @@ -65844,7 +65422,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Weight { @@ -65865,7 +65442,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RuntimeDbWeight { @@ -65892,7 +65468,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct BoundedString( @@ -65929,7 +65504,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum FieldType { @@ -66003,7 +65577,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ApprovalState { @@ -66029,7 +65602,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Architecture { @@ -66065,7 +65637,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Asset<_0> { @@ -66087,7 +65658,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum BlueprintServiceManager { @@ -66107,7 +65677,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ContainerGadget { @@ -66128,7 +65697,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Gadget { @@ -66152,7 +65720,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GadgetBinary { @@ -66174,7 +65741,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GadgetSource { @@ -66193,7 +65759,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum GadgetSourceFetcher { @@ -66225,7 +65790,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct GithubFetcher { @@ -66249,7 +65813,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ImageRegistryFetcher { @@ -66268,7 +65831,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct JobCall<_1> { @@ -66289,7 +65851,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct JobCallResult<_1> { @@ -66312,7 +65873,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct JobDefinition { @@ -66337,7 +65897,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct JobMetadata { @@ -66359,7 +65918,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum MasterBlueprintServiceManagerRevision { @@ -66381,7 +65939,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NativeGadget { @@ -66402,7 +65959,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum OperatingSystem { @@ -66428,7 +65984,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OperatorPreferences { @@ -66446,7 +66001,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct OperatorProfile { @@ -66470,7 +66024,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct PriceTargets { @@ -66491,7 +66044,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct RpcServicesWithBlueprint<_1, _2, _3> { @@ -66512,7 +66064,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Service<_1, _2, _3> { @@ -66541,7 +66092,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ServiceBlueprint { pub metadata : runtime_types :: tangle_primitives :: services :: ServiceMetadata , pub jobs : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: tangle_primitives :: services :: JobDefinition > , pub registration_params : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: tangle_primitives :: services :: field :: FieldType > , pub request_params : runtime_types :: bounded_collections :: bounded_vec :: BoundedVec < runtime_types :: tangle_primitives :: services :: field :: FieldType > , pub manager : runtime_types :: tangle_primitives :: services :: BlueprintServiceManager , pub master_manager_revision : runtime_types :: tangle_primitives :: services :: MasterBlueprintServiceManagerRevision , pub gadget : runtime_types :: tangle_primitives :: services :: Gadget , } @@ -66558,7 +66108,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ServiceMetadata { @@ -66596,7 +66145,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct ServiceRequest<_1, _2, _3> { @@ -66626,7 +66174,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct StagingServicePayment<_0, _1, _2> { @@ -66648,7 +66195,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct TestFetcher { @@ -66668,7 +66214,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum TypeCheckError { @@ -66703,7 +66248,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct WasmGadget { @@ -66725,7 +66269,6 @@ pub mod api { serde :: Serialize, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum WasmRuntime { @@ -66737,6 +66280,51 @@ pub mod api { } pub mod types { use super::runtime_types; + pub mod rewards { + use super::runtime_types; + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub struct LockInfo<_0, _1> { + pub amount: _0, + pub lock_multiplier: + runtime_types::tangle_primitives::types::rewards::LockMultiplier, + pub expiry_block: _1, + } + #[derive( + :: subxt_core :: ext :: codec :: Decode, + :: subxt_core :: ext :: codec :: Encode, + :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt_core :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] + pub enum LockMultiplier { + #[codec(index = 1)] + OneMonth, + #[codec(index = 2)] + TwoMonths, + #[codec(index = 3)] + ThreeMonths, + #[codec(index = 6)] + SixMonths, + } + } #[derive( :: subxt_core :: ext :: codec :: Decode, :: subxt_core :: ext :: codec :: Encode, @@ -66748,7 +66336,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum Account<_0> { @@ -66774,7 +66361,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct SessionKeys { @@ -66794,7 +66380,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MaxDelegations; @@ -66809,7 +66394,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MaxDelegatorBlueprints; @@ -66824,7 +66408,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MaxOperatorBlueprints; @@ -66839,7 +66422,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MaxUnstakeRequests; @@ -66854,7 +66436,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct MaxWithdrawRequests; @@ -66869,7 +66450,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct NposSolution16 { @@ -67039,7 +66619,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum OriginCaller { @@ -67069,7 +66648,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum ProxyType { @@ -67093,7 +66671,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub struct Runtime; @@ -67108,7 +66685,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RuntimeCall { @@ -67188,6 +66764,8 @@ pub mod api { Services(runtime_types::pallet_services::module::Call), #[codec(index = 52)] Lst(runtime_types::pallet_tangle_lst::pallet::Call), + #[codec(index = 53)] + Rewards(runtime_types::pallet_rewards::pallet::Call), } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -67200,7 +66778,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RuntimeError { @@ -67274,6 +66851,8 @@ pub mod api { Services(runtime_types::pallet_services::module::Error), #[codec(index = 52)] Lst(runtime_types::pallet_tangle_lst::pallet::Error), + #[codec(index = 53)] + Rewards(runtime_types::pallet_rewards::pallet::Error), } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -67286,7 +66865,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RuntimeEvent { @@ -67362,6 +66940,8 @@ pub mod api { Services(runtime_types::pallet_services::module::Event), #[codec(index = 52)] Lst(runtime_types::pallet_tangle_lst::pallet::Event), + #[codec(index = 53)] + Rewards(runtime_types::pallet_rewards::pallet::Event), } #[derive( :: subxt_core :: ext :: codec :: Decode, @@ -67374,7 +66954,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RuntimeFreezeReason { @@ -67394,7 +66973,6 @@ pub mod api { PartialEq, )] # [codec (crate = :: subxt_core :: ext :: codec)] - #[codec(dumb_trait_bound)] #[decode_as_type(crate_path = ":: subxt_core :: ext :: scale_decode")] #[encode_as_type(crate_path = ":: subxt_core :: ext :: scale_encode")] pub enum RuntimeHoldReason { From 1485e8fa1637412d569bff6901b58c62aa0fcf72 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:41:08 +0530 Subject: [PATCH 63/63] chore: release v1.2.5 --- Cargo.lock | 32 ++++++++++++++++---------------- Cargo.toml | 2 +- runtime/mainnet/src/lib.rs | 2 +- runtime/testnet/src/lib.rs | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85dd22e3..4bec29fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4899,7 +4899,7 @@ dependencies = [ [[package]] name = "frost-ed448" -version = "1.2.4" +version = "1.2.5" dependencies = [ "ed448-goldilocks-plus", "parity-scale-codec", @@ -4926,7 +4926,7 @@ dependencies = [ [[package]] name = "frost-p384" -version = "1.2.4" +version = "1.2.5" dependencies = [ "p384", "parity-scale-codec", @@ -4980,7 +4980,7 @@ dependencies = [ [[package]] name = "frost-secp256k1-tr" -version = "1.2.4" +version = "1.2.5" dependencies = [ "k256", "parity-scale-codec", @@ -8416,7 +8416,7 @@ dependencies = [ [[package]] name = "pallet-airdrop-claims" -version = "1.2.4" +version = "1.2.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -9488,7 +9488,7 @@ dependencies = [ [[package]] name = "pallet-multi-asset-delegation" -version = "1.2.4" +version = "1.2.5" dependencies = [ "ethabi", "ethereum", @@ -9658,7 +9658,7 @@ dependencies = [ [[package]] name = "pallet-rewards" -version = "1.2.4" +version = "1.2.5" dependencies = [ "ethabi", "ethereum", @@ -9733,7 +9733,7 @@ dependencies = [ [[package]] name = "pallet-services" -version = "1.2.4" +version = "1.2.5" dependencies = [ "ethabi", "ethereum", @@ -9790,7 +9790,7 @@ dependencies = [ [[package]] name = "pallet-services-rpc" -version = "1.2.4" +version = "1.2.5" dependencies = [ "jsonrpsee 0.23.2", "pallet-services-rpc-runtime-api", @@ -9803,7 +9803,7 @@ dependencies = [ [[package]] name = "pallet-services-rpc-runtime-api" -version = "1.2.4" +version = "1.2.5" dependencies = [ "parity-scale-codec", "sp-api", @@ -15740,7 +15740,7 @@ dependencies = [ [[package]] name = "tangle" -version = "1.2.4" +version = "1.2.5" dependencies = [ "alloy", "anyhow", @@ -15835,7 +15835,7 @@ dependencies = [ [[package]] name = "tangle-crypto-primitives" -version = "1.2.4" +version = "1.2.5" dependencies = [ "parity-scale-codec", "scale-info", @@ -15844,7 +15844,7 @@ dependencies = [ [[package]] name = "tangle-primitives" -version = "1.2.4" +version = "1.2.5" dependencies = [ "ark-bn254", "ark-crypto-primitives", @@ -15875,7 +15875,7 @@ dependencies = [ [[package]] name = "tangle-runtime" -version = "1.2.4" +version = "1.2.5" dependencies = [ "evm-tracer", "fp-evm", @@ -15989,7 +15989,7 @@ dependencies = [ [[package]] name = "tangle-subxt" -version = "0.8.0" +version = "0.9.0" dependencies = [ "parity-scale-codec", "scale-info", @@ -16001,7 +16001,7 @@ dependencies = [ [[package]] name = "tangle-testnet-runtime" -version = "1.2.4" +version = "1.2.5" dependencies = [ "evm-tracer", "fixed", @@ -16187,7 +16187,7 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "tg-frost-core" -version = "1.2.4" +version = "1.2.5" dependencies = [ "byteorder", "const-crc32-nostd", diff --git a/Cargo.toml b/Cargo.toml index 7f72d001..b61ad255 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "1.2.4" +version = "1.2.5" authors = ["Tangle Foundation."] edition = "2021" license = "Unlicense" diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs index ee398f9b..f8071633 100644 --- a/runtime/mainnet/src/lib.rs +++ b/runtime/mainnet/src/lib.rs @@ -163,7 +163,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("tangle"), impl_name: create_runtime_str!("tangle"), authoring_version: 1, - spec_version: 1204, // v1.2.4 + spec_version: 1205, // v1.2.5 impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 711944af..5316ec60 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -168,7 +168,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("tangle-testnet"), impl_name: create_runtime_str!("tangle-testnet"), authoring_version: 1, - spec_version: 1204, // v1.2.4 + spec_version: 1205, // v1.2.5 impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,