Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Masternode Registry Governed Proxy
- Optimization enabled
- true
- Compiler version
- v0.5.16+commit.9c3226ce
- Optimization runs
- 200
- EVM Version
- petersburg
- Verified at
- 2021-08-20 08:20:35.525158Z
Constructor Arguments
00000000000000000000000000000000000000000000000000000000000003120000000000000000000000000000000000000000000000000000000000000305
Contract source code
// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.pragma solidity 0.5.16;//pragma experimental SMTChecker;/** * Genesis version of GovernedContract interface. * * Base Consensus interface for upgradable contracts. * Unlike common approach, the implementation is NOT expected to be * called through delegatecall() to minimize risks of shared storage. * * NOTE: it MUST NOT change after blockchain launch! */interface IGovernedContract { // Return actual proxy address for secure validation function proxy() external returns(address); // It must check that the caller is the proxy // and copy all required data from the old address. function migrate(IGovernedContract _oldImpl) external; // It must check that the caller is the proxy // and self destruct to the new address. function destroy(IGovernedContract _newImpl) external; function () external payable;}// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;interface IProposal { function parent() external view returns(address); function created_block() external view returns(uint); function deadline() external view returns(uint); function fee_payer() external view returns(address payable); function fee_amount() external view returns(uint); function accepted_weight() external view returns(uint); function rejected_weight() external view returns(uint); function total_weight() external view returns(uint); function quorum_weight() external view returns(uint); function isFinished() external view returns(bool); function isAccepted() external view returns(bool); function withdraw() external; function destroy() external; function collect() external; function voteAccept() external; function voteReject() external; function setFee() external payable; function canVote(address owner) external view returns(bool);}/** * Interface of UpgradeProposal */contract IUpgradeProposal is IProposal { function impl() external view returns(IGovernedContract);}// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;/** * Genesis version of IGovernedProxy interface. * * Base Consensus interface for upgradable contracts proxy. * Unlike common approach, the implementation is NOT expected to be * called through delegatecall() to minimize risks of shared storage. * * NOTE: it MUST NOT change after blockchain launch! */interface IGovernedProxy { event UpgradeProposal( IGovernedContract indexed impl, IUpgradeProposal proposal ); event Upgraded( IGovernedContract indexed impl, IUpgradeProposal proposal ); function impl() external view returns(IGovernedContract); function proposeUpgrade(IGovernedContract _newImpl, uint _period) external payable returns(IUpgradeProposal); function upgrade(IUpgradeProposal _proposal) external; function upgradeProposalImpl(IUpgradeProposal _proposal) external view returns(IGovernedContract new_impl); function listUpgradeProposals() external view returns(IUpgradeProposal[] memory proposals); function collectUpgradeProposal(IUpgradeProposal _proposal) external; function () external payable;}// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;interface ISporkRegistry { function createUpgradeProposal( IGovernedContract _impl, uint _period, address payable _fee_payer ) external payable returns (IUpgradeProposal); function consensusGasLimits() external view returns(uint callGas, uint xferGas);}// Copyright 2019 The Energi Core Authors// This file is part of Energi Core.//// Energi Core 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.//// Energi Core 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 Energi Core. If not, see <http://www.gnu.org/licenses/>.// Energi Governance system is the fundamental part of Energi Core.// NOTE: It's not allowed to change the compiler due to byte-to-byte// match requirement.//pragma experimental SMTChecker;/** * A little helper to protect contract from being re-entrant in state * modifying functions. */contract NonReentrant { uint private entry_guard; modifier noReentry { require(entry_guard == 0, "Reentry"); entry_guard = 1; _; entry_guard = 0; }}/** * SC-9: This contract has no chance of being updated. It must be stupid simple. * * If another upgrade logic is required in the future - it can be done as proxy stage II. */contract GovernedProxy is IGovernedContract, IGovernedProxy, NonReentrant{ modifier senderOrigin { // Internal calls are expected to use impl directly. // That's due to use of call() instead of delegatecall() on purpose. // solium-disable-next-line security/no-tx-origin require(tx.origin == msg.sender, "Only direct calls are allowed!"); _; } IGovernedContract public impl; IGovernedProxy public spork_proxy; mapping(address => IGovernedContract) public upgrade_proposals; IUpgradeProposal[] public upgrade_proposal_list; constructor(IGovernedContract _impl, IGovernedProxy _sporkProxy) public { impl = _impl; spork_proxy = _sporkProxy; } /** * Pre-create a new contract first. * Then propose upgrade based on that. */ function proposeUpgrade(IGovernedContract _newImpl, uint _period) external payable senderOrigin noReentry returns(IUpgradeProposal) { require(_newImpl != impl, "Already active!"); require(_newImpl.proxy() == address(this), "Wrong proxy!"); ISporkRegistry spork_reg = ISporkRegistry(address(spork_proxy.impl())); IUpgradeProposal proposal = spork_reg.createUpgradeProposal.value(msg.value)(_newImpl, _period, msg.sender); upgrade_proposals[address(proposal)] = _newImpl; upgrade_proposal_list.push(proposal); emit UpgradeProposal(_newImpl, proposal); return proposal; } /** * Once proposal is accepted, anyone can activate that. */ function upgrade(IUpgradeProposal _proposal) external noReentry { IGovernedContract new_impl = upgrade_proposals[address(_proposal)]; require(new_impl != impl, "Already active!"); // in case it changes in the flight require(address(new_impl) != address(0), "Not registered!"); require(_proposal.isAccepted(), "Not accepted!"); IGovernedContract old_impl = impl; new_impl.migrate(old_impl); impl = new_impl; old_impl.destroy(new_impl); // SECURITY: prevent downgrade attack _cleanupProposal(_proposal); // Return fee ASAP _proposal.destroy(); emit Upgraded(new_impl, _proposal); } /** * Map proposal to implementation */ function upgradeProposalImpl(IUpgradeProposal _proposal) external view returns(IGovernedContract new_impl) { new_impl = upgrade_proposals[address(_proposal)]; } /** * Lists all available upgrades */ function listUpgradeProposals() external view returns(IUpgradeProposal[] memory proposals) { uint len = upgrade_proposal_list.length; proposals = new IUpgradeProposal[](len); for (uint i = 0; i < len; ++i) { proposals[i] = upgrade_proposal_list[i]; } return proposals; } /** * Once proposal is reject, anyone can start collect procedure. */ function collectUpgradeProposal(IUpgradeProposal _proposal) external noReentry { IGovernedContract new_impl = upgrade_proposals[address(_proposal)]; require(address(new_impl) != address(0), "Not registered!"); _proposal.collect(); delete upgrade_proposals[address(_proposal)]; _cleanupProposal(_proposal); } function _cleanupProposal(IUpgradeProposal _proposal) internal { delete upgrade_proposals[address(_proposal)]; uint len = upgrade_proposal_list.length; for (uint i = 0; i < len; ++i) { if (upgrade_proposal_list[i] == _proposal) { upgrade_proposal_list[i] = upgrade_proposal_list[len - 1]; upgrade_proposal_list.pop(); break; } } } /** * Related to above */ function proxy() external returns (address) { return address(this); } /** * SECURITY: prevent on-behalf-of calls */ function migrate(IGovernedContract) external { revert("Good try"); } /** * SECURITY: prevent on-behalf-of calls */ function destroy(IGovernedContract) external { revert("Good try"); } /** * Proxy all other calls to implementation. */ function () external payable senderOrigin { // SECURITY: senderOrigin() modifier is mandatory IGovernedContract impl_m = impl; // solium-disable-next-line security/no-inline-assembly assembly { let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize) let res := call(sub(gas, 10000), impl_m, callvalue, ptr, calldatasize, 0, 0) // NOTE: returndatasize should allow repeatable calls // what should save one opcode. returndatacopy(ptr, 0, returndatasize) switch res case 0 { revert(ptr, returndatasize) } default { return(ptr, returndatasize) } } }}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"address","name":"_proxy","internalType":"address"},{"type":"address","name":"_token_proxy","internalType":"contractIGovernedProxy"},{"type":"address","name":"_treasury_proxy","internalType":"contractIGovernedProxy"},{"type":"uint256[5]","name":"_config","internalType":"uint256[5]"}]},{"type":"event","name":"Announced","inputs":[{"type":"address","name":"masternode","internalType":"address","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"uint32","name":"ipv4address","internalType":"uint32","indexed":false},{"type":"bytes32[2]","name":"enode","internalType":"bytes32[2]","indexed":false},{"type":"uint256","name":"collateral","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Deactivated","inputs":[{"type":"address","name":"masternode","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Denounced","inputs":[{"type":"address","name":"masternode","internalType":"address","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Invalidation","inputs":[{"type":"address","name":"masternode","internalType":"address","indexed":true},{"type":"address","name":"validator","internalType":"address","indexed":true}],"anonymous":false},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"announce","inputs":[{"type":"address","name":"masternode","internalType":"address"},{"type":"uint32","name":"ipv4address","internalType":"uint32"},{"type":"bytes32[2]","name":"enode","internalType":"bytes32[2]"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"can_heartbeat","internalType":"bool"}],"name":"canHeartbeat","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"can_invalidate","internalType":"bool"}],"name":"canInvalidate","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"cleanup_period","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":"min","internalType":"uint256"},{"type":"uint256","name":"max","internalType":"uint256"}],"name":"collateralLimits","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"active","internalType":"uint256"},{"type":"uint256","name":"total","internalType":"uint256"},{"type":"uint256","name":"active_collateral","internalType":"uint256"},{"type":"uint256","name":"total_collateral","internalType":"uint256"},{"type":"uint256","name":"max_of_all_times","internalType":"uint256"}],"name":"count","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"curr_validation_ends","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"curr_validation_offset","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"current_masternode","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"current_payouts","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"denounce","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"destroy","inputs":[{"type":"address","name":"_newImpl","internalType":"contractIGovernedContract"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":"masternodes","internalType":"address[]"}],"name":"enumerate","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":"masternodes","internalType":"address[]"}],"name":"enumerateActive","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"getReward","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"heartbeat","inputs":[{"type":"uint256","name":"block_number","internalType":"uint256"},{"type":"bytes32","name":"block_hash","internalType":"bytes32"},{"type":"uint256","name":"sw_features","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint32","name":"ipv4address","internalType":"uint32"},{"type":"bytes32[2]","name":"enode","internalType":"bytes32[2]"},{"type":"uint256","name":"collateral","internalType":"uint256"},{"type":"uint256","name":"announced_block","internalType":"uint256"},{"type":"uint256","name":"sw_features","internalType":"uint256"}],"name":"info","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"invalidate","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isActive","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"last_block_number","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"migrate","inputs":[{"type":"address","name":"_oldImpl","internalType":"contractIGovernedContract"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mn_active","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mn_active_collateral","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mn_announced","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mn_announced_collateral","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mn_ever_collateral","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"sw_features","internalType":"uint256"},{"type":"uint256","name":"next_heartbeat","internalType":"uint256"},{"type":"uint256","name":"inactive_since","internalType":"uint256"},{"type":"uint256","name":"validator_index","internalType":"uint256"},{"type":"uint256","name":"invalidations","internalType":"uint256"},{"type":"uint256","name":"seq_payouts","internalType":"uint256"},{"type":"uint256","name":"last_vote_epoch","internalType":"uint256"}],"name":"mn_status","inputs":[{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"onCollateralUpdate","inputs":[{"type":"address","name":"owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"masternode","internalType":"address"},{"type":"uint32","name":"ipv4address","internalType":"uint32"},{"type":"bytes32[2]","name":"enode","internalType":"bytes32[2]"},{"type":"uint256","name":"collateral","internalType":"uint256"},{"type":"uint256","name":"announced_block","internalType":"uint256"},{"type":"uint256","name":"sw_features","internalType":"uint256"}],"name":"ownerInfo","inputs":[{"type":"address","name":"owner","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"payments_per_block","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"require_validation","inputs":[],"constant":true},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"reward","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contractIGovernedProxy"}],"name":"token_proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contractIGovernedProxy"}],"name":"treasury_proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contractStorageMasternodeRegistryV1"}],"name":"v1storage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"target","internalType":"address"}],"name":"validationTarget","inputs":[{"type":"address","name":"masternode","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"validation_periods","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"validator_list","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true}]
Deployed ByteCode
0x36303830363034303532333438303135363130303130353736303030383066643562353036303430353136313064666133383033383036313064666138333339383138313031363034303532363034303831313031353631303033333537363030303830666435623530383035313630323039303931303135313630303138303534363030313630303136306130316230333933383431363630303136303031363061303162303331393931383231363137393039313535363030323830353439333930393231363932313639313930393131373930353536313064383038303631303037613630303033393630303066336665363038303630343035323630303433363130363130306136353736303030333536306530316338303633386162663630373731313631303036343537383036333861626636303737313436313032373235373830363361316230653437363134363130323837353738303633623336343539356531343631303262613537383036336365353439346262313436313031333235373830363364643661383531643134363130333166353738303633656335353638383931343631303333343537363130306136353635623830363266353564396431343631303133323537383036333039303066303130313436313031363735373830363333326533613930353134363130313961353738303633356236646565346331343631303165393537383036333664356236633434313436313032313535373830363336666130396162303134363130323438353735623332333331343631303066613537363034303830353136323436316263643630653531623831353236303230363030343832303135323630316536303234383230313532376634663665366337393230363436393732363536333734323036333631366336633733323036313732363532303631366336633666373736353634323130303030363034343832303135323930353139303831393030333630363430313930666435623630303135343630343035313630303136303031363061303162303339303931313639303336363030303832333736303030383033363833333438363631323731303561303366313364363030303833336538303830313536313031326535373364383366333562336438336664356233343830313536313031336535373630303038306664356235303631303136353630303438303336303336303230383131303135363130313535353736303030383066643562353033353630303136303031363061303162303331363631303334393536356230303562333438303135363130313733353736303030383066643562353036313031363536303034383033363033363032303831313031353631303138613537363030303830666435623530333536303031363030313630613031623033313636313033383135363562333438303135363130316136353736303030383066643562353036313031636436303034383033363033363032303831313031353631303162643537363030303830666435623530333536303031363030313630613031623033313636313036613535363562363034303830353136303031363030313630613031623033393039323136383235323531393038313930303336303230303139306633356236313031636436303034383033363033363034303831313031353631303166663537363030303830666435623530363030313630303136306130316230333831333531363930363032303031333536313036633035363562333438303135363130323231353736303030383066643562353036313031636436303034383033363033363032303831313031353631303233383537363030303830666435623530333536303031363030313630613031623033313636313061313535363562333438303135363130323534353736303030383066643562353036313031636436303034383033363033363032303831313031353631303236623537363030303830666435623530333536313061333335363562333438303135363130323765353736303030383066643562353036313031636436313061356135363562333438303135363130323933353736303030383066643562353036313031363536303034383033363033363032303831313031353631303261613537363030303830666435623530333536303031363030313630613031623033313636313061363935363562333438303135363130326336353736303030383066643562353036313032636636313062393635363562363034303830353136303230383038323532383335313831383330313532383335313931393238333932393038333031393138353831303139313032383038333833363030303562383338313130313536313033306235373831383130313531383338323031353236303230303136313032663335363562353035303530353039303530303139323530353035303630343035313830393130333930663335623334383031353631303332623537363030303830666435623530363130316364363130633330353635623334383031353631303334303537363030303830666435623530363130316364363130633366353635623630343038303531363234363162636436306535316238313532363032303630303438323031353236303038363032343832303135323637343736663666363432303734373237393630633031623630343438323031353239303531393038313930303336303634303139306664356236303030353431353631303363303537363034303830353136323436316263643630653531623831353236303230363030343832303135323630303736303234383230313532363635323635363536653734373237393630633831623630343438323031353239303531393038313930303336303634303139306664356236303031363030303831383135353630303136303031363061303162303338303834313638323532363030333630323035323630343039303931323035343931353439313831313639313136383131343135363130343263353736303430383035313632343631626364363065353162383135323630323036303034383230313532363030663630323438323031353236653431366337323635363136343739323036313633373436393736363532313630383831623630343438323031353239303531393038313930303336303634303139306664356236303031363030313630613031623033383131363631303437393537363034303830353136323436316263643630653531623831353236303230363030343832303135323630306636303234383230313532366534653666373432303732363536373639373337343635373236353634323136303838316236303434383230313532393035313930383139303033363036343031393066643562383136303031363030313630613031623033313636333530353161356563363034303531383136336666666666666666313636306530316238313532363030343031363032303630343035313830383330333831383638303362313538303135363130346232353736303030383066643562353035616661313538303135363130346336353733643630303038303365336436303030666435623530353035303530363034303531336436303230383131303135363130346463353736303030383066643562353035313631303531663537363034303830353136323436316263643630653531623831353236303230363030343832303135323630306436303234383230313532366334653666373432303631363336333635373037343635363432313630393831623630343438323031353239303531393038313930303336303634303139306664356236303031353436303430383035313633636535343934626236306530316238313532363030313630303136306130316230333932383331363630303438323031383139303532393135313931393238343136393136336365353439346262393136303234383038323031393236303030393239303931393038323930303330313831383338373830336231353830313536313035373035373630303038306664356235303561663131353830313536313035383435373364363030303830336533643630303066643562353035303630303138303534363030313630303136306130316230333139313636303031363030313630613031623033383638313136393138323137393039323535363034303830353136326635356439643630653031623831353236303034383130313932393039323532353139313835313639333530363266353564396439323530363032343830383230313932363030303932393039313930383239303033303138313833383738303362313538303135363130356537353736303030383066643562353035616631313538303135363130356662353733643630303038303365336436303030666435623530353035303530363130363038383336313063343335363562383236303031363030313630613031623033313636333833313937656630363034303531383136336666666666666666313636306530316238313532363030343031363030303630343035313830383330333831363030303837383033623135383031353631303634333537363030303830666435623530356166313135383031353631303635373537336436303030383033653364363030306664356235303530363034303830353136303031363030313630613031623033383738313136383235323931353139313836313639333530376635643631316633313836383064303035393862623733356436316261636630633531346336623530653165356164333030343061346466326231323739316337393235303831393030333630323030313930613235303530363030303830353535303536356236303033363032303532363030303930383135323630343039303230353436303031363030313630613031623033313638313536356236303030333233333134363130373136353736303430383035313632343631626364363065353162383135323630323036303034383230313532363031653630323438323031353237663466366536633739323036343639373236353633373432303633363136633663373332303631373236353230363136633663366637373635363432313030303036303434383230313532393035313930383139303033363036343031393066643562363030303534313536313037353535373630343038303531363234363162636436306535316238313532363032303630303438323031353236303037363032343832303135323636353236353635366537343732373936306338316236303434383230313532393035313930383139303033363036343031393066643562363030313630303038313930353535343630303136303031363061303162303338343831313639313136313431353631303761663537363034303830353136323436316263643630653531623831353236303230363030343832303135323630306636303234383230313532366534313663373236353631363437393230363136333734363937363635323136303838316236303434383230313532393035313930383139303033363036343031393066643562333036303031363030313630613031623033313638333630303136303031363061303162303331363633656335353638383936303430353138313633666666666666666631363630653031623831353236303034303136303230363034303531383038333033383136303030383738303362313538303135363130376634353736303030383066643562353035616631313538303135363130383038353733643630303038303365336436303030666435623530353035303530363034303531336436303230383131303135363130383165353736303030383066643562353035313630303136303031363061303162303331363134363130383661353736303430383035313632343631626364363065353162383135323630323036303034383230313532363030633630323438323031353236623537373236663665363732303730373236663738373932313630613031623630343438323031353239303531393038313930303336303634303139306664356236303032353436303430383035313633386162663630373736306530316238313532393035313630303039323630303136303031363061303162303331363931363338616266363037373931363030343830383330313932363032303932393139303832393030333031383138363830336231353830313536313038616635373630303038306664356235303561666131353830313536313038633335373364363030303830336533643630303066643562353035303530353036303430353133643630323038313130313536313038643935373630303038306664356235303531363034303830353136333632383737636364363065303162383135323630303136303031363061303162303338373831313636303034383330313532363032343832303138373930353233333630343438333031353239313531393239333530363030303932393138343136393136333632383737636364393133343931363036343830383330313932363032303932393139303832393030333031383138353838383033623135383031353631303933613537363030303830666435623530356166313135383031353631303934653537336436303030383033653364363030306664356235303530353035303530363034303531336436303230383131303135363130393635353736303030383066643562353035313630303136303031363061303162303338303832313636303030383138313532363030333630323039303831353236303430383038333230383035343935386331363630303136303031363061303162303331393936383731363831313739303931353536303034383035343630303138313031383235353934353237663861333561636662633135666638316133396165376433343466643730396632386538363030623461613863363563366236346266653766653336626431396239303933303138303534393039353136383431373930393435353833353139323833353239323531393339343530393237663831326562323638396565636639346366623535636166346131323365613736633664393365656630376464353461353237336237613439343966376437363339323931383139303033393039313031393061323630303038303535393439333530353035303530353635623630303136303031363061303162303339303831313636303030393038313532363030333630323035323630343039303230353431363930353635623630303438313831353438313130363130613430353766653562363030303931383235323630323039303931323030313534363030313630303136306130316230333136393035303831353635623630303135343630303136303031363061303162303331363831353635623630303035343135363130616138353736303430383035313632343631626364363065353162383135323630323036303034383230313532363030373630323438323031353236363532363536353665373437323739363063383162363034343832303135323930353139303831393030333630363430313930666435623630303136303030393038313535363030313630303136306130316230333830383331363832353236303033363032303532363034303930393132303534313638303631306230633537363034303830353136323436316263643630653531623831353236303230363030343832303135323630306636303234383230313532366534653666373432303732363536373639373337343635373236353634323136303838316236303434383230313532393035313930383139303033363036343031393066643562383136303031363030313630613031623033313636336535323235333831363034303531383136336666666666666666313636306530316238313532363030343031363030303630343035313830383330333831363030303837383033623135383031353631306234373537363030303830666435623530356166313135383031353631306235623537336436303030383033653364363030306664356235303530353036303031363030313630613031623033383331363630303039303831353236303033363032303532363034303930323038303534363030313630303136306130316230333139313639303535353036313062386538323631306334333536356235303530363030303830353535363562363030343534363034303830353138323831353236303230383038343032383230313031393039313532363036303931393038313830313536313062633635373831363032303031363032303832303238303338383333393031393035303562353039313530363030303562383138313130313536313063326235373630303438313831353438313130363130626531353766653562393036303030353236303230363030303230303136303030393035343930363130313030306139303034363030313630303136306130316230333136383338323831353138313130363130633062353766653562363030313630303136306130316230333930393231363630323039323833303239313930393130313930393130313532363030313031363130626363353635623530353039303536356236303032353436303031363030313630613031623033313638313536356233303930353635623630303136303031363061303162303338313136363030303930383135323630303336303230353236303430383132303830353436303031363030313630613031623033313931363930353536303034353439303562383138313130313536313064343635373832363030313630303136306130316230333136363030343832383135343831313036313063386435376665356236303030393138323532363032303930393132303031353436303031363030313630613031623033313631343135363130643365353736303034363030313833303338313534383131303631306362383537666535623630303039313832353236303230393039313230303135343630303438303534363030313630303136306130316230333930393231363931383339303831313036313063646535376665356239303630303035323630323036303030323030313630303036313031303030613831353438313630303136303031363061303162303330323139313639303833363030313630303136306130316230333136303231373930353535303630303438303534383036313064313735376665356236303030383238313532363032303930323038313031363030303139393038313031383035343630303136303031363061303162303331393136393035353031393035353631306434363536356236303031303136313063366535363562353035303530353666656132363536323761376137323331353832303432326630353666663036643865666266323633396538313637653338356664393135643839613638376362333165373030623830393038663436386361323436343733366636633633343330303035313030303332