Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 3,825 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Verify Header An... | 13441005 | 1610 days ago | IN | 0 ETH | 0.01523982 | ||||
| Verify Header An... | 13440975 | 1610 days ago | IN | 0 ETH | 0.01372838 | ||||
| Verify Header An... | 13440975 | 1610 days ago | IN | 0 ETH | 0.01386767 | ||||
| Verify Header An... | 13440883 | 1610 days ago | IN | 0 ETH | 0.01353715 | ||||
| Verify Header An... | 13440880 | 1610 days ago | IN | 0 ETH | 0.00677633 | ||||
| Verify Header An... | 13440867 | 1610 days ago | IN | 0 ETH | 0.01310315 | ||||
| Verify Header An... | 13440867 | 1610 days ago | IN | 0 ETH | 0.01569717 | ||||
| Verify Header An... | 13440593 | 1610 days ago | IN | 0 ETH | 0.01241145 | ||||
| Verify Header An... | 13440538 | 1610 days ago | IN | 0 ETH | 0.01257264 | ||||
| Verify Header An... | 13440497 | 1610 days ago | IN | 0 ETH | 0.01183387 | ||||
| Verify Header An... | 13440484 | 1610 days ago | IN | 0 ETH | 0.01182502 | ||||
| Verify Header An... | 13440448 | 1610 days ago | IN | 0 ETH | 0.01232221 | ||||
| Verify Header An... | 13440333 | 1610 days ago | IN | 0 ETH | 0.01153011 | ||||
| Verify Header An... | 13440310 | 1610 days ago | IN | 0 ETH | 0.0089465 | ||||
| Verify Header An... | 13440277 | 1610 days ago | IN | 0 ETH | 0.0098129 | ||||
| Verify Header An... | 13440265 | 1610 days ago | IN | 0 ETH | 0.01145206 | ||||
| Verify Header An... | 13440242 | 1610 days ago | IN | 0 ETH | 0.01268364 | ||||
| Verify Header An... | 13440238 | 1610 days ago | IN | 0 ETH | 0.01558976 | ||||
| Verify Header An... | 13440219 | 1610 days ago | IN | 0 ETH | 0.01195928 | ||||
| Verify Header An... | 13440195 | 1610 days ago | IN | 0 ETH | 0.0127682 | ||||
| Verify Header An... | 13440174 | 1610 days ago | IN | 0 ETH | 0.010669 | ||||
| Verify Header An... | 13440131 | 1610 days ago | IN | 0 ETH | 0.01166992 | ||||
| Verify Header An... | 13440112 | 1610 days ago | IN | 0 ETH | 0.01313336 | ||||
| Verify Header An... | 13439877 | 1610 days ago | IN | 0 ETH | 0.01187545 | ||||
| Verify Header An... | 13439792 | 1610 days ago | IN | 0 ETH | 0.01441577 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
EthCrossChainManager
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-09-01
*/
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
library Utils {
/* @notice Convert the bytes array to bytes32 type, the bytes array length must be 32
* @param _bs Source bytes array
* @return bytes32
*/
function bytesToBytes32(bytes memory _bs) internal pure returns (bytes32 value) {
require(_bs.length == 32, "bytes length is not 32.");
assembly {
// load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length
value := mload(add(_bs, 0x20))
}
}
/* @notice Convert bytes to uint256
* @param _b Source bytes should have length of 32
* @return uint256
*/
function bytesToUint256(bytes memory _bs) internal pure returns (uint256 value) {
require(_bs.length == 32, "bytes length is not 32.");
assembly {
// load 32 bytes from memory starting from position _bs + 32
value := mload(add(_bs, 0x20))
}
require(value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range");
}
/* @notice Convert uint256 to bytes
* @param _b uint256 that needs to be converted
* @return bytes
*/
function uint256ToBytes(uint256 _value) internal pure returns (bytes memory bs) {
require(_value <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range");
assembly {
// Get a location of some free memory and store it in result as
// Solidity does for memory variables.
bs := mload(0x40)
// Put 0x20 at the first word, the length of bytes for uint256 value
mstore(bs, 0x20)
//In the next word, put value in bytes format to the next 32 bytes
mstore(add(bs, 0x20), _value)
// Update the free-memory pointer by padding our last write location to 32 bytes
mstore(0x40, add(bs, 0x40))
}
}
/* @notice Convert bytes to address
* @param _bs Source bytes: bytes length must be 20
* @return Converted address from source bytes
*/
function bytesToAddress(bytes memory _bs) internal pure returns (address addr)
{
require(_bs.length == 20, "bytes length does not match address");
assembly {
// for _bs, first word store _bs.length, second word store _bs.value
// load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address).
addr := mload(add(_bs, 0x14))
}
}
/* @notice Convert address to bytes
* @param _addr Address need to be converted
* @return Converted bytes from address
*/
function addressToBytes(address _addr) internal pure returns (bytes memory bs){
assembly {
// Get a location of some free memory and store it in result as
// Solidity does for memory variables.
bs := mload(0x40)
// Put 20 (address byte length) at the first word, the length of bytes for uint256 value
mstore(bs, 0x14)
// logical shift left _a by 12 bytes, change _a from right-aligned to left-aligned
mstore(add(bs, 0x20), shl(96, _addr))
// Update the free-memory pointer by padding our last write location to 32 bytes
mstore(0x40, add(bs, 0x40))
}
}
/* @notice Do hash leaf as the multi-chain does
* @param _data Data in bytes format
* @return Hashed value in bytes32 format
*/
function hashLeaf(bytes memory _data) internal pure returns (bytes32 result) {
result = sha256(abi.encodePacked(byte(0x0), _data));
}
/* @notice Do hash children as the multi-chain does
* @param _l Left node
* @param _r Right node
* @return Hashed value in bytes32 format
*/
function hashChildren(bytes32 _l, bytes32 _r) internal pure returns (bytes32 result) {
result = sha256(abi.encodePacked(bytes1(0x01), _l, _r));
}
/* @notice Compare if two bytes are equal, which are in storage and memory, seperately
Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L368
* @param _preBytes The bytes stored in storage
* @param _postBytes The bytes stored in memory
* @return Bool type indicating if they are equal
*/
function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes_slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// fslot can contain both the length and contents of the array
// if slength < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
// slength != 0
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes_slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
/* @notice Slice the _bytes from _start index till the result has length of _length
Refer from https://github.com/summa-tx/bitcoin-spv/blob/master/solidity/contracts/BytesLib.sol#L246
* @param _bytes The original bytes needs to be sliced
* @param _start The index of _bytes for the start of sliced bytes
* @param _length The index of _bytes for the end of sliced bytes
* @return The sliced bytes
*/
function slice(
bytes memory _bytes,
uint _start,
uint _length
)
internal
pure
returns (bytes memory)
{
require(_bytes.length >= (_start + _length));
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
// lengthmod <= _length % 32
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
/* @notice Check if the elements number of _signers within _keepers array is no less than _m
* @param _keepers The array consists of serveral address
* @param _signers Some specific addresses to be looked into
* @param _m The number requirement paramter
* @return True means containment, false meansdo do not contain.
*/
function containMAddresses(address[] memory _keepers, address[] memory _signers, uint _m) internal pure returns (bool){
uint m = 0;
for(uint i = 0; i < _signers.length; i++){
for (uint j = 0; j < _keepers.length; j++) {
if (_signers[i] == _keepers[j]) {
m++;
delete _keepers[j];
}
}
}
return m >= _m;
}
/* @notice TODO
* @param key
* @return
*/
function compressMCPubKey(bytes memory key) internal pure returns (bytes memory newkey) {
require(key.length >= 67, "key lenggh is too short");
newkey = slice(key, 0, 35);
if (uint8(key[66]) % 2 == 0){
newkey[2] = byte(0x02);
} else {
newkey[2] = byte(0x03);
}
return newkey;
}
/**
* @dev Returns true if `account` is a contract.
* Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L18
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* IMPORTANT: It is unsafe to assume that an address for which this
* function returns false is an externally-owned account (EOA) and not a
* contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
}
/**
* @dev Wrappers over encoding and serialization operation into bytes from bassic types in Solidity for PolyNetwork cross chain utility.
*
* Encode basic types in Solidity into bytes easily. It's designed to be used
* for PolyNetwork cross chain application, and the encoding rules on Ethereum chain
* and the decoding rules on other chains should be consistent. Here we
* follow the underlying serialization rule with implementation found here:
* https://github.com/polynetwork/poly/blob/master/common/zero_copy_sink.go
*
* Using this library instead of the unchecked serialization method can help reduce
* the risk of serious bugs and handfule, so it's recommended to use it.
*
* Please note that risk can be minimized, yet not eliminated.
*/
library ZeroCopySink {
/* @notice Convert boolean value into bytes
* @param b The boolean value
* @return Converted bytes array
*/
function WriteBool(bool b) internal pure returns (bytes memory) {
bytes memory buff;
assembly{
buff := mload(0x40)
mstore(buff, 1)
switch iszero(b)
case 1 {
mstore(add(buff, 0x20), shl(248, 0x00))
// mstore8(add(buff, 0x20), 0x00)
}
default {
mstore(add(buff, 0x20), shl(248, 0x01))
// mstore8(add(buff, 0x20), 0x01)
}
mstore(0x40, add(buff, 0x21))
}
return buff;
}
/* @notice Convert byte value into bytes
* @param b The byte value
* @return Converted bytes array
*/
function WriteByte(byte b) internal pure returns (bytes memory) {
return WriteUint8(uint8(b));
}
/* @notice Convert uint8 value into bytes
* @param v The uint8 value
* @return Converted bytes array
*/
function WriteUint8(uint8 v) internal pure returns (bytes memory) {
bytes memory buff;
assembly{
buff := mload(0x40)
mstore(buff, 1)
mstore(add(buff, 0x20), shl(248, v))
// mstore(add(buff, 0x20), byte(0x1f, v))
mstore(0x40, add(buff, 0x21))
}
return buff;
}
/* @notice Convert uint16 value into bytes
* @param v The uint16 value
* @return Converted bytes array
*/
function WriteUint16(uint16 v) internal pure returns (bytes memory) {
bytes memory buff;
assembly{
buff := mload(0x40)
let byteLen := 0x02
mstore(buff, byteLen)
for {
let mindex := 0x00
let vindex := 0x1f
} lt(mindex, byteLen) {
mindex := add(mindex, 0x01)
vindex := sub(vindex, 0x01)
}{
mstore8(add(add(buff, 0x20), mindex), byte(vindex, v))
}
mstore(0x40, add(buff, 0x22))
}
return buff;
}
/* @notice Convert uint32 value into bytes
* @param v The uint32 value
* @return Converted bytes array
*/
function WriteUint32(uint32 v) internal pure returns(bytes memory) {
bytes memory buff;
assembly{
buff := mload(0x40)
let byteLen := 0x04
mstore(buff, byteLen)
for {
let mindex := 0x00
let vindex := 0x1f
} lt(mindex, byteLen) {
mindex := add(mindex, 0x01)
vindex := sub(vindex, 0x01)
}{
mstore8(add(add(buff, 0x20), mindex), byte(vindex, v))
}
mstore(0x40, add(buff, 0x24))
}
return buff;
}
/* @notice Convert uint64 value into bytes
* @param v The uint64 value
* @return Converted bytes array
*/
function WriteUint64(uint64 v) internal pure returns(bytes memory) {
bytes memory buff;
assembly{
buff := mload(0x40)
let byteLen := 0x08
mstore(buff, byteLen)
for {
let mindex := 0x00
let vindex := 0x1f
} lt(mindex, byteLen) {
mindex := add(mindex, 0x01)
vindex := sub(vindex, 0x01)
}{
mstore8(add(add(buff, 0x20), mindex), byte(vindex, v))
}
mstore(0x40, add(buff, 0x28))
}
return buff;
}
/* @notice Convert limited uint256 value into bytes
* @param v The uint256 value
* @return Converted bytes array
*/
function WriteUint255(uint256 v) internal pure returns (bytes memory) {
require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range");
bytes memory buff;
assembly{
buff := mload(0x40)
let byteLen := 0x20
mstore(buff, byteLen)
for {
let mindex := 0x00
let vindex := 0x1f
} lt(mindex, byteLen) {
mindex := add(mindex, 0x01)
vindex := sub(vindex, 0x01)
}{
mstore8(add(add(buff, 0x20), mindex), byte(vindex, v))
}
mstore(0x40, add(buff, 0x40))
}
return buff;
}
/* @notice Encode bytes format data into bytes
* @param data The bytes array data
* @return Encoded bytes array
*/
function WriteVarBytes(bytes memory data) internal pure returns (bytes memory) {
uint64 l = uint64(data.length);
return abi.encodePacked(WriteVarUint(l), data);
}
function WriteVarUint(uint64 v) internal pure returns (bytes memory) {
if (v < 0xFD){
return WriteUint8(uint8(v));
} else if (v <= 0xFFFF) {
return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v)));
} else if (v <= 0xFFFFFFFF) {
return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v)));
} else {
return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v)));
}
}
}
/**
* @dev Wrappers over decoding and deserialization operation from bytes into bassic types in Solidity for PolyNetwork cross chain utility.
*
* Decode into basic types in Solidity from bytes easily. It's designed to be used
* for PolyNetwork cross chain application, and the decoding rules on Ethereum chain
* and the encoding rule on other chains should be consistent, and . Here we
* follow the underlying deserialization rule with implementation found here:
* https://github.com/polynetwork/poly/blob/master/common/zero_copy_source.go
*
* Using this library instead of the unchecked serialization method can help reduce
* the risk of serious bugs and handfule, so it's recommended to use it.
*
* Please note that risk can be minimized, yet not eliminated.
*/
library ZeroCopySource {
/* @notice Read next byte as boolean type starting at offset from buff
* @param buff Source bytes array
* @param offset The position from where we read the boolean value
* @return The the read boolean value and new offset
*/
function NextBool(bytes memory buff, uint256 offset) internal pure returns(bool, uint256) {
require(offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit");
// byte === bytes1
byte v;
assembly{
v := mload(add(add(buff, 0x20), offset))
}
bool value;
if (v == 0x01) {
value = true;
} else if (v == 0x00) {
value = false;
} else {
revert("NextBool value error");
}
return (value, offset + 1);
}
/* @notice Read next byte starting at offset from buff
* @param buff Source bytes array
* @param offset The position from where we read the byte value
* @return The read byte value and new offset
*/
function NextByte(bytes memory buff, uint256 offset) internal pure returns (byte, uint256) {
require(offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum");
byte v;
assembly{
v := mload(add(add(buff, 0x20), offset))
}
return (v, offset + 1);
}
/* @notice Read next byte as uint8 starting at offset from buff
* @param buff Source bytes array
* @param offset The position from where we read the byte value
* @return The read uint8 value and new offset
*/
function NextUint8(bytes memory buff, uint256 offset) internal pure returns (uint8, uint256) {
require(offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum");
uint8 v;
assembly{
let tmpbytes := mload(0x40)
let bvalue := mload(add(add(buff, 0x20), offset))
mstore8(tmpbytes, byte(0, bvalue))
mstore(0x40, add(tmpbytes, 0x01))
v := mload(sub(tmpbytes, 0x1f))
}
return (v, offset + 1);
}
/* @notice Read next two bytes as uint16 type starting from offset
* @param buff Source bytes array
* @param offset The position from where we read the uint16 value
* @return The read uint16 value and updated offset
*/
function NextUint16(bytes memory buff, uint256 offset) internal pure returns (uint16, uint256) {
require(offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum");
uint16 v;
assembly {
let tmpbytes := mload(0x40)
let bvalue := mload(add(add(buff, 0x20), offset))
mstore8(tmpbytes, byte(0x01, bvalue))
mstore8(add(tmpbytes, 0x01), byte(0, bvalue))
mstore(0x40, add(tmpbytes, 0x02))
v := mload(sub(tmpbytes, 0x1e))
}
return (v, offset + 2);
}
/* @notice Read next four bytes as uint32 type starting from offset
* @param buff Source bytes array
* @param offset The position from where we read the uint32 value
* @return The read uint32 value and updated offset
*/
function NextUint32(bytes memory buff, uint256 offset) internal pure returns (uint32, uint256) {
require(offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum");
uint32 v;
assembly {
let tmpbytes := mload(0x40)
let byteLen := 0x04
for {
let tindex := 0x00
let bindex := sub(byteLen, 0x01)
let bvalue := mload(add(add(buff, 0x20), offset))
} lt(tindex, byteLen) {
tindex := add(tindex, 0x01)
bindex := sub(bindex, 0x01)
}{
mstore8(add(tmpbytes, tindex), byte(bindex, bvalue))
}
mstore(0x40, add(tmpbytes, byteLen))
v := mload(sub(tmpbytes, sub(0x20, byteLen)))
}
return (v, offset + 4);
}
/* @notice Read next eight bytes as uint64 type starting from offset
* @param buff Source bytes array
* @param offset The position from where we read the uint64 value
* @return The read uint64 value and updated offset
*/
function NextUint64(bytes memory buff, uint256 offset) internal pure returns (uint64, uint256) {
require(offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum");
uint64 v;
assembly {
let tmpbytes := mload(0x40)
let byteLen := 0x08
for {
let tindex := 0x00
let bindex := sub(byteLen, 0x01)
let bvalue := mload(add(add(buff, 0x20), offset))
} lt(tindex, byteLen) {
tindex := add(tindex, 0x01)
bindex := sub(bindex, 0x01)
}{
mstore8(add(tmpbytes, tindex), byte(bindex, bvalue))
}
mstore(0x40, add(tmpbytes, byteLen))
v := mload(sub(tmpbytes, sub(0x20, byteLen)))
}
return (v, offset + 8);
}
/* @notice Read next 32 bytes as uint256 type starting from offset,
there are limits considering the numerical limits in multi-chain
* @param buff Source bytes array
* @param offset The position from where we read the uint256 value
* @return The read uint256 value and updated offset
*/
function NextUint255(bytes memory buff, uint256 offset) internal pure returns (uint256, uint256) {
require(offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum");
uint256 v;
assembly {
let tmpbytes := mload(0x40)
let byteLen := 0x20
for {
let tindex := 0x00
let bindex := sub(byteLen, 0x01)
let bvalue := mload(add(add(buff, 0x20), offset))
} lt(tindex, byteLen) {
tindex := add(tindex, 0x01)
bindex := sub(bindex, 0x01)
}{
mstore8(add(tmpbytes, tindex), byte(bindex, bvalue))
}
mstore(0x40, add(tmpbytes, byteLen))
v := mload(tmpbytes)
}
require(v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range");
return (v, offset + 32);
}
/* @notice Read next variable bytes starting from offset,
the decoding rule coming from multi-chain
* @param buff Source bytes array
* @param offset The position from where we read the bytes value
* @return The read variable bytes array value and updated offset
*/
function NextVarBytes(bytes memory buff, uint256 offset) internal pure returns(bytes memory, uint256) {
uint len;
(len, offset) = NextVarUint(buff, offset);
require(offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum");
bytes memory tempBytes;
assembly{
switch iszero(len)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(len, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, len)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, len)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
mstore(0x40, add(tempBytes, 0x20))
}
}
return (tempBytes, offset + len);
}
/* @notice Read next 32 bytes starting from offset,
* @param buff Source bytes array
* @param offset The position from where we read the bytes value
* @return The read bytes32 value and updated offset
*/
function NextHash(bytes memory buff, uint256 offset) internal pure returns (bytes32 , uint256) {
require(offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum");
bytes32 v;
assembly {
v := mload(add(buff, add(offset, 0x20)))
}
return (v, offset + 32);
}
/* @notice Read next 20 bytes starting from offset,
* @param buff Source bytes array
* @param offset The position from where we read the bytes value
* @return The read bytes20 value and updated offset
*/
function NextBytes20(bytes memory buff, uint256 offset) internal pure returns (bytes20 , uint256) {
require(offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum");
bytes20 v;
assembly {
v := mload(add(buff, add(offset, 0x20)))
}
return (v, offset + 20);
}
function NextVarUint(bytes memory buff, uint256 offset) internal pure returns(uint, uint256) {
byte v;
(v, offset) = NextByte(buff, offset);
uint value;
if (v == 0xFD) {
// return NextUint16(buff, offset);
(value, offset) = NextUint16(buff, offset);
require(value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range");
return (value, offset);
} else if (v == 0xFE) {
// return NextUint32(buff, offset);
(value, offset) = NextUint32(buff, offset);
require(value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range");
return (value, offset);
} else if (v == 0xFF) {
// return NextUint64(buff, offset);
(value, offset) = NextUint64(buff, offset);
require(value > 0xFFFFFFFF, "NextVarUint, value outside range");
return (value, offset);
} else{
// return (uint8(v), offset);
value = uint8(v);
require(value < 0xFD, "NextVarUint, value outside range");
return (value, offset);
}
}
}
library ECCUtils {
using SafeMath for uint256;
struct Header {
uint32 version;
uint64 chainId;
uint32 timestamp;
uint32 height;
uint64 consensusData;
bytes32 prevBlockHash;
bytes32 transactionsRoot;
bytes32 crossStatesRoot;
bytes32 blockRoot;
bytes consensusPayload;
bytes20 nextBookkeeper;
}
struct ToMerkleValue {
bytes txHash; // cross chain txhash
uint64 fromChainID;
TxParam makeTxParam;
}
struct TxParam {
bytes txHash; // source chain txhash
bytes crossChainId;
bytes fromContract;
uint64 toChainId;
bytes toContract;
bytes method;
bytes args;
}
uint constant POLYCHAIN_PUBKEY_LEN = 67;
uint constant POLYCHAIN_SIGNATURE_LEN = 65;
/* @notice Verify Poly chain transaction whether exist or not
* @param _auditPath Poly chain merkle proof
* @param _root Poly chain root
* @return The verified value included in _auditPath
*/
function merkleProve(bytes memory _auditPath, bytes32 _root) internal pure returns (bytes memory) {
uint256 off = 0;
bytes memory value;
(value, off) = ZeroCopySource.NextVarBytes(_auditPath, off);
bytes32 hash = Utils.hashLeaf(value);
uint size = _auditPath.length.sub(off).div(33);
bytes32 nodeHash;
byte pos;
for (uint i = 0; i < size; i++) {
(pos, off) = ZeroCopySource.NextByte(_auditPath, off);
(nodeHash, off) = ZeroCopySource.NextHash(_auditPath, off);
if (pos == 0x00) {
hash = Utils.hashChildren(nodeHash, hash);
} else if (pos == 0x01) {
hash = Utils.hashChildren(hash, nodeHash);
} else {
revert("merkleProve, NextByte for position info failed");
}
}
require(hash == _root, "merkleProve, expect root is not equal actual root");
return value;
}
/* @notice calculate next book keeper according to public key list
* @param _keyLen consensus node number
* @param _m minimum signature number
* @param _pubKeyList consensus node public key list
* @return two element: next book keeper, consensus node signer addresses
*/
function _getBookKeeper(uint _keyLen, uint _m, bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory){
bytes memory buff;
buff = ZeroCopySink.WriteUint16(uint16(_keyLen));
address[] memory keepers = new address[](_keyLen);
bytes32 hash;
bytes memory publicKey;
for(uint i = 0; i < _keyLen; i++){
publicKey = Utils.slice(_pubKeyList, i*POLYCHAIN_PUBKEY_LEN, POLYCHAIN_PUBKEY_LEN);
buff = abi.encodePacked(buff, ZeroCopySink.WriteVarBytes(Utils.compressMCPubKey(publicKey)));
hash = keccak256(Utils.slice(publicKey, 3, 64));
keepers[i] = address(uint160(uint256(hash)));
}
buff = abi.encodePacked(buff, ZeroCopySink.WriteUint16(uint16(_m)));
bytes20 nextBookKeeper = ripemd160(abi.encodePacked(sha256(buff)));
return (nextBookKeeper, keepers);
}
/* @notice Verify public key derived from Poly chain
* @param _pubKeyList serialized consensus node public key list
* @param _sigList consensus node signature list
* @return return two element: next book keeper, consensus node signer addresses
*/
function verifyPubkey(bytes memory _pubKeyList) internal pure returns (bytes20, address[] memory) {
require(_pubKeyList.length % POLYCHAIN_PUBKEY_LEN == 0, "_pubKeyList length illegal!");
uint n = _pubKeyList.length / POLYCHAIN_PUBKEY_LEN;
require(n >= 1, "too short _pubKeyList!");
return _getBookKeeper(n, n - (n - 1) / 3, _pubKeyList);
}
/* @notice Verify Poly chain consensus node signature
* @param _rawHeader Poly chain block header raw bytes
* @param _sigList consensus node signature list
* @param _keepers addresses corresponding with Poly chain book keepers' public keys
* @param _m minimum signature number
* @return true or false
*/
function verifySig(bytes memory _rawHeader, bytes memory _sigList, address[] memory _keepers, uint _m) internal pure returns (bool){
bytes32 hash = getHeaderHash(_rawHeader);
uint sigCount = _sigList.length.div(POLYCHAIN_SIGNATURE_LEN);
address[] memory signers = new address[](sigCount);
bytes32 r;
bytes32 s;
uint8 v;
for(uint j = 0; j < sigCount; j++){
r = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN, 32));
s = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN + 32, 32));
v = uint8(_sigList[j*POLYCHAIN_SIGNATURE_LEN + 64]) + 27;
signers[j] = ecrecover(sha256(abi.encodePacked(hash)), v, r, s);
}
return Utils.containMAddresses(_keepers, signers, _m);
}
/* @notice Serialize Poly chain book keepers' info in Ethereum addresses format into raw bytes
* @param keepersBytes The serialized addresses
* @return serialized bytes result
*/
function serializeKeepers(address[] memory keepers) internal pure returns (bytes memory) {
uint256 keeperLen = keepers.length;
bytes memory keepersBytes = ZeroCopySink.WriteUint64(uint64(keeperLen));
for(uint i = 0; i < keeperLen; i++) {
keepersBytes = abi.encodePacked(keepersBytes, ZeroCopySink.WriteVarBytes(Utils.addressToBytes(keepers[i])));
}
return keepersBytes;
}
/* @notice Deserialize bytes into Ethereum addresses
* @param keepersBytes The serialized addresses derived from Poly chain book keepers in bytes format
* @return addresses
*/
function deserializeKeepers(bytes memory keepersBytes) internal pure returns (address[] memory) {
uint256 off = 0;
uint64 keeperLen;
(keeperLen, off) = ZeroCopySource.NextUint64(keepersBytes, off);
address[] memory keepers = new address[](keeperLen);
bytes memory keeperBytes;
for(uint i = 0; i < keeperLen; i++) {
(keeperBytes, off) = ZeroCopySource.NextVarBytes(keepersBytes, off);
keepers[i] = Utils.bytesToAddress(keeperBytes);
}
return keepers;
}
/* @notice Deserialize Poly chain transaction raw value
* @param _valueBs Poly chain transaction raw bytes
* @return ToMerkleValue struct
*/
function deserializeMerkleValue(bytes memory _valueBs) internal pure returns (ToMerkleValue memory) {
ToMerkleValue memory toMerkleValue;
uint256 off = 0;
(toMerkleValue.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(toMerkleValue.fromChainID, off) = ZeroCopySource.NextUint64(_valueBs, off);
TxParam memory txParam;
(txParam.txHash, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(txParam.crossChainId, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(txParam.fromContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(txParam.toChainId, off) = ZeroCopySource.NextUint64(_valueBs, off);
(txParam.toContract, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(txParam.method, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
(txParam.args, off) = ZeroCopySource.NextVarBytes(_valueBs, off);
toMerkleValue.makeTxParam = txParam;
return toMerkleValue;
}
/* @notice Deserialize Poly chain block header raw bytes
* @param _valueBs Poly chain block header raw bytes
* @return Header struct
*/
function deserializeHeader(bytes memory _headerBs) internal pure returns (Header memory) {
Header memory header;
uint256 off = 0;
(header.version, off) = ZeroCopySource.NextUint32(_headerBs, off);
(header.chainId, off) = ZeroCopySource.NextUint64(_headerBs, off);
(header.prevBlockHash, off) = ZeroCopySource.NextHash(_headerBs, off);
(header.transactionsRoot, off) = ZeroCopySource.NextHash(_headerBs, off);
(header.crossStatesRoot, off) = ZeroCopySource.NextHash(_headerBs, off);
(header.blockRoot, off) = ZeroCopySource.NextHash(_headerBs, off);
(header.timestamp, off) = ZeroCopySource.NextUint32(_headerBs, off);
(header.height, off) = ZeroCopySource.NextUint32(_headerBs, off);
(header.consensusData, off) = ZeroCopySource.NextUint64(_headerBs, off);
(header.consensusPayload, off) = ZeroCopySource.NextVarBytes(_headerBs, off);
(header.nextBookkeeper, off) = ZeroCopySource.NextBytes20(_headerBs, off);
return header;
}
/* @notice Deserialize Poly chain block header raw bytes
* @param rawHeader Poly chain block header raw bytes
* @return header hash same as Poly chain
*/
function getHeaderHash(bytes memory rawHeader) internal pure returns (bytes32) {
return sha256(abi.encodePacked(sha256(rawHeader)));
}
}
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b != 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
/**
* @dev Interface of the EthCrossChainData contract, the implementation is in EthCrossChainData.sol
*/
interface IEthCrossChainData {
function putCurEpochStartHeight(uint32 curEpochStartHeight) external returns (bool);
function getCurEpochStartHeight() external view returns (uint32);
function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool);
function getCurEpochConPubKeyBytes() external view returns (bytes memory);
function markFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external returns (bool);
function checkIfFromChainTxExist(uint64 fromChainId, bytes32 fromChainTx) external view returns (bool);
function getEthTxHashIndex() external view returns (uint256);
function putEthTxHash(bytes32 ethTxHash) external returns (bool);
function putExtraData(bytes32 key1, bytes32 key2, bytes calldata value) external returns (bool);
function getExtraData(bytes32 key1, bytes32 key2) external view returns (bytes memory);
function transferOwnership(address newOwner) external;
function pause() external returns (bool);
function unpause() external returns (bool);
function paused() external view returns (bool);
// Not used currently by ECCM
function getEthTxHash(uint256 ethTxHashIndex) external view returns (bytes32);
}
pragma solidity ^0.5.0;
/**
* @dev Interface of the EthCrossChainManager contract for business contract like LockProxy to request cross chain transaction
*/
interface IEthCrossChainManager {
function crossChain(uint64 _toChainId, bytes calldata _toContract, bytes calldata _method, bytes calldata _txData) external returns (bool);
}
pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
* Refer from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by a pauser (`account`).
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by a pauser (`account`).
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor () internal {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!_paused, "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(_paused, "Pausable: not paused");
_;
}
/**
* @dev Called to pause, triggers stopped state.
*/
function _pause() internal whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Called to unpause, returns to normal state.
*/
function _unpause() internal whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
pragma solidity ^0.5.0;
/**
* @dev Interface of upgradableECCM to make ECCM be upgradable, the implementation is in UpgradableECCM.sol
*/
interface IUpgradableECCM {
function pause() external returns (bool);
function unpause() external returns (bool);
function paused() external view returns (bool);
function upgradeToNew(address) external returns (bool);
function isOwner() external view returns (bool);
function setChainId(uint64 _newChainId) external returns (bool);
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract UpgradableECCM is IUpgradableECCM, Ownable, Pausable {
address public EthCrossChainDataAddress;
uint64 public chainId;
constructor (address ethCrossChainDataAddr, uint64 _chainId) Pausable() Ownable() public {
EthCrossChainDataAddress = ethCrossChainDataAddr;
chainId = _chainId;
}
function pause() onlyOwner public returns (bool) {
if (!paused()) {
_pause();
}
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
if (!eccd.paused()) {
require(eccd.pause(), "pause EthCrossChainData contract failed");
}
return true;
}
function unpause() onlyOwner public returns (bool) {
if (paused()) {
_unpause();
}
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
if (eccd.paused()) {
require(eccd.unpause(), "unpause EthCrossChainData contract failed");
}
return true;
}
// if we want to upgrade this contract, we need to invoke this method
function upgradeToNew(address newEthCrossChainManagerAddress) whenPaused onlyOwner public returns (bool) {
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
eccd.transferOwnership(newEthCrossChainManagerAddress);
return true;
}
function setChainId(uint64 _newChainId) whenPaused onlyOwner public returns (bool) {
chainId = _newChainId;
return true;
}
}
contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM {
using SafeMath for uint256;
mapping(address => bool) public whiteListFromContract;
mapping(address => bool) public whiteListToContract;
mapping(bytes => bool) public whiteListMethod;
mapping(bytes => bool) public unsetEpochPkBytes;
event InitGenesisBlockEvent(uint256 height, bytes rawHeader);
event ChangeBookKeeperEvent(uint256 height, bytes rawHeader);
event CrossChainEvent(address indexed sender, bytes txId, address proxyOrAssetContract, uint64 toChainId, bytes toContract, bytes rawdata);
event VerifyHeaderAndExecuteTxEvent(uint64 fromChainID, bytes toContract, bytes crossChainTxHash, bytes fromChainTxHash);
constructor(
address _eccd,
uint64 _chainId,
address[] memory fromContractWhiteList,
address[] memory toContractWhiteList,
bytes[] memory methodWhiteList,
bytes memory curEpochPkBytes
) UpgradableECCM(_eccd,_chainId) public {
for (uint i=0;i<fromContractWhiteList.length;i++) {
whiteListFromContract[fromContractWhiteList[i]] = true;
}
for (uint i=0;i<toContractWhiteList.length;i++) {
whiteListToContract[toContractWhiteList[i]] = true;
}
for (uint i=0;i<methodWhiteList.length;i++) {
whiteListMethod[methodWhiteList[i]] = true;
}
unsetEpochPkBytes[curEpochPkBytes] = true;
}
function recoverEpochPk(bytes memory EpochPkBytes) public {
require(unsetEpochPkBytes[EpochPkBytes],"Don't arbitrarily set");
unsetEpochPkBytes[EpochPkBytes] = false;
IEthCrossChainData(EthCrossChainDataAddress).putCurEpochConPubKeyBytes(EpochPkBytes);
}
/* @notice sync Poly chain genesis block header to smart contrat
* @dev this function can only be called once, nextbookkeeper of rawHeader can't be empty
* @param rawHeader Poly chain genesis block raw header or raw Header including switching consensus peers info
* @return true or false
*/
function initGenesisBlock(bytes memory rawHeader, bytes memory pubKeyList) whenNotPaused public returns(bool) {
// Load Ethereum cross chain data contract
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
// Make sure the contract has not been initialized before
require(eccd.getCurEpochConPubKeyBytes().length == 0, "EthCrossChainData contract has already been initialized!");
// Parse header and convit the public keys into nextBookKeeper and compare it with header.nextBookKeeper to verify the validity of signature
ECCUtils.Header memory header = ECCUtils.deserializeHeader(rawHeader);
(bytes20 nextBookKeeper, address[] memory keepers) = ECCUtils.verifyPubkey(pubKeyList);
require(header.nextBookkeeper == nextBookKeeper, "NextBookers illegal");
// Record current epoch start height and public keys (by storing them in address format)
require(eccd.putCurEpochStartHeight(header.height), "Save Poly chain current epoch start height to Data contract failed!");
require(eccd.putCurEpochConPubKeyBytes(ECCUtils.serializeKeepers(keepers)), "Save Poly chain current epoch book keepers to Data contract failed!");
// Fire the event
emit InitGenesisBlockEvent(header.height, rawHeader);
return true;
}
/* @notice change Poly chain consensus book keeper
* @param rawHeader Poly chain change book keeper block raw header
* @param pubKeyList Poly chain consensus nodes public key list
* @param sigList Poly chain consensus nodes signature list
* @return true or false
*/
function changeBookKeeper(bytes memory rawHeader, bytes memory pubKeyList, bytes memory sigList) whenNotPaused public returns(bool) {
// Load Ethereum cross chain data contract
ECCUtils.Header memory header = ECCUtils.deserializeHeader(rawHeader);
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
// Make sure rawHeader.height is higher than recorded current epoch start height
uint64 curEpochStartHeight = eccd.getCurEpochStartHeight();
require(header.height > curEpochStartHeight, "The height of header is lower than current epoch start height!");
// Ensure the rawHeader is the key header including info of switching consensus peers by containing non-empty nextBookKeeper field
require(header.nextBookkeeper != bytes20(0), "The nextBookKeeper of header is empty");
// Verify signature of rawHeader comes from pubKeyList
address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes());
uint n = polyChainBKs.length;
require(ECCUtils.verifySig(rawHeader, sigList, polyChainBKs, n - (n - 1) / 3), "Verify signature failed!");
// Convert pubKeyList into ethereum address format and make sure the compound address from the converted ethereum addresses
// equals passed in header.nextBooker
(bytes20 nextBookKeeper, address[] memory keepers) = ECCUtils.verifyPubkey(pubKeyList);
require(header.nextBookkeeper == nextBookKeeper, "NextBookers illegal");
// update current epoch start height of Poly chain and current epoch consensus peers book keepers addresses
require(eccd.putCurEpochStartHeight(header.height), "Save MC LatestHeight to Data contract failed!");
require(eccd.putCurEpochConPubKeyBytes(ECCUtils.serializeKeepers(keepers)), "Save Poly chain book keepers bytes to Data contract failed!");
// Fire the change book keeper event
emit ChangeBookKeeperEvent(header.height, rawHeader);
return true;
}
/* @notice ERC20 token cross chain to other blockchain.
* this function push tx event to blockchain
* @param toChainId Target chain id
* @param toContract Target smart contract address in target block chain
* @param txData Transaction data for target chain, include to_address, amount
* @return true or false
*/
function crossChain(uint64 toChainId, bytes calldata toContract, bytes calldata method, bytes calldata txData) whenNotPaused external returns (bool) {
// Only allow whitelist contract to call
require(whiteListFromContract[msg.sender],"Invalid from contract");
// Load Ethereum cross chain data contract
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
// To help differentiate two txs, the ethTxHashIndex is increasing automatically
uint256 txHashIndex = eccd.getEthTxHashIndex();
// Convert the uint256 into bytes
bytes memory paramTxHash = Utils.uint256ToBytes(txHashIndex);
// Construct the makeTxParam, and put the hash info storage, to help provide proof of tx existence
bytes memory rawParam = abi.encodePacked(ZeroCopySink.WriteVarBytes(paramTxHash),
ZeroCopySink.WriteVarBytes(abi.encodePacked(sha256(abi.encodePacked(address(this), paramTxHash)))),
ZeroCopySink.WriteVarBytes(Utils.addressToBytes(msg.sender)),
ZeroCopySink.WriteUint64(toChainId),
ZeroCopySink.WriteVarBytes(toContract),
ZeroCopySink.WriteVarBytes(method),
ZeroCopySink.WriteVarBytes(txData)
);
// Must save it in the storage to be included in the proof to be verified.
require(eccd.putEthTxHash(keccak256(rawParam)), "Save ethTxHash by index to Data contract failed!");
// Fire the cross chain event denoting there is a cross chain request from Ethereum network to other public chains through Poly chain network
emit CrossChainEvent(tx.origin, paramTxHash, msg.sender, toChainId, toContract, rawParam);
return true;
}
/* @notice Verify Poly chain header and proof, execute the cross chain tx from Poly chain to Ethereum
* @param proof Poly chain tx merkle proof
* @param rawHeader The header containing crossStateRoot to verify the above tx merkle proof
* @param headerProof The header merkle proof used to verify rawHeader
* @param curRawHeader Any header in current epoch consensus of Poly chain
* @param headerSig The coverted signature veriable for solidity derived from Poly chain consensus nodes' signature
* used to verify the validity of curRawHeader
* @return true or false
*/
function verifyHeaderAndExecuteTx(bytes memory proof, bytes memory rawHeader, bytes memory headerProof, bytes memory curRawHeader,bytes memory headerSig) whenNotPaused public returns (bool){
ECCUtils.Header memory header = ECCUtils.deserializeHeader(rawHeader);
// Load ehereum cross chain data contract
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);
// Get stored consensus public key bytes of current poly chain epoch and deserialize Poly chain consensus public key bytes to address[]
address[] memory polyChainBKs = ECCUtils.deserializeKeepers(eccd.getCurEpochConPubKeyBytes());
uint256 curEpochStartHeight = eccd.getCurEpochStartHeight();
uint n = polyChainBKs.length;
if (header.height >= curEpochStartHeight) {
// It's enough to verify rawHeader signature
require(ECCUtils.verifySig(rawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain header signature failed!");
} else {
// We need to verify the signature of curHeader
require(ECCUtils.verifySig(curRawHeader, headerSig, polyChainBKs, n - ( n - 1) / 3), "Verify poly chain current epoch header signature failed!");
// Then use curHeader.StateRoot and headerProof to verify rawHeader.CrossStateRoot
ECCUtils.Header memory curHeader = ECCUtils.deserializeHeader(curRawHeader);
bytes memory proveValue = ECCUtils.merkleProve(headerProof, curHeader.blockRoot);
require(ECCUtils.getHeaderHash(rawHeader) == Utils.bytesToBytes32(proveValue), "verify header proof failed!");
}
// Through rawHeader.CrossStatesRoot, the toMerkleValue or cross chain msg can be verified and parsed from proof
bytes memory toMerkleValueBs = ECCUtils.merkleProve(proof, header.crossStatesRoot);
// Parse the toMerkleValue struct and make sure the tx has not been processed, then mark this tx as processed
ECCUtils.ToMerkleValue memory toMerkleValue = ECCUtils.deserializeMerkleValue(toMerkleValueBs);
require(!eccd.checkIfFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "the transaction has been executed!");
require(eccd.markFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "Save crosschain tx exist failed!");
// Ethereum ChainId is 2, we need to check the transaction is for Ethereum network
require(toMerkleValue.makeTxParam.toChainId == chainId, "This Tx is not aiming at this network!");
// Obtain the targeting contract, so that Ethereum cross chain manager contract can trigger the executation of cross chain tx on Ethereum side
address toContract = Utils.bytesToAddress(toMerkleValue.makeTxParam.toContract);
// only invoke PreWhiteListed Contract and method For Now
require(whiteListToContract[toContract],"Invalid to contract");
require(whiteListMethod[toMerkleValue.makeTxParam.method],"Invalid method");
//TODO: check this part to make sure we commit the next line when doing local net UT test
require(_executeCrossChainTx(toContract, toMerkleValue.makeTxParam.method, toMerkleValue.makeTxParam.args, toMerkleValue.makeTxParam.fromContract, toMerkleValue.fromChainID), "Execute CrossChain Tx failed!");
// Fire the cross chain event denoting the executation of cross chain tx is successful,
// and this tx is coming from other public chains to current Ethereum network
emit VerifyHeaderAndExecuteTxEvent(toMerkleValue.fromChainID, toMerkleValue.makeTxParam.toContract, toMerkleValue.txHash, toMerkleValue.makeTxParam.txHash);
return true;
}
/* @notice Dynamically invoke the targeting contract, and trigger executation of cross chain tx on Ethereum side
* @param _toContract The targeting contract that will be invoked by the Ethereum Cross Chain Manager contract
* @param _method At which method will be invoked within the targeting contract
* @param _args The parameter that will be passed into the targeting contract
* @param _fromContractAddr From chain smart contract address
* @param _fromChainId Indicate from which chain current cross chain tx comes
* @return true or false
*/
function _executeCrossChainTx(address _toContract, bytes memory _method, bytes memory _args, bytes memory _fromContractAddr, uint64 _fromChainId) internal returns (bool){
// Ensure the targeting contract gonna be invoked is indeed a contract rather than a normal account address
require(Utils.isContract(_toContract), "The passed in address is not a contract!");
bytes memory returnData;
bool success;
// The returnData will be bytes32, the last byte must be 01;
(success, returnData) = _toContract.call(abi.encodePacked(bytes4(keccak256(abi.encodePacked(_method, "(bytes,bytes,uint64)"))), abi.encode(_args, _fromContractAddr, _fromChainId)));
// Ensure the executation is successful
require(success == true, "EthCrossChain call business contract failed");
// Ensure the returned value is true
require(returnData.length != 0, "No return value from business contract!");
(bool res,) = ZeroCopySource.NextBool(returnData, 31);
require(res == true, "EthCrossChain call business contract return is not true");
return true;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_eccd","type":"address"},{"internalType":"uint64","name":"_chainId","type":"uint64"},{"internalType":"address[]","name":"fromContractWhiteList","type":"address[]"},{"internalType":"address[]","name":"toContractWhiteList","type":"address[]"},{"internalType":"bytes[]","name":"methodWhiteList","type":"bytes[]"},{"internalType":"bytes","name":"curEpochPkBytes","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"height","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"rawHeader","type":"bytes"}],"name":"ChangeBookKeeperEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"txId","type":"bytes"},{"indexed":false,"internalType":"address","name":"proxyOrAssetContract","type":"address"},{"indexed":false,"internalType":"uint64","name":"toChainId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"toContract","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"rawdata","type":"bytes"}],"name":"CrossChainEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"height","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"rawHeader","type":"bytes"}],"name":"InitGenesisBlockEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"fromChainID","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"toContract","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"crossChainTxHash","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"fromChainTxHash","type":"bytes"}],"name":"VerifyHeaderAndExecuteTxEvent","type":"event"},{"constant":true,"inputs":[],"name":"EthCrossChainDataAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"chainId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"rawHeader","type":"bytes"},{"internalType":"bytes","name":"pubKeyList","type":"bytes"},{"internalType":"bytes","name":"sigList","type":"bytes"}],"name":"changeBookKeeper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"toChainId","type":"uint64"},{"internalType":"bytes","name":"toContract","type":"bytes"},{"internalType":"bytes","name":"method","type":"bytes"},{"internalType":"bytes","name":"txData","type":"bytes"}],"name":"crossChain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"rawHeader","type":"bytes"},{"internalType":"bytes","name":"pubKeyList","type":"bytes"}],"name":"initGenesisBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"EpochPkBytes","type":"bytes"}],"name":"recoverEpochPk","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_newChainId","type":"uint64"}],"name":"setChainId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"unsetEpochPkBytes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newEthCrossChainManagerAddress","type":"address"}],"name":"upgradeToNew","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"bytes","name":"rawHeader","type":"bytes"},{"internalType":"bytes","name":"headerProof","type":"bytes"},{"internalType":"bytes","name":"curRawHeader","type":"bytes"},{"internalType":"bytes","name":"headerSig","type":"bytes"}],"name":"verifyHeaderAndExecuteTx","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListFromContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"whiteListMethod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListToContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162004fa738038062004fa78339810160408190526200003491620003a7565b858560006200004b6001600160e01b036200023f16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506000805460ff60a01b19168155600180546001600160401b03909316600160a01b02600160a01b600160e01b03196001600160a01b039095166001600160a01b03199094169390931793909316919091179091555b845181101562000142576001600260008784815181106200010757fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101620000ea565b5060005b83518110156200019e576001600360008684815181106200016357fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905560010162000146565b5060005b8251811015620001fd5760016004848381518110620001bd57fe5b6020026020010151604051620001d49190620004d0565b908152604051908190036020019020805491151560ff19909216919091179055600101620001a2565b506001600582604051620002129190620004d0565b908152604051908190036020019020805491151560ff1990921691909117905550620005d4945050505050565b3390565b80516200025081620005af565b92915050565b600082601f8301126200026857600080fd5b81516200027f62000279826200050c565b620004e5565b91508181835260208401935060208101905083856020840282011115620002a557600080fd5b60005b83811015620002d55781620002be888262000243565b8452506020928301929190910190600101620002a8565b5050505092915050565b600082601f830112620002f157600080fd5b81516200030262000279826200050c565b81815260209384019390925082018360005b83811015620002d557815186016200032d888262000344565b845250602092830192919091019060010162000314565b600082601f8301126200035657600080fd5b81516200036762000279826200052d565b915080825260208301602083018583830111156200038457600080fd5b620003918382846200057c565b50505092915050565b80516200025081620005c9565b60008060008060008060c08789031215620003c157600080fd5b6000620003cf898962000243565b9650506020620003e289828a016200039a565b95505060408701516001600160401b03811115620003ff57600080fd5b6200040d89828a0162000256565b94505060608701516001600160401b038111156200042a57600080fd5b6200043889828a0162000256565b93505060808701516001600160401b038111156200045557600080fd5b6200046389828a01620002df565b92505060a08701516001600160401b038111156200048057600080fd5b6200048e89828a0162000344565b9150509295509295509295565b6000620004a88262000555565b620004b4818562000559565b9350620004c68185602086016200057c565b9290920192915050565b6000620004de82846200049b565b9392505050565b6040518181016001600160401b03811182821017156200050457600080fd5b604052919050565b60006001600160401b038211156200052357600080fd5b5060209081020190565b60006001600160401b038211156200054457600080fd5b506020601f91909101601f19160190565b5190565b919050565b60006001600160a01b03821662000250565b6001600160401b031690565b60005b83811015620005995781810151838201526020016200057f565b83811115620005a9576000848401525b50505050565b620005ba816200055e565b8114620005c657600080fd5b50565b620005ba8162000570565b6149c380620005e46000396000f3fe608060405234801561001057600080fd5b506004361061012b5760003560e01c80637e724ff3116100ad5780639a8a0592116100715780639a8a059214610225578063b91ca1061461023a578063bd5cf6251461024d578063d450e04c14610260578063f2fde38b146102735761012b565b80637e724ff3146101e75780638456cb59146101fa5780638c5aea41146102025780638da5cb5b146102155780638f32d59b1461021d5761012b565b80636f31031d116100f45780636f31031d14610191578063715018a6146101a457806373f53ba4146101ae5780637b935854146101c15780637bcf7dc1146101d45761012b565b8062ba16941461013057806329dcf4ab1461014e57806334a773eb1461016e5780633f4ba83a146101815780635c975abb14610189575b600080fd5b610138610286565b6040516101459190614346565b60405180910390f35b61016161015c366004613138565b610295565b6040516101459190614362565b61016161017c3660046130d1565b610663565b610161610916565b610161610a6b565b61016161019f3660046132ce565b610a7b565b6101ac610af5565b005b6101616101bc36600461300f565b610b63565b6101616101cf366004613069565b610b78565b6101ac6101e2366004613069565b610b98565b6101616101f536600461300f565b610c8b565b610161610d46565b610161610210366004613069565b610e91565b610138610eb1565b610161610ec0565b61022d610ee4565b60405161014591906147a6565b61016161024836600461300f565b610efa565b61016161025b3660046132ec565b610f0f565b61016161026e3660046131c9565b611298565b6101ac61028136600461300f565b611770565b6001546001600160a01b031681565b60008054600160a01b900460ff16156102c95760405162461bcd60e51b81526004016102c090614548565b60405180910390fd5b6102d1612e38565b6102da856117a0565b90506000600160009054906101000a90046001600160a01b031690506000816001600160a01b0316635ac407906040518163ffffffff1660e01b815260040160206040518083038186803b15801561033157600080fd5b505afa158015610345573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061036991908101906132b0565b63ffffffff169050806001600160401b0316836060015163ffffffff16116103a35760405162461bcd60e51b81526004016102c090614588565b6101408301516bffffffffffffffffffffffff19166103d45760405162461bcd60e51b81526004016102c090614498565b6060610453836001600160a01b03166369d480746040518163ffffffff1660e01b815260040160006040518083038186803b15801561041257600080fd5b505afa158015610426573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261044e919081019061309d565b6118bf565b805190915061046e898884600360001986015b048503611972565b61048a5760405162461bcd60e51b81526004016102c090614528565b600060606104978a611b2f565b91509150816001600160601b0319168761014001516001600160601b031916146104d35760405162461bcd60e51b81526004016102c090614568565b6060870151604051638a8bd17f60e01b81526001600160a01b03881691638a8bd17f916105039190600401614778565b602060405180830381600087803b15801561051d57600080fd5b505af1158015610531573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610555919081019061302d565b6105715760405162461bcd60e51b81526004016102c090614638565b856001600160a01b03166341973cd961058983611bab565b6040518263ffffffff1660e01b81526004016105a591906143b3565b602060405180830381600087803b1580156105bf57600080fd5b505af11580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105f7919081019061302d565b6106135760405162461bcd60e51b81526004016102c0906145a8565b7fe60d33488cba3977bf65766cd2f8ac9617f64bf3b3198aff6240ce5c7d43b69087606001518c604051610648929190614786565b60405180910390a160019750505050505050505b9392505050565b60008054600160a01b900460ff161561068e5760405162461bcd60e51b81526004016102c090614548565b60015460408051631a75201d60e21b815290516001600160a01b039092169182916369d48074916004808301926000929190829003018186803b1580156106d457600080fd5b505afa1580156106e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610710919081019061309d565b511561072e5760405162461bcd60e51b81526004016102c0906146c8565b610736612e38565b61073f856117a0565b90506000606061074e86611b2f565b91509150816001600160601b0319168361014001516001600160601b0319161461078a5760405162461bcd60e51b81526004016102c090614568565b6060830151604051638a8bd17f60e01b81526001600160a01b03861691638a8bd17f916107ba9190600401614778565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061080c919081019061302d565b6108285760405162461bcd60e51b81526004016102c0906144f8565b836001600160a01b03166341973cd961084083611bab565b6040518263ffffffff1660e01b815260040161085c91906143b3565b602060405180830381600087803b15801561087657600080fd5b505af115801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108ae919081019061302d565b6108ca5760405162461bcd60e51b81526004016102c0906146e8565b7ff01968fc3a2655cf1b5144cb32de6dc898f91b9239c103744e8457152ab2fbde8360600151886040516108ff929190614786565b60405180910390a160019450505050505b92915050565b6000610920610ec0565b61093c5760405162461bcd60e51b81526004016102c0906145d8565b610944610a6b565b1561095157610951611c1a565b60015460408051635c975abb60e01b815290516001600160a01b03909216918291635c975abb916004808301926020929190829003018186803b15801561099757600080fd5b505afa1580156109ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109cf919081019061302d565b15610a6357806001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610a0f57600080fd5b505af1158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a47919081019061302d565b610a635760405162461bcd60e51b81526004016102c0906144a8565b600191505090565b600054600160a01b900460ff1690565b60008054600160a01b900460ff16610aa55760405162461bcd60e51b81526004016102c090614458565b610aad610ec0565b610ac95760405162461bcd60e51b81526004016102c0906145d8565b506001805467ffffffffffffffff60a01b1916600160a01b6001600160401b038416021781555b919050565b610afd610ec0565b610b195760405162461bcd60e51b81526004016102c0906145d8565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60026020526000908152604090205460ff1681565b805160208183018101805160048252928201919093012091525460ff1681565b600581604051610ba891906142aa565b9081526040519081900360200190205460ff16610bd75760405162461bcd60e51b81526004016102c0906145c8565b6000600582604051610be991906142aa565b908152604051908190036020018120805492151560ff19909316929092179091556001546341973cd960e01b82526001600160a01b0316906341973cd990610c359084906004016143b3565b602060405180830381600087803b158015610c4f57600080fd5b505af1158015610c63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c87919081019061302d565b5050565b60008054600160a01b900460ff16610cb55760405162461bcd60e51b81526004016102c090614458565b610cbd610ec0565b610cd95760405162461bcd60e51b81526004016102c0906145d8565b60015460405163f2fde38b60e01b81526001600160a01b0390911690819063f2fde38b90610d0b908690600401614346565b600060405180830381600087803b158015610d2557600080fd5b505af1158015610d39573d6000803e3d6000fd5b5060019695505050505050565b6000610d50610ec0565b610d6c5760405162461bcd60e51b81526004016102c0906145d8565b610d74610a6b565b610d8057610d80611c90565b60015460408051635c975abb60e01b815290516001600160a01b03909216918291635c975abb916004808301926020929190829003018186803b158015610dc657600080fd5b505afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dfe919081019061302d565b610a6357806001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e3d57600080fd5b505af1158015610e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e75919081019061302d565b610a635760405162461bcd60e51b81526004016102c090614478565b805160208183018101805160058252928201919093012091525460ff1681565b6000546001600160a01b031690565b600080546001600160a01b0316610ed5611cf2565b6001600160a01b031614905090565b600154600160a01b90046001600160401b031681565b60036020526000908152604090205460ff1681565b60008054600160a01b900460ff1615610f3a5760405162461bcd60e51b81526004016102c090614548565b3360009081526002602052604090205460ff16610f695760405162461bcd60e51b81526004016102c090614538565b60015460408051600162c2db5f60e01b0319815290516001600160a01b0390921691600091839163ff3d24a191600480820192602092909190829003018186803b158015610fb657600080fd5b505afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fee919081019061304b565b90506060610ffb82611cf6565b9050606061100882611d3a565b61109e6002308560405160200161102092919061420a565b60408051601f198184030181529082905261103a916142aa565b602060405180830381855afa158015611057573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061107a919081019061304b565b60405160200161108a9190614279565b604051602081830303815290604052611d3a565b6110af6110aa33611d71565b611d3a565b6110b88f611d8c565b6110f78f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b6111368e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b6111758d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b60405160200161118b97969594939291906142ce565b60408051601f19818403018152908290528051602082012063130f33d960e21b83529092506001600160a01b03861691634c3ccf64916111cd91600401614370565b602060405180830381600087803b1580156111e757600080fd5b505af11580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061121f919081019061302d565b61123b5760405162461bcd60e51b81526004016102c090614738565b326001600160a01b03167f6ad3bf15c1988bc04bc153490cab16db8efb9a3990215bf1c64ea6e28be8848383338f8f8f8760405161127e969594939291906143c4565b60405180910390a25060019b9a5050505050505050505050565b60008054600160a01b900460ff16156112c35760405162461bcd60e51b81526004016102c090614548565b6112cb612e38565b6112d4866117a0565b90506000600160009054906101000a90046001600160a01b03169050606061132e826001600160a01b03166369d480746040518163ffffffff1660e01b815260040160006040518083038186803b15801561041257600080fd5b90506000826001600160a01b0316635ac407906040518163ffffffff1660e01b815260040160206040518083038186803b15801561136b57600080fd5b505afa15801561137f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113a391908101906132b0565b63ffffffff16905060008251905081856060015163ffffffff16106113f5576113d48a888560036000198601610466565b6113f05760405162461bcd60e51b81526004016102c090614768565b61147b565b61140788888560036000198601610466565b6114235760405162461bcd60e51b81526004016102c090614658565b61142b612e38565b611434896117a0565b905060606114478b836101000151611dcf565b905061145281611ece565b61145b8d611ef9565b146114785760405162461bcd60e51b81526004016102c0906144c8565b50505b606061148b8c8760e00151611dcf565b9050611495612e93565b61149e82611fb6565b9050856001600160a01b0316630586763c82602001516114c18460000151611ece565b6040518363ffffffff1660e01b81526004016114de9291906147b4565b60206040518083038186803b1580156114f657600080fd5b505afa15801561150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061152e919081019061302d565b1561154b5760405162461bcd60e51b81526004016102c090614728565b856001600160a01b031663e90bfdcf826020015161156c8460000151611ece565b6040518363ffffffff1660e01b81526004016115899291906147b4565b602060405180830381600087803b1580156115a357600080fd5b505af11580156115b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115db919081019061302d565b6115f75760405162461bcd60e51b81526004016102c0906144e8565b6001546040820151606001516001600160401b03908116600160a01b90920416146116345760405162461bcd60e51b81526004016102c090614508565b6000611647826040015160800151612092565b6001600160a01b03811660009081526003602052604090205490915060ff166116825760405162461bcd60e51b81526004016102c090614578565b6004826040015160a0015160405161169a91906142aa565b9081526040519081900360200190205460ff166116c95760405162461bcd60e51b81526004016102c090614678565b6116f281836040015160a00151846040015160c0015185604001516040015186602001516120bd565b61170e5760405162461bcd60e51b81526004016102c090614468565b602082015160408084015160808101518551915192517f8a4a2663ce60ce4955c595da2894de0415240f1ace024cfbff85f513b656bdae94611752949093916147cf565b60405180910390a16001985050505050505050505b95945050505050565b611778610ec0565b6117945760405162461bcd60e51b81526004016102c0906145d8565b61179d8161222e565b50565b6117a8612e38565b6117b0612e38565b60006117bc84826122af565b63ffffffff909116835290506117d28482612338565b6001600160401b03909116602084015290506117ee84826123bf565b60a0840191909152905061180284826123bf565b60c0840191909152905061181684826123bf565b60e0840191909152905061182a84826123bf565b610100840191909152905061183f84826122af565b63ffffffff9091166040840152905061185884826122af565b63ffffffff909116606084015290506118718482612338565b6001600160401b039091166080840152905061188d8482612404565b61012084019190915290506118a284826124b8565b506bffffffffffffffffffffffff19166101408301525092915050565b60606000806118ce8482612338565b80935081925050506060816001600160401b031660405190808252806020026020018201604052801561190b578160200160208202803883390190505b509050606060005b836001600160401b03168110156119675761192e8786612404565b9550915061193b82612092565b83828151811061194757fe5b6001600160a01b0390921660209283029190910190910152600101611913565b509095945050505050565b60008061197e86611ef9565b905060006119976041875161250190919063ffffffff16565b90506060816040519080825280602002602001820160405280156119c5578160200160208202803883390190505b50905060008080805b85811015611b12576119ed6119e88c604184026020612543565b611ece565b9350611a046119e88c604184026020016020612543565b92508a6041820260400181518110611a1857fe5b602001015160f81c60f81b60f81c601b0191506001600288604051602001611a409190614279565b60408051601f1981840301815290829052611a5a916142aa565b602060405180830381855afa158015611a77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611a9a919081019061304b565b83868660405160008152602001604052604051611aba949392919061437e565b6020604051602081039080840390855afa158015611adc573d6000803e3d6000fd5b50505060206040510351858281518110611af257fe5b6001600160a01b03909216602092830291909101909101526001016119ce565b50611b1e89858a6125c3565b96505050505050505b949350505050565b600060606043835181611b3e57fe5b0615611b5c5760405162461bcd60e51b81526004016102c090614618565b60006043845181611b6957fe5b0490506001811015611b8d5760405162461bcd60e51b81526004016102c090614698565b611ba1816003600019820104830386612664565b9250925050915091565b805160609081611bba82611d8c565b905060005b82811015611c125781611be76110aa878481518110611bda57fe5b6020026020010151611d71565b604051602001611bf89291906142b6565b60408051601f198184030181529190529150600101611bbf565b509392505050565b600054600160a01b900460ff16611c435760405162461bcd60e51b81526004016102c090614458565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611c79611cf2565b604051611c869190614354565b60405180910390a1565b600054600160a01b900460ff1615611cba5760405162461bcd60e51b81526004016102c090614548565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c795b3390565b60606001600160ff1b03821115611d1f5760405162461bcd60e51b81526004016102c0906145b8565b60405190506020815281602082015260408101604052919050565b8051606090611d4881612819565b83604051602001611d5a9291906142b6565b604051602081830303815290604052915050919050565b604080516014815260609290921b6020830152818101905290565b6040516008808252606091906000601f5b82821015611dbf5785811a826020860101536001919091019060001901611d9d565b5050506028810160405292915050565b6060600081611dde8583612404565b925090506000611ded826128d0565b90506000611e166021611e0a868a516128eb90919063ffffffff16565b9063ffffffff61250116565b9050600080805b83811015611ea157611e2f8a8861292d565b97509150611e3d8a886123bf565b975092506001600160f81b03198216611e6157611e5a8386612976565b9450611e99565b600160f81b6001600160f81b031983161415611e8157611e5a8584612976565b60405162461bcd60e51b81526004016102c0906145f8565b600101611e1d565b50878414611ec15760405162461bcd60e51b81526004016102c090614558565b5092979650505050505050565b60008151602014611ef15760405162461bcd60e51b81526004016102c090614688565b506020015190565b600060028083604051611f0c91906142aa565b602060405180830381855afa158015611f29573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f4c919081019061304b565b604051602001611f5c9190614279565b60408051601f1981840301815290829052611f76916142aa565b602060405180830381855afa158015611f93573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250610910919081019061304b565b611fbe612e93565b611fc6612e93565b6000611fd28482612404565b9083529050611fe18482612338565b6001600160401b0390911660208401529050611ffb612eb7565b6120058583612404565b90825291506120148583612404565b602083019190915291506120288583612404565b6040830191909152915061203c8583612338565b6001600160401b03909116606083015291506120588583612404565b6080830191909152915061206c8583612404565b60a083019190915291506120808583612404565b5060c082015260408301525092915050565b600081516014146120b55760405162461bcd60e51b81526004016102c0906144b8565b506014015190565b60006120c8866129ed565b6120e45760405162461bcd60e51b81526004016102c090614628565b60606000876001600160a01b031687604051602001612103919061432f565b6040516020818303038152906040528051906020012087878760405160200161212e93929190614424565b60408051601f198184030181529082905261214c929160200161428e565b60408051601f1981840301815290829052612166916142aa565b6000604051808303816000865af19150503d80600081146121a3576040519150601f19603f3d011682016040523d82523d6000602084013e6121a8565b606091505b50925090506001811515146121cf5760405162461bcd60e51b81526004016102c090614598565b81516121ed5760405162461bcd60e51b81526004016102c090614668565b60006121fa83601f612a24565b50905060018115151461221f5760405162461bcd60e51b81526004016102c0906146a8565b50600198975050505050505050565b6001600160a01b0381166122545760405162461bcd60e51b81526004016102c0906144d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080835183600401111580156122c857508260040183105b6122e45760405162461bcd60e51b81526004016102c090614748565b600060405160046000600182038760208a0101515b838310156123195780821a838601536001830192506001820391506122f9565b50505080820160405260200390035192505050600482015b9250929050565b6000808351836008011115801561235157508260080183105b61236d5760405162461bcd60e51b81526004016102c090614708565b600060405160086000600182038760208a0101515b838310156123a25780821a83860153600183019250600182039150612382565b505050808201604052602003900351956008949094019450505050565b600080835183602001111580156123d857508260200183105b6123f45760405162461bcd60e51b81526004016102c0906146f8565b5050602091810182015192910190565b60606000806124138585612abd565b86519095509091508185011180159061242d575080840184105b6124495760405162461bcd60e51b81526004016102c090614758565b606081158015612464576040519150602082016040526124ae565b6040519150601f8316801560200281840101848101888315602002848c0101015b8183101561249d578051835260209283019201612485565b5050848452601f01601f1916604052505b5095930193505050565b600080835183601401111580156124d157508260140183105b6124ed5760405162461bcd60e51b81526004016102c090614518565b505081810160200151601482019250929050565b600061065c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612c02565b60608183018451101561255557600080fd5b606082158015612570576040519150602082016040526125ba565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125a9578051835260209283019201612591565b5050858452601f01601f1916604052505b50949350505050565b600080805b84518110156126585760005b865181101561264f578681815181106125e957fe5b60200260200101516001600160a01b031686838151811061260657fe5b60200260200101516001600160a01b0316141561264757828060010193505086818151811061263157fe5b6020026020010160006001600160a01b03168152505b6001016125d4565b506001016125c8565b50909111159392505050565b600060608061267286612c39565b90506060866040519080825280602002602001820160405280156126a0578160200160208202803883390190505b50905060006060815b89811015612737576126c088604383026043612543565b9150846126cf6110aa84612c7c565b6040516020016126e09291906142b6565b60405160208183030381529060405294506126fe8260036040612543565b8051906020012092508260001c84828151811061271757fe5b6001600160a01b03909216602092830291909101909101526001016126a9565b508361274289612c39565b6040516020016127539291906142b6565b60405160208183030381529060405293506000600360028660405161277891906142aa565b602060405180830381855afa158015612795573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506127b8919081019061304b565b6040516020016127c89190614279565b60408051601f19818403018152908290526127e2916142aa565b602060405180830381855afa1580156127ff573d6000803e3d6000fd5b50506040515160601b9b949a509398505050505050505050565b606060fd826001600160401b0316101561283d5761283682612d35565b9050610af0565b61ffff826001600160401b03161161288c5761285c60fd60f81b612d51565b61286583612c39565b6040516020016128769291906142b6565b6040516020818303038152906040529050610af0565b63ffffffff826001600160401b0316116128b6576128ad607f60f91b612d51565b61286583612d5f565b6128c76001600160f81b0319612d51565b61286583611d8c565b60006002600060f81b83604051602001611f5c92919061425d565b600061065c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612da2565b6000808351836001011115801561294657508260010183105b6129625760405162461bcd60e51b81526004016102c090614608565b505081810160200151600182019250929050565b60006002600160f81b848460405160200161299393929190614226565b60408051601f19818403018152908290526129ad916142aa565b602060405180830381855afa1580156129ca573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061065c919081019061304b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590611b275750141592915050565b60008083518360010111158015612a3d57508260010183105b612a595760405162461bcd60e51b81526004016102c0906146d8565b838301602001516000600160f81b6001600160f81b031983161415612a8057506001612aaf565b6001600160f81b03198216612a9757506000612aaf565b60405162461bcd60e51b81526004016102c0906145e8565b956001949094019450505050565b6000806000612acc858561292d565b94509050600060fd60f81b6001600160f81b031983161415612b3557612af28686612dce565b955061ffff16905060fd8110801590612b0d575061ffff8111155b612b295760405162461bcd60e51b81526004016102c090614488565b92508391506123319050565b607f60f91b6001600160f81b031983161415612b9057612b5586866122af565b955063ffffffff16905061ffff81118015612b74575063ffffffff8111155b612b295760405162461bcd60e51b81526004016102c090614648565b6001600160f81b03198083161415612bdc57612bac8686612338565b95506001600160401b0316905063ffffffff8111612b295760405162461bcd60e51b81526004016102c090614648565b5060f881901c60fd8110612b295760405162461bcd60e51b81526004016102c090614648565b60008183612c235760405162461bcd60e51b81526004016102c091906143b3565b506000838581612c2f57fe5b0495945050505050565b6040516002808252606091906000601f5b82821015612c6c5785811a826020860101536001919091019060001901612c4a565b5050506022810160405292915050565b6060604382511015612ca05760405162461bcd60e51b81526004016102c090614718565b612cad8260006023612543565b9050600282604281518110612cbe57fe5b016020015160f81c81612ccd57fe5b0660ff1660001415612d0757600260f81b81600281518110612ceb57fe5b60200101906001600160f81b031916908160001a905350610af0565b600360f81b81600281518110612d1957fe5b60200101906001600160f81b031916908160001a905350919050565b604080516001815260f89290921b602083015260218201905290565b60606109108260f81c612d35565b6040516004808252606091906000601f5b82821015612d925785811a826020860101536001919091019060001901612d70565b5050506024810160405292915050565b60008184841115612dc65760405162461bcd60e51b81526004016102c091906143b3565b505050900390565b60008083518360020111158015612de757508260020183105b612e035760405162461bcd60e51b81526004016102c0906146b8565b6000604051846020870101518060011a82538060001a6001830153506002818101604052601d19909101519694019450505050565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082015261014081019190915290565b6040805160608082018352815260006020820152908101612eb2612eb7565b905290565b6040518060e0016040528060608152602001606081526020016060815260200160006001600160401b031681526020016060815260200160608152602001606081525090565b803561091081614948565b80516109108161495c565b805161091081614965565b60008083601f840112612f3057600080fd5b5081356001600160401b03811115612f4757600080fd5b60208301915083600182028301111561233157600080fd5b600082601f830112612f7057600080fd5b8135612f83612f7e82614847565b614821565b91508082526020830160208301858383011115612f9f57600080fd5b612faa8382846148eb565b50505092915050565b600082601f830112612fc457600080fd5b8151612fd2612f7e82614847565b91508082526020830160208301858383011115612fee57600080fd5b612faa8382846148f7565b80516109108161496e565b803561091081614977565b60006020828403121561302157600080fd5b6000611b278484612efd565b60006020828403121561303f57600080fd5b6000611b278484612f08565b60006020828403121561305d57600080fd5b6000611b278484612f13565b60006020828403121561307b57600080fd5b81356001600160401b0381111561309157600080fd5b611b2784828501612f5f565b6000602082840312156130af57600080fd5b81516001600160401b038111156130c557600080fd5b611b2784828501612fb3565b600080604083850312156130e457600080fd5b82356001600160401b038111156130fa57600080fd5b61310685828601612f5f565b92505060208301356001600160401b0381111561312257600080fd5b61312e85828601612f5f565b9150509250929050565b60008060006060848603121561314d57600080fd5b83356001600160401b0381111561316357600080fd5b61316f86828701612f5f565b93505060208401356001600160401b0381111561318b57600080fd5b61319786828701612f5f565b92505060408401356001600160401b038111156131b357600080fd5b6131bf86828701612f5f565b9150509250925092565b600080600080600060a086880312156131e157600080fd5b85356001600160401b038111156131f757600080fd5b61320388828901612f5f565b95505060208601356001600160401b0381111561321f57600080fd5b61322b88828901612f5f565b94505060408601356001600160401b0381111561324757600080fd5b61325388828901612f5f565b93505060608601356001600160401b0381111561326f57600080fd5b61327b88828901612f5f565b92505060808601356001600160401b0381111561329757600080fd5b6132a388828901612f5f565b9150509295509295909350565b6000602082840312156132c257600080fd5b6000611b278484612ff9565b6000602082840312156132e057600080fd5b6000611b278484613004565b60008060008060008060006080888a03121561330757600080fd5b60006133138a8a613004565b97505060208801356001600160401b0381111561332f57600080fd5b61333b8a828b01612f1e565b965096505060408801356001600160401b0381111561335957600080fd5b6133658a828b01612f1e565b945094505060608801356001600160401b0381111561338357600080fd5b61338f8a828b01612f1e565b925092505092959891949750929550565b6133a9816148cf565b82525050565b6133a98161487b565b6133a96133c48261487b565b614927565b6133a981614886565b6133a96133de8261488b565b614898565b6133a981614898565b6133a96133de82614898565b6133a96133de8261489b565b60006134108385614872565b935061341d8385846148eb565b61342683614938565b9093019392505050565b600061343b8261486e565b6134458185614872565b93506134558185602086016148f7565b61342681614938565b60006134698261486e565b6134738185610af0565b93506134838185602086016148f7565b9290920192915050565b600061349a601483614872565b7314185d5cd8589b194e881b9bdd081c185d5cd95960621b815260200192915050565b60006134ca601d83614872565b7f457865637574652043726f7373436861696e205478206661696c656421000000815260200192915050565b6000613503602783614872565b7f70617573652045746843726f7373436861696e4461746120636f6e74726163748152660819985a5b195960ca1b602082015260400192915050565b600061354c601f83614872565b7f4e65787455696e7431362c2076616c7565206f7574736964652072616e676500815260200192915050565b6000613585602583614872565b7f546865206e657874426f6f6b4b6565706572206f662068656164657220697320815264656d70747960d81b602082015260400192915050565b60006135cc602983614872565b7f756e70617573652045746843726f7373436861696e4461746120636f6e74726181526818dd0819985a5b195960ba1b602082015260400192915050565b6000613617602383614872565b7f6279746573206c656e67746820646f6573206e6f74206d61746368206164647281526265737360e81b602082015260400192915050565b600061365c601b83614872565b7f766572696679206865616465722070726f6f66206661696c6564210000000000815260200192915050565b6000613695602683614872565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b60006136dd602083614872565b7f536176652063726f7373636861696e207478206578697374206661696c656421815260200192915050565b6000613716604383614872565b7f5361766520506f6c7920636861696e2063757272656e742065706f636820737481527f6172742068656967687420746f204461746120636f6e7472616374206661696c60208201526265642160e81b604082015260600192915050565b6000613781602683614872565b7f54686973205478206973206e6f742061696d696e672061742074686973206e6581526574776f726b2160d01b602082015260400192915050565b60006137c9602383614872565b7f4e657874427974657332302c206f66667365742065786365656473206d6178698152626d756d60e81b602082015260400192915050565b600061380e601883614872565b7f566572696679207369676e6174757265206661696c6564210000000000000000815260200192915050565b6000613847601583614872565b74125b9d985b1a5908199c9bdb4818dbdb9d1c9858dd605a1b815260200192915050565b6000613878601083614872565b6f14185d5cd8589b194e881c185d5cd95960821b815260200192915050565b60006138a4603183614872565b7f6d65726b6c6550726f76652c2065787065637420726f6f74206973206e6f7420815270195c5d585b081858dd1d585b081c9bdbdd607a1b602082015260400192915050565b60006138f7601383614872565b7213995e1d109bdbdad95c9cc81a5b1b1959d85b606a1b815260200192915050565b6000613926601383614872565b72125b9d985b1a59081d1bc818dbdb9d1c9858dd606a1b815260200192915050565b6000613955603e83614872565b7f54686520686569676874206f6620686561646572206973206c6f77657220746881527f616e2063757272656e742065706f636820737461727420686569676874210000602082015260400192915050565b60006139b4602b83614872565b7f45746843726f7373436861696e2063616c6c20627573696e65737320636f6e7481526a1c9858dd0819985a5b195960aa1b602082015260400192915050565b6000613a01603b83614872565b7f5361766520506f6c7920636861696e20626f6f6b206b6565706572732062797481527f657320746f204461746120636f6e7472616374206661696c6564210000000000602082015260400192915050565b6000613a60601783614872565b7f56616c75652065786365656473207468652072616e6765000000000000000000815260200192915050565b6000613a99601583614872565b74111bdb89dd08185c989a5d1c985c9a5b1e481cd95d605a1b815260200192915050565b6000613aca602083614872565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613b03601483614872565b732732bc3a2137b7b6103b30b63ab29032b93937b960611b815260200192915050565b6000613b33602e83614872565b7f6d65726b6c6550726f76652c204e6578744279746520666f7220706f7369746981526d1bdb881a5b999bc819985a5b195960921b602082015260400192915050565b6000613b83602083614872565b7f4e657874427974652c204f66667365742065786365656473206d6178696d756d815260200192915050565b6000613bbc601b83614872565b7f5f7075624b65794c697374206c656e67746820696c6c6567616c210000000000815260200192915050565b6000613bf5602883614872565b7f5468652070617373656420696e2061646472657373206973206e6f74206120638152676f6e74726163742160c01b602082015260400192915050565b6000613c3f602d83614872565b7f53617665204d43204c617465737448656967687420746f204461746120636f6e81526c7472616374206661696c65642160981b602082015260400192915050565b6000613c8e602083614872565b7f4e65787456617255696e742c2076616c7565206f7574736964652072616e6765815260200192915050565b6000613cc7603883614872565b7f56657269667920706f6c7920636861696e2063757272656e742065706f63682081527f686561646572207369676e6174757265206661696c6564210000000000000000602082015260400192915050565b6000613d26601483610af0565b732862797465732c62797465732c75696e7436342960601b815260140192915050565b6000613d56602783614872565b7f4e6f2072657475726e2076616c75652066726f6d20627573696e65737320636f8152666e74726163742160c81b602082015260400192915050565b6000613d9f600e83614872565b6d125b9d985b1a59081b595d1a1bd960921b815260200192915050565b6000613dc9601783614872565b7f6279746573206c656e677468206973206e6f742033322e000000000000000000815260200192915050565b6000613e02601683614872565b75746f6f2073686f7274205f7075624b65794c6973742160501b815260200192915050565b6000613e34603783614872565b7f45746843726f7373436861696e2063616c6c20627573696e65737320636f6e7481527f726163742072657475726e206973206e6f742074727565000000000000000000602082015260400192915050565b6000613e93602283614872565b7f4e65787455696e7431362c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b6000613ed7603883614872565b7f45746843726f7373436861696e4461746120636f6e747261637420686173206181527f6c7265616479206265656e20696e697469616c697a6564210000000000000000602082015260400192915050565b6000613f36601483614872565b7313d9999cd95d08195e18d959591cc81b1a5b5a5d60621b815260200192915050565b6000613f66604383614872565b7f5361766520506f6c7920636861696e2063757272656e742065706f636820626f81527f6f6b206b65657065727320746f204461746120636f6e7472616374206661696c60208201526265642160e81b604082015260600192915050565b6000613fd1602083614872565b7f4e657874486173682c206f66667365742065786365656473206d6178696d756d815260200192915050565b600061400a602283614872565b7f4e65787455696e7436342c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b600061404e601783614872565b7f6b6579206c656e67676820697320746f6f2073686f7274000000000000000000815260200192915050565b6000614087602283614872565b7f746865207472616e73616374696f6e20686173206265656e2065786563757465815261642160f01b602082015260400192915050565b60006140cb603083614872565b7f536176652065746854784861736820627920696e64657820746f20446174612081526f636f6e7472616374206661696c65642160801b602082015260400192915050565b600061411d602283614872565b7f4e65787455696e7433322c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b6000614161602483614872565b7f4e65787456617242797465732c206f66667365742065786365656473206d6178815263696d756d60e01b602082015260400192915050565b60006141a7602a83614872565b7f56657269667920706f6c7920636861696e20686561646572207369676e6174758152697265206661696c65642160b01b602082015260400192915050565b6133a9816148e0565b6133a9816148b4565b6133a9816148bd565b6133a9816148c9565b600061421682856133b8565b601482019150611b27828461345e565b600061423282866133d2565b60018201915061424282856133ec565b60208201915061425282846133ec565b506020019392505050565b600061426982856133d2565b600182019150611b27828461345e565b600061428582846133ec565b50602001919050565b600061429a82856133f8565b600482019150611b27828461345e565b600061065c828461345e565b60006142c2828561345e565b9150611b27828461345e565b60006142da828a61345e565b91506142e6828961345e565b91506142f2828861345e565b91506142fe828761345e565b915061430a828661345e565b9150614316828561345e565b9150614322828461345e565b9998505050505050505050565b600061433b828461345e565b915061065c82613d19565b6020810161091082846133af565b6020810161091082846133a0565b6020810161091082846133c9565b6020810161091082846133e3565b6080810161438c82876133e3565b6143996020830186614201565b6143a660408301856133e3565b61176760608301846133e3565b6020808252810161065c8184613430565b60a080825281016143d58189613430565b90506143e460208301886133a0565b6143f160408301876141f8565b8181036060830152614404818587613404565b905081810360808301526144188184613430565b98975050505050505050565b606080825281016144358186613430565b905081810360208301526144498185613430565b9050611b2760408301846141f8565b602080825281016109108161348d565b60208082528101610910816134bd565b60208082528101610910816134f6565b602080825281016109108161353f565b6020808252810161091081613578565b60208082528101610910816135bf565b602080825281016109108161360a565b602080825281016109108161364f565b6020808252810161091081613688565b60208082528101610910816136d0565b6020808252810161091081613709565b6020808252810161091081613774565b60208082528101610910816137bc565b6020808252810161091081613801565b602080825281016109108161383a565b602080825281016109108161386b565b6020808252810161091081613897565b60208082528101610910816138ea565b6020808252810161091081613919565b6020808252810161091081613948565b60208082528101610910816139a7565b60208082528101610910816139f4565b6020808252810161091081613a53565b6020808252810161091081613a8c565b6020808252810161091081613abd565b6020808252810161091081613af6565b6020808252810161091081613b26565b6020808252810161091081613b76565b6020808252810161091081613baf565b6020808252810161091081613be8565b6020808252810161091081613c32565b6020808252810161091081613c81565b6020808252810161091081613cba565b6020808252810161091081613d49565b6020808252810161091081613d92565b6020808252810161091081613dbc565b6020808252810161091081613df5565b6020808252810161091081613e27565b6020808252810161091081613e86565b6020808252810161091081613eca565b6020808252810161091081613f29565b6020808252810161091081613f59565b6020808252810161091081613fc4565b6020808252810161091081613ffd565b6020808252810161091081614041565b602080825281016109108161407a565b60208082528101610910816140be565b6020808252810161091081614110565b6020808252810161091081614154565b602080825281016109108161419a565b6020810161091082846141ef565b6040810161479482856141e6565b8181036020830152611b278184613430565b6020810161091082846141f8565b604081016147c282856141f8565b61065c60208301846133e3565b608081016147dd82876141f8565b81810360208301526147ef8186613430565b905081810360408301526148038185613430565b905081810360608301526148178184613430565b9695505050505050565b6040518181016001600160401b038111828210171561483f57600080fd5b604052919050565b60006001600160401b0382111561485d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000610910826148a8565b151590565b6001600160f81b03191690565b90565b6001600160e01b03191690565b6001600160a01b031690565b63ffffffff1690565b6001600160401b031690565b60ff1690565b60006109108260006109108261487b565b6000610910826148b4565b82818337506000910152565b60005b838110156149125781810151838201526020016148fa565b83811115614921576000848401525b50505050565b600061091082600061091082614942565b601f01601f191690565b60601b90565b6149518161487b565b811461179d57600080fd5b61495181614886565b61495181614898565b614951816148b4565b614951816148bd56fea365627a7a72315820a9d6245213ee3a62077ae8be794cd326c79e975395163981b0e369d773535ea36c6578706572696d656e74616cf564736f6c63430005110040000000000000000000000000cf2afe102057ba5c16f899271045a0a37fcb10f2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000af83ce8d461e8834de03a3803c968615013c6b3d000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc9060000000000000000000000002cdfc90250ef967036838da601099656e74bcfc50000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c540000000000000000000000000000000000000000000000000000000000000003000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc9060000000000000000000000002cdfc90250ef967036838da601099656e74bcfc50000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c54000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000036164640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000672656d6f76650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000473776170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006756e6c6f636b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c616464457874656e73696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f72656d6f7665457874656e73696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d7265676973746572417373657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c0400000000000000143dfccb7b8a6972cde3b695d3c0c032514b0f3825144c46e1f946362547546677bfa719598385ce56f214f81f676832f6dfec4a5d0671bd27156425fcef981451b7529137d34002c4ebd81a2244f0ee7e95b2c000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012b5760003560e01c80637e724ff3116100ad5780639a8a0592116100715780639a8a059214610225578063b91ca1061461023a578063bd5cf6251461024d578063d450e04c14610260578063f2fde38b146102735761012b565b80637e724ff3146101e75780638456cb59146101fa5780638c5aea41146102025780638da5cb5b146102155780638f32d59b1461021d5761012b565b80636f31031d116100f45780636f31031d14610191578063715018a6146101a457806373f53ba4146101ae5780637b935854146101c15780637bcf7dc1146101d45761012b565b8062ba16941461013057806329dcf4ab1461014e57806334a773eb1461016e5780633f4ba83a146101815780635c975abb14610189575b600080fd5b610138610286565b6040516101459190614346565b60405180910390f35b61016161015c366004613138565b610295565b6040516101459190614362565b61016161017c3660046130d1565b610663565b610161610916565b610161610a6b565b61016161019f3660046132ce565b610a7b565b6101ac610af5565b005b6101616101bc36600461300f565b610b63565b6101616101cf366004613069565b610b78565b6101ac6101e2366004613069565b610b98565b6101616101f536600461300f565b610c8b565b610161610d46565b610161610210366004613069565b610e91565b610138610eb1565b610161610ec0565b61022d610ee4565b60405161014591906147a6565b61016161024836600461300f565b610efa565b61016161025b3660046132ec565b610f0f565b61016161026e3660046131c9565b611298565b6101ac61028136600461300f565b611770565b6001546001600160a01b031681565b60008054600160a01b900460ff16156102c95760405162461bcd60e51b81526004016102c090614548565b60405180910390fd5b6102d1612e38565b6102da856117a0565b90506000600160009054906101000a90046001600160a01b031690506000816001600160a01b0316635ac407906040518163ffffffff1660e01b815260040160206040518083038186803b15801561033157600080fd5b505afa158015610345573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061036991908101906132b0565b63ffffffff169050806001600160401b0316836060015163ffffffff16116103a35760405162461bcd60e51b81526004016102c090614588565b6101408301516bffffffffffffffffffffffff19166103d45760405162461bcd60e51b81526004016102c090614498565b6060610453836001600160a01b03166369d480746040518163ffffffff1660e01b815260040160006040518083038186803b15801561041257600080fd5b505afa158015610426573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261044e919081019061309d565b6118bf565b805190915061046e898884600360001986015b048503611972565b61048a5760405162461bcd60e51b81526004016102c090614528565b600060606104978a611b2f565b91509150816001600160601b0319168761014001516001600160601b031916146104d35760405162461bcd60e51b81526004016102c090614568565b6060870151604051638a8bd17f60e01b81526001600160a01b03881691638a8bd17f916105039190600401614778565b602060405180830381600087803b15801561051d57600080fd5b505af1158015610531573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610555919081019061302d565b6105715760405162461bcd60e51b81526004016102c090614638565b856001600160a01b03166341973cd961058983611bab565b6040518263ffffffff1660e01b81526004016105a591906143b3565b602060405180830381600087803b1580156105bf57600080fd5b505af11580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105f7919081019061302d565b6106135760405162461bcd60e51b81526004016102c0906145a8565b7fe60d33488cba3977bf65766cd2f8ac9617f64bf3b3198aff6240ce5c7d43b69087606001518c604051610648929190614786565b60405180910390a160019750505050505050505b9392505050565b60008054600160a01b900460ff161561068e5760405162461bcd60e51b81526004016102c090614548565b60015460408051631a75201d60e21b815290516001600160a01b039092169182916369d48074916004808301926000929190829003018186803b1580156106d457600080fd5b505afa1580156106e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610710919081019061309d565b511561072e5760405162461bcd60e51b81526004016102c0906146c8565b610736612e38565b61073f856117a0565b90506000606061074e86611b2f565b91509150816001600160601b0319168361014001516001600160601b0319161461078a5760405162461bcd60e51b81526004016102c090614568565b6060830151604051638a8bd17f60e01b81526001600160a01b03861691638a8bd17f916107ba9190600401614778565b602060405180830381600087803b1580156107d457600080fd5b505af11580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061080c919081019061302d565b6108285760405162461bcd60e51b81526004016102c0906144f8565b836001600160a01b03166341973cd961084083611bab565b6040518263ffffffff1660e01b815260040161085c91906143b3565b602060405180830381600087803b15801561087657600080fd5b505af115801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108ae919081019061302d565b6108ca5760405162461bcd60e51b81526004016102c0906146e8565b7ff01968fc3a2655cf1b5144cb32de6dc898f91b9239c103744e8457152ab2fbde8360600151886040516108ff929190614786565b60405180910390a160019450505050505b92915050565b6000610920610ec0565b61093c5760405162461bcd60e51b81526004016102c0906145d8565b610944610a6b565b1561095157610951611c1a565b60015460408051635c975abb60e01b815290516001600160a01b03909216918291635c975abb916004808301926020929190829003018186803b15801561099757600080fd5b505afa1580156109ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109cf919081019061302d565b15610a6357806001600160a01b0316633f4ba83a6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610a0f57600080fd5b505af1158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a47919081019061302d565b610a635760405162461bcd60e51b81526004016102c0906144a8565b600191505090565b600054600160a01b900460ff1690565b60008054600160a01b900460ff16610aa55760405162461bcd60e51b81526004016102c090614458565b610aad610ec0565b610ac95760405162461bcd60e51b81526004016102c0906145d8565b506001805467ffffffffffffffff60a01b1916600160a01b6001600160401b038416021781555b919050565b610afd610ec0565b610b195760405162461bcd60e51b81526004016102c0906145d8565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60026020526000908152604090205460ff1681565b805160208183018101805160048252928201919093012091525460ff1681565b600581604051610ba891906142aa565b9081526040519081900360200190205460ff16610bd75760405162461bcd60e51b81526004016102c0906145c8565b6000600582604051610be991906142aa565b908152604051908190036020018120805492151560ff19909316929092179091556001546341973cd960e01b82526001600160a01b0316906341973cd990610c359084906004016143b3565b602060405180830381600087803b158015610c4f57600080fd5b505af1158015610c63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c87919081019061302d565b5050565b60008054600160a01b900460ff16610cb55760405162461bcd60e51b81526004016102c090614458565b610cbd610ec0565b610cd95760405162461bcd60e51b81526004016102c0906145d8565b60015460405163f2fde38b60e01b81526001600160a01b0390911690819063f2fde38b90610d0b908690600401614346565b600060405180830381600087803b158015610d2557600080fd5b505af1158015610d39573d6000803e3d6000fd5b5060019695505050505050565b6000610d50610ec0565b610d6c5760405162461bcd60e51b81526004016102c0906145d8565b610d74610a6b565b610d8057610d80611c90565b60015460408051635c975abb60e01b815290516001600160a01b03909216918291635c975abb916004808301926020929190829003018186803b158015610dc657600080fd5b505afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dfe919081019061302d565b610a6357806001600160a01b0316638456cb596040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e3d57600080fd5b505af1158015610e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e75919081019061302d565b610a635760405162461bcd60e51b81526004016102c090614478565b805160208183018101805160058252928201919093012091525460ff1681565b6000546001600160a01b031690565b600080546001600160a01b0316610ed5611cf2565b6001600160a01b031614905090565b600154600160a01b90046001600160401b031681565b60036020526000908152604090205460ff1681565b60008054600160a01b900460ff1615610f3a5760405162461bcd60e51b81526004016102c090614548565b3360009081526002602052604090205460ff16610f695760405162461bcd60e51b81526004016102c090614538565b60015460408051600162c2db5f60e01b0319815290516001600160a01b0390921691600091839163ff3d24a191600480820192602092909190829003018186803b158015610fb657600080fd5b505afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fee919081019061304b565b90506060610ffb82611cf6565b9050606061100882611d3a565b61109e6002308560405160200161102092919061420a565b60408051601f198184030181529082905261103a916142aa565b602060405180830381855afa158015611057573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061107a919081019061304b565b60405160200161108a9190614279565b604051602081830303815290604052611d3a565b6110af6110aa33611d71565b611d3a565b6110b88f611d8c565b6110f78f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b6111368e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b6111758d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d3a92505050565b60405160200161118b97969594939291906142ce565b60408051601f19818403018152908290528051602082012063130f33d960e21b83529092506001600160a01b03861691634c3ccf64916111cd91600401614370565b602060405180830381600087803b1580156111e757600080fd5b505af11580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061121f919081019061302d565b61123b5760405162461bcd60e51b81526004016102c090614738565b326001600160a01b03167f6ad3bf15c1988bc04bc153490cab16db8efb9a3990215bf1c64ea6e28be8848383338f8f8f8760405161127e969594939291906143c4565b60405180910390a25060019b9a5050505050505050505050565b60008054600160a01b900460ff16156112c35760405162461bcd60e51b81526004016102c090614548565b6112cb612e38565b6112d4866117a0565b90506000600160009054906101000a90046001600160a01b03169050606061132e826001600160a01b03166369d480746040518163ffffffff1660e01b815260040160006040518083038186803b15801561041257600080fd5b90506000826001600160a01b0316635ac407906040518163ffffffff1660e01b815260040160206040518083038186803b15801561136b57600080fd5b505afa15801561137f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113a391908101906132b0565b63ffffffff16905060008251905081856060015163ffffffff16106113f5576113d48a888560036000198601610466565b6113f05760405162461bcd60e51b81526004016102c090614768565b61147b565b61140788888560036000198601610466565b6114235760405162461bcd60e51b81526004016102c090614658565b61142b612e38565b611434896117a0565b905060606114478b836101000151611dcf565b905061145281611ece565b61145b8d611ef9565b146114785760405162461bcd60e51b81526004016102c0906144c8565b50505b606061148b8c8760e00151611dcf565b9050611495612e93565b61149e82611fb6565b9050856001600160a01b0316630586763c82602001516114c18460000151611ece565b6040518363ffffffff1660e01b81526004016114de9291906147b4565b60206040518083038186803b1580156114f657600080fd5b505afa15801561150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061152e919081019061302d565b1561154b5760405162461bcd60e51b81526004016102c090614728565b856001600160a01b031663e90bfdcf826020015161156c8460000151611ece565b6040518363ffffffff1660e01b81526004016115899291906147b4565b602060405180830381600087803b1580156115a357600080fd5b505af11580156115b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115db919081019061302d565b6115f75760405162461bcd60e51b81526004016102c0906144e8565b6001546040820151606001516001600160401b03908116600160a01b90920416146116345760405162461bcd60e51b81526004016102c090614508565b6000611647826040015160800151612092565b6001600160a01b03811660009081526003602052604090205490915060ff166116825760405162461bcd60e51b81526004016102c090614578565b6004826040015160a0015160405161169a91906142aa565b9081526040519081900360200190205460ff166116c95760405162461bcd60e51b81526004016102c090614678565b6116f281836040015160a00151846040015160c0015185604001516040015186602001516120bd565b61170e5760405162461bcd60e51b81526004016102c090614468565b602082015160408084015160808101518551915192517f8a4a2663ce60ce4955c595da2894de0415240f1ace024cfbff85f513b656bdae94611752949093916147cf565b60405180910390a16001985050505050505050505b95945050505050565b611778610ec0565b6117945760405162461bcd60e51b81526004016102c0906145d8565b61179d8161222e565b50565b6117a8612e38565b6117b0612e38565b60006117bc84826122af565b63ffffffff909116835290506117d28482612338565b6001600160401b03909116602084015290506117ee84826123bf565b60a0840191909152905061180284826123bf565b60c0840191909152905061181684826123bf565b60e0840191909152905061182a84826123bf565b610100840191909152905061183f84826122af565b63ffffffff9091166040840152905061185884826122af565b63ffffffff909116606084015290506118718482612338565b6001600160401b039091166080840152905061188d8482612404565b61012084019190915290506118a284826124b8565b506bffffffffffffffffffffffff19166101408301525092915050565b60606000806118ce8482612338565b80935081925050506060816001600160401b031660405190808252806020026020018201604052801561190b578160200160208202803883390190505b509050606060005b836001600160401b03168110156119675761192e8786612404565b9550915061193b82612092565b83828151811061194757fe5b6001600160a01b0390921660209283029190910190910152600101611913565b509095945050505050565b60008061197e86611ef9565b905060006119976041875161250190919063ffffffff16565b90506060816040519080825280602002602001820160405280156119c5578160200160208202803883390190505b50905060008080805b85811015611b12576119ed6119e88c604184026020612543565b611ece565b9350611a046119e88c604184026020016020612543565b92508a6041820260400181518110611a1857fe5b602001015160f81c60f81b60f81c601b0191506001600288604051602001611a409190614279565b60408051601f1981840301815290829052611a5a916142aa565b602060405180830381855afa158015611a77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611a9a919081019061304b565b83868660405160008152602001604052604051611aba949392919061437e565b6020604051602081039080840390855afa158015611adc573d6000803e3d6000fd5b50505060206040510351858281518110611af257fe5b6001600160a01b03909216602092830291909101909101526001016119ce565b50611b1e89858a6125c3565b96505050505050505b949350505050565b600060606043835181611b3e57fe5b0615611b5c5760405162461bcd60e51b81526004016102c090614618565b60006043845181611b6957fe5b0490506001811015611b8d5760405162461bcd60e51b81526004016102c090614698565b611ba1816003600019820104830386612664565b9250925050915091565b805160609081611bba82611d8c565b905060005b82811015611c125781611be76110aa878481518110611bda57fe5b6020026020010151611d71565b604051602001611bf89291906142b6565b60408051601f198184030181529190529150600101611bbf565b509392505050565b600054600160a01b900460ff16611c435760405162461bcd60e51b81526004016102c090614458565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611c79611cf2565b604051611c869190614354565b60405180910390a1565b600054600160a01b900460ff1615611cba5760405162461bcd60e51b81526004016102c090614548565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c795b3390565b60606001600160ff1b03821115611d1f5760405162461bcd60e51b81526004016102c0906145b8565b60405190506020815281602082015260408101604052919050565b8051606090611d4881612819565b83604051602001611d5a9291906142b6565b604051602081830303815290604052915050919050565b604080516014815260609290921b6020830152818101905290565b6040516008808252606091906000601f5b82821015611dbf5785811a826020860101536001919091019060001901611d9d565b5050506028810160405292915050565b6060600081611dde8583612404565b925090506000611ded826128d0565b90506000611e166021611e0a868a516128eb90919063ffffffff16565b9063ffffffff61250116565b9050600080805b83811015611ea157611e2f8a8861292d565b97509150611e3d8a886123bf565b975092506001600160f81b03198216611e6157611e5a8386612976565b9450611e99565b600160f81b6001600160f81b031983161415611e8157611e5a8584612976565b60405162461bcd60e51b81526004016102c0906145f8565b600101611e1d565b50878414611ec15760405162461bcd60e51b81526004016102c090614558565b5092979650505050505050565b60008151602014611ef15760405162461bcd60e51b81526004016102c090614688565b506020015190565b600060028083604051611f0c91906142aa565b602060405180830381855afa158015611f29573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f4c919081019061304b565b604051602001611f5c9190614279565b60408051601f1981840301815290829052611f76916142aa565b602060405180830381855afa158015611f93573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250610910919081019061304b565b611fbe612e93565b611fc6612e93565b6000611fd28482612404565b9083529050611fe18482612338565b6001600160401b0390911660208401529050611ffb612eb7565b6120058583612404565b90825291506120148583612404565b602083019190915291506120288583612404565b6040830191909152915061203c8583612338565b6001600160401b03909116606083015291506120588583612404565b6080830191909152915061206c8583612404565b60a083019190915291506120808583612404565b5060c082015260408301525092915050565b600081516014146120b55760405162461bcd60e51b81526004016102c0906144b8565b506014015190565b60006120c8866129ed565b6120e45760405162461bcd60e51b81526004016102c090614628565b60606000876001600160a01b031687604051602001612103919061432f565b6040516020818303038152906040528051906020012087878760405160200161212e93929190614424565b60408051601f198184030181529082905261214c929160200161428e565b60408051601f1981840301815290829052612166916142aa565b6000604051808303816000865af19150503d80600081146121a3576040519150601f19603f3d011682016040523d82523d6000602084013e6121a8565b606091505b50925090506001811515146121cf5760405162461bcd60e51b81526004016102c090614598565b81516121ed5760405162461bcd60e51b81526004016102c090614668565b60006121fa83601f612a24565b50905060018115151461221f5760405162461bcd60e51b81526004016102c0906146a8565b50600198975050505050505050565b6001600160a01b0381166122545760405162461bcd60e51b81526004016102c0906144d8565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080835183600401111580156122c857508260040183105b6122e45760405162461bcd60e51b81526004016102c090614748565b600060405160046000600182038760208a0101515b838310156123195780821a838601536001830192506001820391506122f9565b50505080820160405260200390035192505050600482015b9250929050565b6000808351836008011115801561235157508260080183105b61236d5760405162461bcd60e51b81526004016102c090614708565b600060405160086000600182038760208a0101515b838310156123a25780821a83860153600183019250600182039150612382565b505050808201604052602003900351956008949094019450505050565b600080835183602001111580156123d857508260200183105b6123f45760405162461bcd60e51b81526004016102c0906146f8565b5050602091810182015192910190565b60606000806124138585612abd565b86519095509091508185011180159061242d575080840184105b6124495760405162461bcd60e51b81526004016102c090614758565b606081158015612464576040519150602082016040526124ae565b6040519150601f8316801560200281840101848101888315602002848c0101015b8183101561249d578051835260209283019201612485565b5050848452601f01601f1916604052505b5095930193505050565b600080835183601401111580156124d157508260140183105b6124ed5760405162461bcd60e51b81526004016102c090614518565b505081810160200151601482019250929050565b600061065c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612c02565b60608183018451101561255557600080fd5b606082158015612570576040519150602082016040526125ba565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125a9578051835260209283019201612591565b5050858452601f01601f1916604052505b50949350505050565b600080805b84518110156126585760005b865181101561264f578681815181106125e957fe5b60200260200101516001600160a01b031686838151811061260657fe5b60200260200101516001600160a01b0316141561264757828060010193505086818151811061263157fe5b6020026020010160006001600160a01b03168152505b6001016125d4565b506001016125c8565b50909111159392505050565b600060608061267286612c39565b90506060866040519080825280602002602001820160405280156126a0578160200160208202803883390190505b50905060006060815b89811015612737576126c088604383026043612543565b9150846126cf6110aa84612c7c565b6040516020016126e09291906142b6565b60405160208183030381529060405294506126fe8260036040612543565b8051906020012092508260001c84828151811061271757fe5b6001600160a01b03909216602092830291909101909101526001016126a9565b508361274289612c39565b6040516020016127539291906142b6565b60405160208183030381529060405293506000600360028660405161277891906142aa565b602060405180830381855afa158015612795573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506127b8919081019061304b565b6040516020016127c89190614279565b60408051601f19818403018152908290526127e2916142aa565b602060405180830381855afa1580156127ff573d6000803e3d6000fd5b50506040515160601b9b949a509398505050505050505050565b606060fd826001600160401b0316101561283d5761283682612d35565b9050610af0565b61ffff826001600160401b03161161288c5761285c60fd60f81b612d51565b61286583612c39565b6040516020016128769291906142b6565b6040516020818303038152906040529050610af0565b63ffffffff826001600160401b0316116128b6576128ad607f60f91b612d51565b61286583612d5f565b6128c76001600160f81b0319612d51565b61286583611d8c565b60006002600060f81b83604051602001611f5c92919061425d565b600061065c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612da2565b6000808351836001011115801561294657508260010183105b6129625760405162461bcd60e51b81526004016102c090614608565b505081810160200151600182019250929050565b60006002600160f81b848460405160200161299393929190614226565b60408051601f19818403018152908290526129ad916142aa565b602060405180830381855afa1580156129ca573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061065c919081019061304b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590611b275750141592915050565b60008083518360010111158015612a3d57508260010183105b612a595760405162461bcd60e51b81526004016102c0906146d8565b838301602001516000600160f81b6001600160f81b031983161415612a8057506001612aaf565b6001600160f81b03198216612a9757506000612aaf565b60405162461bcd60e51b81526004016102c0906145e8565b956001949094019450505050565b6000806000612acc858561292d565b94509050600060fd60f81b6001600160f81b031983161415612b3557612af28686612dce565b955061ffff16905060fd8110801590612b0d575061ffff8111155b612b295760405162461bcd60e51b81526004016102c090614488565b92508391506123319050565b607f60f91b6001600160f81b031983161415612b9057612b5586866122af565b955063ffffffff16905061ffff81118015612b74575063ffffffff8111155b612b295760405162461bcd60e51b81526004016102c090614648565b6001600160f81b03198083161415612bdc57612bac8686612338565b95506001600160401b0316905063ffffffff8111612b295760405162461bcd60e51b81526004016102c090614648565b5060f881901c60fd8110612b295760405162461bcd60e51b81526004016102c090614648565b60008183612c235760405162461bcd60e51b81526004016102c091906143b3565b506000838581612c2f57fe5b0495945050505050565b6040516002808252606091906000601f5b82821015612c6c5785811a826020860101536001919091019060001901612c4a565b5050506022810160405292915050565b6060604382511015612ca05760405162461bcd60e51b81526004016102c090614718565b612cad8260006023612543565b9050600282604281518110612cbe57fe5b016020015160f81c81612ccd57fe5b0660ff1660001415612d0757600260f81b81600281518110612ceb57fe5b60200101906001600160f81b031916908160001a905350610af0565b600360f81b81600281518110612d1957fe5b60200101906001600160f81b031916908160001a905350919050565b604080516001815260f89290921b602083015260218201905290565b60606109108260f81c612d35565b6040516004808252606091906000601f5b82821015612d925785811a826020860101536001919091019060001901612d70565b5050506024810160405292915050565b60008184841115612dc65760405162461bcd60e51b81526004016102c091906143b3565b505050900390565b60008083518360020111158015612de757508260020183105b612e035760405162461bcd60e51b81526004016102c0906146b8565b6000604051846020870101518060011a82538060001a6001830153506002818101604052601d19909101519694019450505050565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082015261014081019190915290565b6040805160608082018352815260006020820152908101612eb2612eb7565b905290565b6040518060e0016040528060608152602001606081526020016060815260200160006001600160401b031681526020016060815260200160608152602001606081525090565b803561091081614948565b80516109108161495c565b805161091081614965565b60008083601f840112612f3057600080fd5b5081356001600160401b03811115612f4757600080fd5b60208301915083600182028301111561233157600080fd5b600082601f830112612f7057600080fd5b8135612f83612f7e82614847565b614821565b91508082526020830160208301858383011115612f9f57600080fd5b612faa8382846148eb565b50505092915050565b600082601f830112612fc457600080fd5b8151612fd2612f7e82614847565b91508082526020830160208301858383011115612fee57600080fd5b612faa8382846148f7565b80516109108161496e565b803561091081614977565b60006020828403121561302157600080fd5b6000611b278484612efd565b60006020828403121561303f57600080fd5b6000611b278484612f08565b60006020828403121561305d57600080fd5b6000611b278484612f13565b60006020828403121561307b57600080fd5b81356001600160401b0381111561309157600080fd5b611b2784828501612f5f565b6000602082840312156130af57600080fd5b81516001600160401b038111156130c557600080fd5b611b2784828501612fb3565b600080604083850312156130e457600080fd5b82356001600160401b038111156130fa57600080fd5b61310685828601612f5f565b92505060208301356001600160401b0381111561312257600080fd5b61312e85828601612f5f565b9150509250929050565b60008060006060848603121561314d57600080fd5b83356001600160401b0381111561316357600080fd5b61316f86828701612f5f565b93505060208401356001600160401b0381111561318b57600080fd5b61319786828701612f5f565b92505060408401356001600160401b038111156131b357600080fd5b6131bf86828701612f5f565b9150509250925092565b600080600080600060a086880312156131e157600080fd5b85356001600160401b038111156131f757600080fd5b61320388828901612f5f565b95505060208601356001600160401b0381111561321f57600080fd5b61322b88828901612f5f565b94505060408601356001600160401b0381111561324757600080fd5b61325388828901612f5f565b93505060608601356001600160401b0381111561326f57600080fd5b61327b88828901612f5f565b92505060808601356001600160401b0381111561329757600080fd5b6132a388828901612f5f565b9150509295509295909350565b6000602082840312156132c257600080fd5b6000611b278484612ff9565b6000602082840312156132e057600080fd5b6000611b278484613004565b60008060008060008060006080888a03121561330757600080fd5b60006133138a8a613004565b97505060208801356001600160401b0381111561332f57600080fd5b61333b8a828b01612f1e565b965096505060408801356001600160401b0381111561335957600080fd5b6133658a828b01612f1e565b945094505060608801356001600160401b0381111561338357600080fd5b61338f8a828b01612f1e565b925092505092959891949750929550565b6133a9816148cf565b82525050565b6133a98161487b565b6133a96133c48261487b565b614927565b6133a981614886565b6133a96133de8261488b565b614898565b6133a981614898565b6133a96133de82614898565b6133a96133de8261489b565b60006134108385614872565b935061341d8385846148eb565b61342683614938565b9093019392505050565b600061343b8261486e565b6134458185614872565b93506134558185602086016148f7565b61342681614938565b60006134698261486e565b6134738185610af0565b93506134838185602086016148f7565b9290920192915050565b600061349a601483614872565b7314185d5cd8589b194e881b9bdd081c185d5cd95960621b815260200192915050565b60006134ca601d83614872565b7f457865637574652043726f7373436861696e205478206661696c656421000000815260200192915050565b6000613503602783614872565b7f70617573652045746843726f7373436861696e4461746120636f6e74726163748152660819985a5b195960ca1b602082015260400192915050565b600061354c601f83614872565b7f4e65787455696e7431362c2076616c7565206f7574736964652072616e676500815260200192915050565b6000613585602583614872565b7f546865206e657874426f6f6b4b6565706572206f662068656164657220697320815264656d70747960d81b602082015260400192915050565b60006135cc602983614872565b7f756e70617573652045746843726f7373436861696e4461746120636f6e74726181526818dd0819985a5b195960ba1b602082015260400192915050565b6000613617602383614872565b7f6279746573206c656e67746820646f6573206e6f74206d61746368206164647281526265737360e81b602082015260400192915050565b600061365c601b83614872565b7f766572696679206865616465722070726f6f66206661696c6564210000000000815260200192915050565b6000613695602683614872565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b60006136dd602083614872565b7f536176652063726f7373636861696e207478206578697374206661696c656421815260200192915050565b6000613716604383614872565b7f5361766520506f6c7920636861696e2063757272656e742065706f636820737481527f6172742068656967687420746f204461746120636f6e7472616374206661696c60208201526265642160e81b604082015260600192915050565b6000613781602683614872565b7f54686973205478206973206e6f742061696d696e672061742074686973206e6581526574776f726b2160d01b602082015260400192915050565b60006137c9602383614872565b7f4e657874427974657332302c206f66667365742065786365656473206d6178698152626d756d60e81b602082015260400192915050565b600061380e601883614872565b7f566572696679207369676e6174757265206661696c6564210000000000000000815260200192915050565b6000613847601583614872565b74125b9d985b1a5908199c9bdb4818dbdb9d1c9858dd605a1b815260200192915050565b6000613878601083614872565b6f14185d5cd8589b194e881c185d5cd95960821b815260200192915050565b60006138a4603183614872565b7f6d65726b6c6550726f76652c2065787065637420726f6f74206973206e6f7420815270195c5d585b081858dd1d585b081c9bdbdd607a1b602082015260400192915050565b60006138f7601383614872565b7213995e1d109bdbdad95c9cc81a5b1b1959d85b606a1b815260200192915050565b6000613926601383614872565b72125b9d985b1a59081d1bc818dbdb9d1c9858dd606a1b815260200192915050565b6000613955603e83614872565b7f54686520686569676874206f6620686561646572206973206c6f77657220746881527f616e2063757272656e742065706f636820737461727420686569676874210000602082015260400192915050565b60006139b4602b83614872565b7f45746843726f7373436861696e2063616c6c20627573696e65737320636f6e7481526a1c9858dd0819985a5b195960aa1b602082015260400192915050565b6000613a01603b83614872565b7f5361766520506f6c7920636861696e20626f6f6b206b6565706572732062797481527f657320746f204461746120636f6e7472616374206661696c6564210000000000602082015260400192915050565b6000613a60601783614872565b7f56616c75652065786365656473207468652072616e6765000000000000000000815260200192915050565b6000613a99601583614872565b74111bdb89dd08185c989a5d1c985c9a5b1e481cd95d605a1b815260200192915050565b6000613aca602083614872565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6000613b03601483614872565b732732bc3a2137b7b6103b30b63ab29032b93937b960611b815260200192915050565b6000613b33602e83614872565b7f6d65726b6c6550726f76652c204e6578744279746520666f7220706f7369746981526d1bdb881a5b999bc819985a5b195960921b602082015260400192915050565b6000613b83602083614872565b7f4e657874427974652c204f66667365742065786365656473206d6178696d756d815260200192915050565b6000613bbc601b83614872565b7f5f7075624b65794c697374206c656e67746820696c6c6567616c210000000000815260200192915050565b6000613bf5602883614872565b7f5468652070617373656420696e2061646472657373206973206e6f74206120638152676f6e74726163742160c01b602082015260400192915050565b6000613c3f602d83614872565b7f53617665204d43204c617465737448656967687420746f204461746120636f6e81526c7472616374206661696c65642160981b602082015260400192915050565b6000613c8e602083614872565b7f4e65787456617255696e742c2076616c7565206f7574736964652072616e6765815260200192915050565b6000613cc7603883614872565b7f56657269667920706f6c7920636861696e2063757272656e742065706f63682081527f686561646572207369676e6174757265206661696c6564210000000000000000602082015260400192915050565b6000613d26601483610af0565b732862797465732c62797465732c75696e7436342960601b815260140192915050565b6000613d56602783614872565b7f4e6f2072657475726e2076616c75652066726f6d20627573696e65737320636f8152666e74726163742160c81b602082015260400192915050565b6000613d9f600e83614872565b6d125b9d985b1a59081b595d1a1bd960921b815260200192915050565b6000613dc9601783614872565b7f6279746573206c656e677468206973206e6f742033322e000000000000000000815260200192915050565b6000613e02601683614872565b75746f6f2073686f7274205f7075624b65794c6973742160501b815260200192915050565b6000613e34603783614872565b7f45746843726f7373436861696e2063616c6c20627573696e65737320636f6e7481527f726163742072657475726e206973206e6f742074727565000000000000000000602082015260400192915050565b6000613e93602283614872565b7f4e65787455696e7431362c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b6000613ed7603883614872565b7f45746843726f7373436861696e4461746120636f6e747261637420686173206181527f6c7265616479206265656e20696e697469616c697a6564210000000000000000602082015260400192915050565b6000613f36601483614872565b7313d9999cd95d08195e18d959591cc81b1a5b5a5d60621b815260200192915050565b6000613f66604383614872565b7f5361766520506f6c7920636861696e2063757272656e742065706f636820626f81527f6f6b206b65657065727320746f204461746120636f6e7472616374206661696c60208201526265642160e81b604082015260600192915050565b6000613fd1602083614872565b7f4e657874486173682c206f66667365742065786365656473206d6178696d756d815260200192915050565b600061400a602283614872565b7f4e65787455696e7436342c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b600061404e601783614872565b7f6b6579206c656e67676820697320746f6f2073686f7274000000000000000000815260200192915050565b6000614087602283614872565b7f746865207472616e73616374696f6e20686173206265656e2065786563757465815261642160f01b602082015260400192915050565b60006140cb603083614872565b7f536176652065746854784861736820627920696e64657820746f20446174612081526f636f6e7472616374206661696c65642160801b602082015260400192915050565b600061411d602283614872565b7f4e65787455696e7433322c206f66667365742065786365656473206d6178696d815261756d60f01b602082015260400192915050565b6000614161602483614872565b7f4e65787456617242797465732c206f66667365742065786365656473206d6178815263696d756d60e01b602082015260400192915050565b60006141a7602a83614872565b7f56657269667920706f6c7920636861696e20686561646572207369676e6174758152697265206661696c65642160b01b602082015260400192915050565b6133a9816148e0565b6133a9816148b4565b6133a9816148bd565b6133a9816148c9565b600061421682856133b8565b601482019150611b27828461345e565b600061423282866133d2565b60018201915061424282856133ec565b60208201915061425282846133ec565b506020019392505050565b600061426982856133d2565b600182019150611b27828461345e565b600061428582846133ec565b50602001919050565b600061429a82856133f8565b600482019150611b27828461345e565b600061065c828461345e565b60006142c2828561345e565b9150611b27828461345e565b60006142da828a61345e565b91506142e6828961345e565b91506142f2828861345e565b91506142fe828761345e565b915061430a828661345e565b9150614316828561345e565b9150614322828461345e565b9998505050505050505050565b600061433b828461345e565b915061065c82613d19565b6020810161091082846133af565b6020810161091082846133a0565b6020810161091082846133c9565b6020810161091082846133e3565b6080810161438c82876133e3565b6143996020830186614201565b6143a660408301856133e3565b61176760608301846133e3565b6020808252810161065c8184613430565b60a080825281016143d58189613430565b90506143e460208301886133a0565b6143f160408301876141f8565b8181036060830152614404818587613404565b905081810360808301526144188184613430565b98975050505050505050565b606080825281016144358186613430565b905081810360208301526144498185613430565b9050611b2760408301846141f8565b602080825281016109108161348d565b60208082528101610910816134bd565b60208082528101610910816134f6565b602080825281016109108161353f565b6020808252810161091081613578565b60208082528101610910816135bf565b602080825281016109108161360a565b602080825281016109108161364f565b6020808252810161091081613688565b60208082528101610910816136d0565b6020808252810161091081613709565b6020808252810161091081613774565b60208082528101610910816137bc565b6020808252810161091081613801565b602080825281016109108161383a565b602080825281016109108161386b565b6020808252810161091081613897565b60208082528101610910816138ea565b6020808252810161091081613919565b6020808252810161091081613948565b60208082528101610910816139a7565b60208082528101610910816139f4565b6020808252810161091081613a53565b6020808252810161091081613a8c565b6020808252810161091081613abd565b6020808252810161091081613af6565b6020808252810161091081613b26565b6020808252810161091081613b76565b6020808252810161091081613baf565b6020808252810161091081613be8565b6020808252810161091081613c32565b6020808252810161091081613c81565b6020808252810161091081613cba565b6020808252810161091081613d49565b6020808252810161091081613d92565b6020808252810161091081613dbc565b6020808252810161091081613df5565b6020808252810161091081613e27565b6020808252810161091081613e86565b6020808252810161091081613eca565b6020808252810161091081613f29565b6020808252810161091081613f59565b6020808252810161091081613fc4565b6020808252810161091081613ffd565b6020808252810161091081614041565b602080825281016109108161407a565b60208082528101610910816140be565b6020808252810161091081614110565b6020808252810161091081614154565b602080825281016109108161419a565b6020810161091082846141ef565b6040810161479482856141e6565b8181036020830152611b278184613430565b6020810161091082846141f8565b604081016147c282856141f8565b61065c60208301846133e3565b608081016147dd82876141f8565b81810360208301526147ef8186613430565b905081810360408301526148038185613430565b905081810360608301526148178184613430565b9695505050505050565b6040518181016001600160401b038111828210171561483f57600080fd5b604052919050565b60006001600160401b0382111561485d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b6000610910826148a8565b151590565b6001600160f81b03191690565b90565b6001600160e01b03191690565b6001600160a01b031690565b63ffffffff1690565b6001600160401b031690565b60ff1690565b60006109108260006109108261487b565b6000610910826148b4565b82818337506000910152565b60005b838110156149125781810151838201526020016148fa565b83811115614921576000848401525b50505050565b600061091082600061091082614942565b601f01601f191690565b60601b90565b6149518161487b565b811461179d57600080fd5b61495181614886565b61495181614898565b614951816148b4565b614951816148bd56fea365627a7a72315820a9d6245213ee3a62077ae8be794cd326c79e975395163981b0e369d773535ea36c6578706572696d656e74616cf564736f6c63430005110040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cf2afe102057ba5c16f899271045a0a37fcb10f2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000af83ce8d461e8834de03a3803c968615013c6b3d000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc9060000000000000000000000002cdfc90250ef967036838da601099656e74bcfc50000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c540000000000000000000000000000000000000000000000000000000000000003000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc9060000000000000000000000002cdfc90250ef967036838da601099656e74bcfc50000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c54000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000036164640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000672656d6f76650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000473776170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006756e6c6f636b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c616464457874656e73696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f72656d6f7665457874656e73696f6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d7265676973746572417373657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c0400000000000000143dfccb7b8a6972cde3b695d3c0c032514b0f3825144c46e1f946362547546677bfa719598385ce56f214f81f676832f6dfec4a5d0671bd27156425fcef981451b7529137d34002c4ebd81a2244f0ee7e95b2c000000000
-----Decoded View---------------
Arg [0] : _eccd (address): 0xcF2afe102057bA5c16f899271045a0A37fCb10f2
Arg [1] : _chainId (uint64): 2
Arg [2] : fromContractWhiteList (address[]): 0xAF83Ce8d461E8834dE03A3803c968615013c6B3d,0x250e76987d838a75310c34bf422ea9f1AC4Cc906,0x2cdfc90250EF967036838DA601099656e74bCfc5,0x9a016Ce184a22DbF6c17daA59Eb7d3140DBd1c54
Arg [3] : toContractWhiteList (address[]): 0x250e76987d838a75310c34bf422ea9f1AC4Cc906,0x2cdfc90250EF967036838DA601099656e74bCfc5,0x9a016Ce184a22DbF6c17daA59Eb7d3140DBd1c54
Arg [4] : methodWhiteList (bytes[]): System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[],System.Byte[]
Arg [5] : curEpochPkBytes (bytes): 0x0400000000000000143dfccb7b8a6972cde3b695d3c0c032514b0f3825144c46e1f946362547546677bfa719598385ce56f214f81f676832f6dfec4a5d0671bd27156425fcef981451b7529137d34002c4ebd81a2244f0ee7e95b2c0
-----Encoded View---------------
41 Constructor Arguments found :
Arg [0] : 000000000000000000000000cf2afe102057ba5c16f899271045a0a37fcb10f2
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [5] : 00000000000000000000000000000000000000000000000000000000000004a0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 000000000000000000000000af83ce8d461e8834de03a3803c968615013c6b3d
Arg [8] : 000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc906
Arg [9] : 0000000000000000000000002cdfc90250ef967036838da601099656e74bcfc5
Arg [10] : 0000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c54
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 000000000000000000000000250e76987d838a75310c34bf422ea9f1ac4cc906
Arg [13] : 0000000000000000000000002cdfc90250ef967036838da601099656e74bcfc5
Arg [14] : 0000000000000000000000009a016ce184a22dbf6c17daa59eb7d3140dbd1c54
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [16] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [19] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [20] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [24] : 6164640000000000000000000000000000000000000000000000000000000000
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [26] : 72656d6f76650000000000000000000000000000000000000000000000000000
Arg [27] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [28] : 7377617000000000000000000000000000000000000000000000000000000000
Arg [29] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [30] : 756e6c6f636b0000000000000000000000000000000000000000000000000000
Arg [31] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [32] : 616464457874656e73696f6e0000000000000000000000000000000000000000
Arg [33] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [34] : 72656d6f7665457874656e73696f6e0000000000000000000000000000000000
Arg [35] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [36] : 7265676973746572417373657400000000000000000000000000000000000000
Arg [37] : 000000000000000000000000000000000000000000000000000000000000005c
Arg [38] : 0400000000000000143dfccb7b8a6972cde3b695d3c0c032514b0f3825144c46
Arg [39] : e1f946362547546677bfa719598385ce56f214f81f676832f6dfec4a5d0671bd
Arg [40] : 27156425fcef981451b7529137d34002c4ebd81a2244f0ee7e95b2c000000000
Deployed Bytecode Sourcemap
57097:14652:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57097:14652:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55594:39;;;:::i;:::-;;;;;;;;;;;;;;;;61001:2120;;;;;;;;;:::i;:::-;;;;;;;;59259:1391;;;;;;;;;:::i;56221:347::-;;;:::i;52072:78::-;;;:::i;56945:145::-;;;;;;;;;:::i;54776:140::-;;;:::i;:::-;;57210:53;;;;;;;;;:::i;57328:45::-;;;;;;;;;:::i;58600:286::-;;;;;;;;;:::i;56652:281::-;;;;;;;;;:::i;55868:341::-;;;:::i;57380:47::-;;;;;;;;;:::i;53965:79::-;;;:::i;54331:94::-;;;:::i;55640:21::-;;;:::i;:::-;;;;;;;;57270:51;;;;;;;;;:::i;63544:1804::-;;;;;;;;;:::i;66040:3853::-;;;;;;;;;:::i;55071:110::-;;;;;;;;;:::i;55594:39::-;;;-1:-1:-1;;;;;55594:39:0;;:::o;61001:2120::-;61127:4;52309:7;;-1:-1:-1;;;52309:7:0;;;;52308:8;52300:37;;;;-1:-1:-1;;;52300:37:0;;;;;;;;;;;;;;;;;61196:29;;:::i;:::-;61228:37;61255:9;61228:26;:37::i;:::-;61196:69;;61276:23;61321:24;;;;;;;;;-1:-1:-1;;;;;61321:24:0;61276:70;;61457:26;61486:4;-1:-1:-1;;;;;61486:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61486:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61486:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;61486:29:0;;;;;;;;;61457:58;;;;61550:19;-1:-1:-1;;;;;61534:35:0;:6;:13;;;:35;;;61526:110;;;;-1:-1:-1;;;61526:110:0;;;;;;;;;61805:21;;;;-1:-1:-1;;61805:35:0;61797:85;;;;-1:-1:-1;;;61797:85:0;;;;;;;;;61967:29;61999:61;62027:4;-1:-1:-1;;;;;62027:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62027:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62027:32:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;62027:32:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;62027:32:0;;;;;;;;;61999:27;:61::i;:::-;62080:19;;61967:93;;-1:-1:-1;62118:69:0;62137:9;62148:7;61967:93;62185:1;-1:-1:-1;;62176:5:0;;62175:11;;62171:1;:15;62118:18;:69::i;:::-;62110:106;;;;-1:-1:-1;;;62110:106:0;;;;;;;;;62418:22;62442:24;62470:33;62492:10;62470:21;:33::i;:::-;62417:86;;;;62547:14;-1:-1:-1;;;;;62522:39:0;;:6;:21;;;-1:-1:-1;;;;;62522:39:0;;;62514:71;;;;-1:-1:-1;;;62514:71:0;;;;;;;;;62759:13;;;;62731:42;;-1:-1:-1;;;62731:42:0;;-1:-1:-1;;;;;62731:27:0;;;;;:42;;62759:13;62731:42;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62731:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62731:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62731:42:0;;;;;;;;;62723:100;;;;-1:-1:-1;;;62723:100:0;;;;;;;;;62842:4;-1:-1:-1;;;;;62842:30:0;;62873:34;62899:7;62873:25;:34::i;:::-;62842:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62842:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62842:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62842:66:0;;;;;;;;;62834:138;;;;-1:-1:-1;;;62834:138:0;;;;;;;;;63044:47;63066:6;:13;;;63081:9;63044:47;;;;;;;;;;;;;;;;63109:4;63102:11;;;;;;;;;52348:1;61001:2120;;;;;:::o;59259:1391::-;59363:4;52309:7;;-1:-1:-1;;;52309:7:0;;;;52308:8;52300:37;;;;-1:-1:-1;;;52300:37:0;;;;;;;;;59477:24;;59598:32;;;-1:-1:-1;;;59598:32:0;;;;-1:-1:-1;;;;;59477:24:0;;;;;;59598:30;;:32;;;;;59432:23;;59598:32;;;;;;;59477:24;59598:32;;;5:2:-1;;;;30:1;27;20:12;5:2;59598:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59598:32:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59598:32:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59598:32:0;;;;;;;;;:39;:44;59590:113;;;;-1:-1:-1;;;59590:113:0;;;;;;;;;59874:29;;:::i;:::-;59906:37;59933:9;59906:26;:37::i;:::-;59874:69;;59955:22;59979:24;60007:33;60029:10;60007:21;:33::i;:::-;59954:86;;;;60084:14;-1:-1:-1;;;;;60059:39:0;;:6;:21;;;-1:-1:-1;;;;;60059:39:0;;;60051:71;;;;-1:-1:-1;;;60051:71:0;;;;;;;;;60277:13;;;;60249:42;;-1:-1:-1;;;60249:42:0;;-1:-1:-1;;;;;60249:27:0;;;;;:42;;60277:13;60249:42;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60249:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60249:42:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;60249:42:0;;;;;;;;;60241:122;;;;-1:-1:-1;;;60241:122:0;;;;;;;;;60382:4;-1:-1:-1;;;;;60382:30:0;;60413:34;60439:7;60413:25;:34::i;:::-;60382:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60382:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60382:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;60382:66:0;;;;;;;;;60374:146;;;;-1:-1:-1;;;60374:146:0;;;;;;;;;60573:47;60595:6;:13;;;60610:9;60573:47;;;;;;;;;;;;;;;;60638:4;60631:11;;;;;;52348:1;59259:1391;;;;:::o;56221:347::-;56266:4;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;56287:8;:6;:8::i;:::-;56283:51;;;56312:10;:8;:10::i;:::-;56389:24;;56429:13;;;-1:-1:-1;;;56429:13:0;;;;-1:-1:-1;;;;;56389:24:0;;;;;;56429:11;;:13;;;;;;;;;;;;;;56389:24;56429:13;;;5:2:-1;;;;30:1;27;20:12;5:2;56429:13:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56429:13:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56429:13:0;;;;;;;;;56425:114;;;56467:4;-1:-1:-1;;;;;56467:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56467:14:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56467:14:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56467:14:0;;;;;;;;;56459:68;;;;-1:-1:-1;;;56459:68:0;;;;;;;;;56556:4;56549:11;;;56221:347;:::o;52072:78::-;52111:4;52135:7;-1:-1:-1;;;52135:7:0;;;;;52072:78::o;56945:145::-;57022:4;52508:7;;-1:-1:-1;;;52508:7:0;;;;52500:40;;;;-1:-1:-1;;;52500:40:0;;;;;;;;;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;-1:-1:-1;57039:7:0;:21;;-1:-1:-1;;;;57039:21:0;-1:-1:-1;;;;;;;;57039:21:0;;;;;;54234:1;56945:145;;;:::o;54776:140::-;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;54875:1;54859:6;;54838:40;;-1:-1:-1;;;;;54859:6:0;;;;54838:40;;54875:1;;54838:40;54906:1;54889:19;;-1:-1:-1;;;;;;54889:19:0;;;54776:140::o;57210:53::-;;;;;;;;;;;;;;;:::o;57328:45::-;22:14:-1;;169:4;143:32;;;;;198:20;;57328:45:0;224:31:-1;;156:18;;;283;;;;273:49;328:32;;57328:45:0;;;;:::o;58600:286::-;58677:17;58695:12;58677:31;;;;;;;;;;;;;;;;;;;;;;;;58669:64;;;;-1:-1:-1;;;58669:64:0;;;;;;;;;58778:5;58744:17;58762:12;58744:31;;;;;;;;;;;;;;;;;;;;;:39;;;;;-1:-1:-1;;58744:39:0;;;;;;;;;;;58813:24;-1:-1:-1;;;58794:84:0;;-1:-1:-1;;;;;58813:24:0;;58794:70;;:84;;58865:12;;58794:84;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58794:84:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58794:84:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;58794:84:0;;;;;;;;;;58600:286;:::o;56652:281::-;56751:4;52508:7;;-1:-1:-1;;;52508:7:0;;;;52500:40;;;;-1:-1:-1;;;52500:40:0;;;;;;;;;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;56813:24;;56849:54;;-1:-1:-1;;;56849:54:0;;-1:-1:-1;;;;;56813:24:0;;;;;;56849:22;;:54;;56872:30;;56849:54;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56849:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;56921:4:0;;56652:281;-1:-1:-1;;;;;;56652:281:0:o;55868:341::-;55911:4;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;55933:8;:6;:8::i;:::-;55928:50;;55958:8;:6;:8::i;:::-;56033:24;;56074:13;;;-1:-1:-1;;;56074:13:0;;;;-1:-1:-1;;;;;56033:24:0;;;;;;56074:11;;:13;;;;;;;;;;;;;;56033:24;56074:13;;;5:2:-1;;;;30:1;27;20:12;5:2;56074:13:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56074:13:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56074:13:0;;;;;;;;;56069:111;;56112:4;-1:-1:-1;;;;;56112:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56112:12:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56112:12:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;56112:12:0;;;;;;;;;56104:64;;;;-1:-1:-1;;;56104:64:0;;;;;;;;57380:47;22:14:-1;;169:4;143:32;;;;;198:20;;57380:47:0;224:31:-1;;156:18;;;283;;;;273:49;328:32;;57380:47:0;;;;:::o;53965:79::-;54003:7;54030:6;-1:-1:-1;;;;;54030:6:0;53965:79;:::o;54331:94::-;54371:4;54411:6;;-1:-1:-1;;;;;54411:6:0;54395:12;:10;:12::i;:::-;-1:-1:-1;;;;;54395:22:0;;54388:29;;54331:94;:::o;55640:21::-;;;-1:-1:-1;;;55640:21:0;;-1:-1:-1;;;;;55640:21:0;;:::o;57270:51::-;;;;;;;;;;;;;;;:::o;63544:1804::-;63687:4;52309:7;;-1:-1:-1;;;52309:7:0;;;;52308:8;52300:37;;;;-1:-1:-1;;;52300:37:0;;;;;;;;;63784:10;63762:33;;;;:21;:33;;;;;;;;63754:66;;;;-1:-1:-1;;;63754:66:0;;;;;;;;;63938:24;;64096;;;-1:-1:-1;;;;;;64096:24:0;;;;-1:-1:-1;;;;;63938:24:0;;;;63893:23;;63938:24;;64096:22;;:24;;;;;;;;;;;;;;;63938;64096;;;5:2:-1;;;;30:1;27;20:12;5:2;64096:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64096:24:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64096:24:0;;;;;;;;;64074:46;;64184:24;64211:33;64232:11;64211:20;:33::i;:::-;64184:60;;64373:21;64414:39;64441:11;64414:26;:39::i;:::-;64468:98;64512:52;64544:4;64551:11;64519:44;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;64519:44:0;;;;64512:52;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64512:52:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64512:52:0;;;;;;;;;64495:70;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;64495:70:0;;;64468:26;:98::i;:::-;64581:60;64608:32;64629:10;64608:20;:32::i;:::-;64581:26;:60::i;:::-;64656:35;64681:9;64656:24;:35::i;:::-;64706:38;64733:10;;64706:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;64706:26:0;;-1:-1:-1;;;64706:38:0:i;:::-;64759:34;64786:6;;64759:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;64759:26:0;;-1:-1:-1;;;64759:34:0:i;:::-;64808;64835:6;;64808:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;64808:26:0;;-1:-1:-1;;;64808:34:0:i;:::-;64397:456;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;64397:456:0;;;;64984:19;;49:4:-1;64984:19:0;;;-1:-1:-1;;;64966:38:0;;64397:456;;-1:-1:-1;;;;;;64966:17:0;;;;;:38;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64966:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64966:38:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;64966:38:0;;;;;;;;;64958:99;;;;-1:-1:-1;;;64958:99:0;;;;;;;;;65250:9;-1:-1:-1;;;;;65234:84:0;;65261:11;65274:10;65286:9;65297:10;;65309:8;65234:84;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65336:4:0;;63544:1804;-1:-1:-1;;;;;;;;;;;63544:1804:0:o;66040:3853::-;66224:4;52309:7;;-1:-1:-1;;;52309:7:0;;;;52308:8;52300:37;;;;-1:-1:-1;;;52300:37:0;;;;;;;;;66240:29;;:::i;:::-;66272:37;66299:9;66272:26;:37::i;:::-;66240:69;;66371:23;66416:24;;;;;;;;;-1:-1:-1;;;;;66416:24:0;66371:70;;66607:29;66639:61;66667:4;-1:-1:-1;;;;;66667:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;66639:61:0;66607:93;;66713:27;66743:4;-1:-1:-1;;;;;66743:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66743:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66743:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;66743:29:0;;;;;;;;;66713:59;;;;66785:6;66794:12;:19;66785:28;;66845:19;66828:6;:13;;;:36;;;66824:900;;66947:72;66966:9;66977;66988:12;67017:1;-1:-1:-1;;67008:5:0;;67006:12;;66947:72;66939:127;;;;-1:-1:-1;;;66939:127:0;;;;;;;;;66824:900;;;67169:75;67188:12;67202:9;67213:12;67242:1;-1:-1:-1;;67233:5:0;;67231:12;;67169:75;67161:144;;;;-1:-1:-1;;;67161:144:0;;;;;;;;;67418:32;;:::i;:::-;67453:40;67480:12;67453:26;:40::i;:::-;67418:75;;67508:23;67534:54;67555:11;67568:9;:19;;;67534:20;:54::i;:::-;67508:80;;67648:32;67669:10;67648:20;:32::i;:::-;67611:33;67634:9;67611:22;:33::i;:::-;:69;67603:109;;;;-1:-1:-1;;;67603:109:0;;;;;;;;;66824:900;;;67866:28;67897:51;67918:5;67925:6;:22;;;67897:20;:51::i;:::-;67866:82;;68088:43;;:::i;:::-;68134:48;68166:15;68134:31;:48::i;:::-;68088:94;;68202:4;-1:-1:-1;;;;;68202:28:0;;68231:13;:25;;;68258:42;68279:13;:20;;;68258;:42::i;:::-;68202:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68202:99:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68202:99:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68202:99:0;;;;;;;;;68201:100;68193:147;;;;-1:-1:-1;;;68193:147:0;;;;;;;;;68359:4;-1:-1:-1;;;;;68359:25:0;;68385:13;:25;;;68412:42;68433:13;:20;;;68412;:42::i;:::-;68359:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68359:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68359:96:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68359:96:0;;;;;;;;;68351:141;;;;-1:-1:-1;;;68351:141:0;;;;;;;;;68652:7;;68613:25;;;;:35;;;-1:-1:-1;;;;;68613:46:0;;;-1:-1:-1;;;68652:7:0;;;;68613:46;68605:97;;;;-1:-1:-1;;;68605:97:0;;;;;;;;;68875:18;68896:58;68917:13;:25;;;:36;;;68896:20;:58::i;:::-;-1:-1:-1;;;;;69050:31:0;;;;;;:19;:31;;;;;;68875:79;;-1:-1:-1;69050:31:0;;69042:62;;;;-1:-1:-1;;;69042:62:0;;;;;;;;;69123:15;69139:13;:25;;;:32;;;69123:49;;;;;;;;;;;;;;;;;;;;;;;;69115:75;;;;-1:-1:-1;;;69115:75:0;;;;;;;;;69310:165;69331:10;69343:13;:25;;;:32;;;69377:13;:25;;;:30;;;69409:13;:25;;;:38;;;69449:13;:25;;;69310:20;:165::i;:::-;69302:207;;;;-1:-1:-1;;;69302:207:0;;;;;;;;;69741:25;;;;69768;;;;;:36;;;;69806:20;;69828:32;;69711:150;;;;;;69741:25;;69806:20;69711:150;;;;;;;;;;69881:4;69874:11;;;;;;;;;;52348:1;66040:3853;;;;;;;:::o;55071:110::-;54177:9;:7;:9::i;:::-;54169:54;;;;-1:-1:-1;;;54169:54:0;;;;;;;;;55145:28;55164:8;55145:18;:28::i;:::-;55071:110;:::o;41685:1080::-;41759:13;;:::i;:::-;41785:20;;:::i;:::-;41816:11;41867:41;41893:9;41816:11;41867:25;:41::i;:::-;41842:66;;;;;;;-1:-1:-1;41945:41:0;41971:9;41842:66;41945:25;:41::i;:::-;-1:-1:-1;;;;;41921:65:0;;;41922:14;;;41921:65;;-1:-1:-1;42029:39:0;42053:9;41921:65;42029:23;:39::i;:::-;42000:20;;;41999:69;;;;;-1:-1:-1;42114:39:0;42138:9;41999:69;42114:23;:39::i;:::-;42082:23;;;42081:72;;;;;-1:-1:-1;42198:39:0;42222:9;42081:72;42198:23;:39::i;:::-;42167:22;;;42166:71;;;;;-1:-1:-1;42276:39:0;42300:9;42166:71;42276:23;:39::i;:::-;42251:16;;;42250:65;;;;;-1:-1:-1;42354:41:0;42380:9;42250:65;42354:25;:41::i;:::-;42328:67;;;;42329:16;;;42328:67;;-1:-1:-1;42431:41:0;42457:9;42328:67;42431:25;:41::i;:::-;42408:64;;;;42409:13;;;42408:64;;-1:-1:-1;42515:41:0;42541:9;42408:64;42515:25;:41::i;:::-;-1:-1:-1;;;;;42485:71:0;;;42486:20;;;42485:71;;-1:-1:-1;42602:43:0;42630:9;42485:71;42602:27;:43::i;:::-;42570:23;;;42569:76;;;;;-1:-1:-1;42689:42:0;42716:9;42569:76;42689:26;:42::i;:::-;-1:-1:-1;;;42658:73:0;42659:21;;;42658:73;-1:-1:-1;42659:21:0;41685:1080;-1:-1:-1;;41685:1080:0:o;39693:554::-;39771:16;39800:11;;39872:44;39898:12;39800:11;39872:25;:44::i;:::-;39853:63;;;;;;;;39927:24;39968:9;-1:-1:-1;;;;;39954:24:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;39954:24:0;-1:-1:-1;39927:51:0;-1:-1:-1;39989:24:0;40028:6;40024:191;40044:9;-1:-1:-1;;;;;40040:13:0;:1;:13;40024:191;;;40096:46;40124:12;40138:3;40096:27;:46::i;:::-;40075:67;-1:-1:-1;40075:67:0;-1:-1:-1;40170:33:0;40075:67;40170:20;:33::i;:::-;40157:7;40165:1;40157:10;;;;;;;;-1:-1:-1;;;;;40157:46:0;;;:10;;;;;;;;;;;:46;40055:3;;40024:191;;;-1:-1:-1;40232:7:0;;39693:554;-1:-1:-1;;;;;39693:554:0:o;37932:846::-;38058:4;38074:12;38089:25;38103:10;38089:13;:25::i;:::-;38074:40;;38127:13;38143:44;34271:2;38143:8;:15;:19;;:44;;;;:::i;:::-;38127:60;;38198:24;38239:8;38225:23;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;38225:23:0;-1:-1:-1;38198:50:0;-1:-1:-1;38259:9:0;;;;38317:390;38338:8;38333:1;:13;38317:390;;;38371:74;38392:52;38404:8;34271:2;38414:1;:25;38441:2;38392:11;:52::i;:::-;38371:20;:74::i;:::-;38367:78;;38465:79;38486:57;38498:8;34271:2;38508:1;:25;38536:2;38508:30;38540:2;38486:11;:57::i;38465:79::-;38460:84;;38570:8;34271:2;38579:1;:25;38607:2;38579:30;38570:40;;;;;;;;;;;;;;;;38564:47;;38614:2;38564:52;38559:57;;38645:50;38655:30;38679:4;38662:22;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;38662:22:0;;;;38655:30;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38655:30:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;38655:30:0;;;;;;;;;38687:1;38690;38693;38645:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38645:50:0;;;;;;;;38631:7;38639:1;38631:10;;;;;;;;-1:-1:-1;;;;;38631:64:0;;;:10;;;;;;;;;;;:64;38348:3;;38317:390;;;;38724:46;38748:8;38758:7;38767:2;38724:23;:46::i;:::-;38717:53;;;;;;;;37932:846;;;;;;;:::o;37149:381::-;37220:7;37229:16;34222:2;37266:11;:18;:41;;;;;;:46;37258:86;;;;-1:-1:-1;;;37258:86:0;;;;;;;;;37355:6;34222:2;37364:11;:18;:41;;;;;;37355:50;;37429:1;37424;:6;;37416:41;;;;-1:-1:-1;;;37416:41:0;;;;;;;;;37475:47;37490:1;37507;-1:-1:-1;;37498:5:0;;37497:11;37493:1;:15;37510:11;37475:14;:47::i;:::-;37468:54;;;;;37149:381;;;:::o;39023:434::-;39143:14;;39098:12;;;39196:43;39143:14;39196:24;:43::i;:::-;39168:71;-1:-1:-1;39254:6:0;39250:170;39270:9;39266:1;:13;39250:170;;;39333:12;39347:60;39374:32;39395:7;39403:1;39395:10;;;;;;;;;;;;;;39374:20;:32::i;39347:60::-;39316:92;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;39316:92:0;;;;-1:-1:-1;39281:3:0;;39250:170;;;-1:-1:-1;39437:12:0;39023:434;-1:-1:-1;;;39023:434:0:o;52833:112::-;52508:7;;-1:-1:-1;;;52508:7:0;;;;52500:40;;;;-1:-1:-1;;;52500:40:0;;;;;;;;;52894:5;52884:15;;-1:-1:-1;;;;52884:15:0;;;52915:22;52924:12;:10;:12::i;:::-;52915:22;;;;;;;;;;;;;;;52833:112::o;52640:110::-;52309:7;;-1:-1:-1;;;52309:7:0;;;;52308:8;52300:37;;;;-1:-1:-1;;;52300:37:0;;;;;;;;;52692:7;:14;;-1:-1:-1;;;;52692:14:0;-1:-1:-1;;;52692:14:0;;;52722:20;52729:12;51179:98;51259:10;51179:98;:::o;1322:772::-;1385:15;-1:-1:-1;;;;;1421:6:0;:76;;1413:112;;;;-1:-1:-1;;;1413:112:0;;;;;;;;;1701:4;1695:11;1689:17;;1813:4;1809:2;1802:16;1934:6;1927:4;1923:2;1919:13;1912:29;2070:4;2066:2;2062:13;2056:4;2049:27;1545:542;;;:::o;19512:185::-;19620:11;;19577:12;;19667:15;19620:11;19667:12;:15::i;:::-;19684:4;19650:39;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;19650:39:0;;;19643:46;;;19512:185;;;:::o;2885:690::-;3139:4;3133:11;;3271:4;3260:16;;2947:15;3408:14;;;;3401:4;3393:13;;3386:37;3544:13;;;3531:27;;3133:11;2983:585::o;17803:622::-;17948:4;17942:11;17982:4;18000:21;;;17856:12;;17942:11;18072:4;18108;18035:307;18139:7;18131:6;18128:19;18035:307;;;18324:1;18316:6;18311:15;18302:6;18295:4;18289;18285:15;18281:28;18273:54;18189:4;18177:17;;;;;-1:-1:-1;;18222:17:0;18035:307;;;-1:-1:-1;;;18379:4:0;18369:15;;18363:4;18356:29;18369:15;17803:622;-1:-1:-1;;17803:622:0:o;34555:991::-;34639:12;34664:11;34639:12;34735:44;34763:10;34664:11;34735:27;:44::i;:::-;34719:60;-1:-1:-1;34719:60:0;-1:-1:-1;34792:12:0;34807:21;34719:60;34807:14;:21::i;:::-;34792:36;;34839:9;34851:34;34882:2;34851:26;34873:3;34851:10;:17;:21;;:26;;;;:::i;:::-;:30;:34;:30;:34;:::i;:::-;34839:46;-1:-1:-1;34896:16:0;;;34942:488;34963:4;34959:1;:8;34942:488;;;35002:40;35026:10;35038:3;35002:23;:40::i;:::-;34989:53;-1:-1:-1;34989:53:0;-1:-1:-1;35075:40:0;35099:10;34989:53;35075:23;:40::i;:::-;35057:58;-1:-1:-1;35057:58:0;-1:-1:-1;;;;;;;35134:11:0;;35130:289;;35173:34;35192:8;35202:4;35173:18;:34::i;:::-;35166:41;;35130:289;;;-1:-1:-1;;;;;;;;;35233:11:0;;;35229:190;;;35272:34;35291:4;35297:8;35272:18;:34::i;35229:190::-;35347:56;;-1:-1:-1;;;35347:56:0;;;;;;;;35229:190;34969:3;;34942:488;;;;35456:5;35448:4;:13;35440:75;;;;-1:-1:-1;;;35440:75:0;;;;;;;;;-1:-1:-1;35533:5:0;;34555:991;-1:-1:-1;;;;;;;34555:991:0:o;258:347::-;323:13;357:3;:10;371:2;357:16;349:52;;;;-1:-1:-1;;;349:52:0;;;;;;;;;-1:-1:-1;581:4:0;572:14;566:21;;421:177::o;42973:148::-;43043:7;43070:43;43094:17;43101:9;43094:17;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43094:17:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;43094:17:0;;;;;;;;;43077:35;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;43077:35:0;;;;43070:43;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43070:43:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;43070:43:0;;;;;;;;40452:1042;40530:20;;:::i;:::-;40563:34;;:::i;:::-;40608:11;40666:42;40694:8;40608:11;40666:27;:42::i;:::-;40636:72;;;;-1:-1:-1;40756:40:0;40782:8;40636:72;40756:25;:40::i;:::-;-1:-1:-1;;;;;40721:75:0;;;40722:25;;;40721:75;;-1:-1:-1;40809:22:0;;:::i;:::-;40868:42;40896:8;40906:3;40868:27;:42::i;:::-;40844:66;;;;-1:-1:-1;40961:42:0;40989:8;40844:66;40961:27;:42::i;:::-;40932:20;;;40931:72;;;;;-1:-1:-1;41046:42:0;41074:8;40931:72;41046:27;:42::i;:::-;41017:20;;;41016:72;;;;;-1:-1:-1;41128:40:0;41154:8;41016:72;41128:25;:40::i;:::-;-1:-1:-1;;;;;41101:67:0;;;41102:17;;;41101:67;;-1:-1:-1;41209:42:0;41237:8;41101:67;41209:27;:42::i;:::-;41182:18;;;41181:70;;;;;-1:-1:-1;41288:42:0;41316:8;41181:70;41288:27;:42::i;:::-;41265:14;;;41264:66;;;;;-1:-1:-1;41365:42:0;41393:8;41264:66;41365:27;:42::i;:::-;-1:-1:-1;41344:12:0;;;41343:64;41418:25;;;:35;-1:-1:-1;41418:25:0;40452:1042;-1:-1:-1;;40452:1042:0:o;2272:447::-;2337:12;2375:3;:10;2389:2;2375:16;2367:64;;;;-1:-1:-1;;;2367:64:0;;;;;;;;;-1:-1:-1;2693:4:0;2684:14;2678:21;;2451:259::o;70563:1183::-;70727:4;70868:29;70885:11;70868:16;:29::i;:::-;70860:82;;;;-1:-1:-1;;;70860:82:0;;;;;;;;;70953:23;70987:12;71114:11;-1:-1:-1;;;;;71114:16:0;71182:7;71165:49;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;71165::0;;;71155:60;;;;;;71229:5;71236:17;71255:12;71218:50;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;71218:50:0;;;;71131:138;;;49:4:-1;71131:138:0;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;71131:138:0;;;;71114:156;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;71090:180:0;-1:-1:-1;71090:180:0;-1:-1:-1;71359:4:0;71348:15;;;;71340:71;;;;-1:-1:-1;;;71340:71:0;;;;;;;;;71486:17;;71478:74;;;;-1:-1:-1;;;71478:74:0;;;;;;;;;71564:8;71577:39;71601:10;71613:2;71577:23;:39::i;:::-;-1:-1:-1;71563:53:0;-1:-1:-1;71642:4:0;71635:11;;;;71627:79;;;;-1:-1:-1;;;71627:79:0;;;;;;;;;-1:-1:-1;71734:4:0;;70563:1183;-1:-1:-1;;;;;;;;70563:1183:0:o;55287:229::-;-1:-1:-1;;;;;55361:22:0;;55353:73;;;;-1:-1:-1;;;55353:73:0;;;;;;;;;55463:6;;;55442:38;;-1:-1:-1;;;;;55442:38:0;;;;55463:6;;;55442:38;;;55491:6;:17;;-1:-1:-1;;;;;;55491:17:0;-1:-1:-1;;;;;55491:17:0;;;;;;;;;;55287:229::o;24475:875::-;24553:6;24561:7;24603:4;:11;24589:6;24598:1;24589:10;:25;;:48;;;;;24627:6;24636:1;24627:10;24618:6;:19;24589:48;24581:95;;;;-1:-1:-1;;;24581:95:0;;;;;;;;;24687:8;24752:4;24746:11;24786:4;24841;24890;24881:7;24877:18;24954:6;24947:4;24941;24937:15;24933:28;24927:35;24804:386;24989:7;24981:6;24978:19;24804:386;;;25167:6;25159;25154:20;25145:6;25135:8;25131:21;25123:52;25039:4;25031:6;25027:17;25017:27;;25084:4;25076:6;25072:17;25062:27;;24804:386;;;-1:-1:-1;;;25217:22:0;;;25211:4;25204:36;25283:4;25279:18;25265:33;;25259:40;;-1:-1:-1;;;25340:1:0;25331:10;;24475:875;;;;;;:::o;25649:::-;25727:6;25735:7;25777:4;:11;25763:6;25772:1;25763:10;:25;;:48;;;;;25801:6;25810:1;25801:10;25792:6;:19;25763:48;25755:95;;;;-1:-1:-1;;;25755:95:0;;;;;;;;;25861:8;25926:4;25920:11;25960:4;26015;26064;26055:7;26051:18;26128:6;26121:4;26115;26111:15;26107:28;26101:35;25978:386;26163:7;26155:6;26152:19;25978:386;;;26341:6;26333;26328:20;26319:6;26309:8;26305:21;26297:52;26213:4;26205:6;26201:17;26191:27;;26258:4;26250:6;26246:17;26236:27;;25978:386;;;-1:-1:-1;;;26391:22:0;;;26385:4;26378:36;26457:4;26453:18;26439:33;;26433:40;;26514:1;26505:10;;;;;-1:-1:-1;;;;25649:875:0:o;31199:348::-;31275:7;31285;31328:4;:11;31313:6;31322:2;31313:11;:26;;:50;;;;;31352:6;31361:2;31352:11;31343:6;:20;31313:50;31305:95;;;;-1:-1:-1;;;31305:95:0;;;;;;;;;-1:-1:-1;;31488:4:0;31466:28;;;;;31460:35;;31476:17;;;31199:348::o;28263:2656::-;28342:12;28356:7;28376:8;28411:25;28423:4;28429:6;28411:11;:25::i;:::-;28471:11;;28395:41;;-1:-1:-1;28395:41:0;;-1:-1:-1;28455:12:0;;;:27;;;;:52;;;28504:3;28495:6;:12;28486:6;:21;28455:52;28447:101;;;;-1:-1:-1;;;28447:101:0;;;;;;;;;28559:22;28622:11;;28647:1991;;;;30782:4;30776:11;30763:24;;30835:4;30824:9;30820:20;30814:4;30807:34;28615:2241;;28647:1991;28832:4;28826:11;28813:24;;29497:2;29492:3;29488:12;29885:9;29878:17;29872:4;29868:28;29856:9;29845;29841:25;29837:60;29934:3;29930:2;29926:12;30185:6;30171:9;30164:17;30158:4;30154:28;30142:9;30136:4;30132:20;30128:55;30124:68;29958:432;30219:3;30215:2;30212:11;29958:432;;;30361:9;;30350:21;;30261:4;30253:13;;;;30294;29958:432;;;-1:-1:-1;;30410:22:0;;;30618:2;30601:11;-1:-1:-1;;30597:25:0;30591:4;30584:39;-1:-1:-1;28615:2241:0;-1:-1:-1;30887:9:0;30898:12;;;-1:-1:-1;;;28263:2656:0:o;31829:354::-;31908:7;31918;31961:4;:11;31946:6;31955:2;31946:11;:26;;:50;;;;;31985:6;31994:2;31985:11;31976:6;:20;31946:50;31938:98;;;;-1:-1:-1;;;31938:98:0;;;;;;;;;-1:-1:-1;;32102:28:0;;;32124:4;32102:28;32096:35;32172:2;32163:11;;31829:354;;;;;:::o;46269:132::-;46327:7;46354:39;46358:1;46361;46354:39;;;;;;;;;;;;;;;;;:3;:39::i;8380:2645::-;8527:12;8592:7;8583:6;:16;8565:6;:13;:35;;8557:44;;;;;;8614:22;8680:15;;8709:2051;;;;10904:4;10898:11;10885:24;;10957:4;10946:9;10942:20;10936:4;10929:34;8673:2305;;8709:2051;8894:4;8888:11;8875:24;;9609:2;9600:7;9596:16;9997:9;9990:17;9984:4;9980:28;9968:9;9957;9953:25;9949:60;10046:7;10042:2;10038:16;10303:6;10289:9;10282:17;10276:4;10272:28;10260:9;10252:6;10248:22;10244:57;10240:70;10074:434;10337:3;10333:2;10330:11;10074:434;;;10479:9;;10468:21;;10379:4;10371:13;;;;10412;10074:434;;;-1:-1:-1;;10528:26:0;;;10740:2;10723:11;-1:-1:-1;;10719:25:0;10713:4;10706:39;-1:-1:-1;8673:2305:0;-1:-1:-1;11008:9:0;8380:2645;-1:-1:-1;;;;8380:2645:0:o;11433:445::-;11546:4;;;11583:263;11603:8;:15;11599:1;:19;11583:263;;;11644:6;11639:196;11660:8;:15;11656:1;:19;11639:196;;;11720:8;11729:1;11720:11;;;;;;;;;;;;;;-1:-1:-1;;;;;11705:26:0;:8;11714:1;11705:11;;;;;;;;;;;;;;-1:-1:-1;;;;;11705:26:0;;11701:119;;;11756:3;;;;;;;11789:8;11798:1;11789:11;;;;;;;;;;;;;11782:18;-1:-1:-1;;;;;11782:18:0;;;;11701:119;11677:3;;11639:196;;;-1:-1:-1;11620:3:0;;11583:263;;;-1:-1:-1;;;;11863:7:0;;11433:445;-1:-1:-1;;;11433:445:0:o;35904:929::-;36000:7;36009:16;36038:17;36074:41;36106:7;36074:24;:41::i;:::-;36067:48;;36127:24;36168:7;36154:22;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;36154:22:0;-1:-1:-1;36127:49:0;-1:-1:-1;36188:12:0;36212:22;36188:12;36246:376;36266:7;36262:1;:11;36246:376;;;36307:70;36319:11;34222:2;36332:1;:22;34222:2;36307:11;:70::i;:::-;36295:82;;36418:4;36424:61;36451:33;36474:9;36451:22;:33::i;36424:61::-;36401:85;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36401:85:0;;;36393:93;;36519:29;36531:9;36542:1;36545:2;36519:11;:29::i;:::-;36509:40;;;;;;36502:47;;36602:4;36594:13;;36565:7;36573:1;36565:10;;;;;;;;-1:-1:-1;;;;;36565:44:0;;;:10;;;;;;;;;;;:44;36275:3;;36246:376;;;;36659:4;36665:36;36697:2;36665:24;:36::i;:::-;36642:60;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36642:60:0;;;36635:67;;36714:23;36740:41;36767:12;36774:4;36767:12;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36767:12:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;36767:12:0;;;;;;;;;36750:30;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;36750:30:0;;;;36740:41;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;36740:41:0;;;;;;36817:7;;-1:-1:-1;35904:929:0;;-1:-1:-1;;;;;;;;;35904:929:0:o;19705:453::-;19760:12;19793:4;19789:1;-1:-1:-1;;;;;19789:8:0;;19785:366;;;19814:20;19831:1;19814:10;:20::i;:::-;19807:27;;;;19785:366;19858:6;19853:1;-1:-1:-1;;;;;19853:11:0;;19849:302;;19899:15;-1:-1:-1;;;19899:9:0;:15::i;:::-;19916:22;19935:1;19916:11;:22::i;:::-;19882:57;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;19882:57:0;;;19875:64;;;;19849:302;19963:10;19958:1;-1:-1:-1;;;;;19958:15:0;;19954:197;;20014:15;-1:-1:-1;;;20014:9:0;:15::i;:::-;20031:22;20050:1;20031:11;:22::i;19954:197::-;20102:15;-1:-1:-1;;;;;;20102:9:0;:15::i;:::-;20119:22;20138:1;20119:11;:22::i;3755:148::-;3816:14;3853:42;3882:3;3877:9;;3888:5;3860:34;;;;;;;;;;44414:136;44472:7;44499:43;44503:1;44506;44499:43;;;;;;;;;;;;;;;;;:3;:43::i;22115:337::-;22191:4;22197:7;22239:4;:11;22225:6;22234:1;22225:10;:25;;:48;;;;;22263:6;22272:1;22263:10;22254:6;:19;22225:48;22217:93;;;;-1:-1:-1;;;22217:93:0;;;;;;;;;-1:-1:-1;;22372:28:0;;;22386:4;22372:28;22366:35;22442:1;22433:10;;22115:337;;;;;:::o;4112:161::-;4182:14;4219:46;4250:4;4243:12;;4257:2;4261;4226:38;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;4226:38:0;;;;4219:46;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;4219:46:0;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;4219:46:0;;;;;;;;12921:810;12981:4;13640:20;;13483:66;13680:15;;;;;:42;;-1:-1:-1;13699:23:0;;;13672:51;-1:-1:-1;;12921:810:0:o;21282:556::-;21357:4;21363:7;21405:4;:11;21391:6;21400:1;21391:10;:25;;:48;;;;;21429:6;21438:1;21429:10;21420:6;:19;21391:48;21383:81;;;;-1:-1:-1;;;21383:81:0;;;;;;;;;21554:28;;;21568:4;21554:28;21548:35;21503:6;-1:-1:-1;;;;;;;;;21629:9:0;;;21625:169;;;-1:-1:-1;21657:4:0;21625:169;;;-1:-1:-1;;;;;;21680:9:0;;21676:118;;-1:-1:-1;21714:5:0;21676:118;;;21752:30;;-1:-1:-1;;;21752:30:0;;;;;;;;21676:118;21812:5;21828:1;21819:10;;;;;-1:-1:-1;;;;21282:556:0:o;32195:1186::-;32273:4;32279:7;32299:6;32330:22;32339:4;32345:6;32330:8;:22::i;:::-;32316:36;-1:-1:-1;32316:36:0;-1:-1:-1;32365:10:0;-1:-1:-1;;;;;;;;;32390:9:0;;;32386:988;;;32483:24;32494:4;32500:6;32483:10;:24::i;:::-;32465:42;-1:-1:-1;32465:42:0;;;-1:-1:-1;32539:4:0;32530:13;;;;;:32;;;32556:6;32547:5;:15;;32530:32;32522:76;;;;-1:-1:-1;;;32522:76:0;;;;;;;;;32621:5;-1:-1:-1;32628:6:0;;-1:-1:-1;32613:22:0;;-1:-1:-1;32613:22:0;32386:988;-1:-1:-1;;;;;;;;;32657:9:0;;;32653:721;;;32750:24;32761:4;32767:6;32750:10;:24::i;:::-;32732:42;-1:-1:-1;32732:42:0;;;-1:-1:-1;32805:6:0;32797:14;;:37;;;;;32824:10;32815:5;:19;;32797:37;32789:82;;;;-1:-1:-1;;;32789:82:0;;;;;;;;32653:721;-1:-1:-1;;;;;;32930:9:0;;;;32926:448;;;33023:24;33034:4;33040:6;33023:10;:24::i;:::-;33005:42;-1:-1:-1;;;;;;33005:42:0;;-1:-1:-1;33078:10:0;33070:18;;33062:63;;;;-1:-1:-1;;;33062:63:0;;;;;;;;32926:448;-1:-1:-1;33245:8:0;;;;33284:4;33276:12;;33268:57;;;;-1:-1:-1;;;33268:57:0;;;;;;;;46931:346;47017:7;47120:12;47112:6;47104:29;;;;-1:-1:-1;;;47104:29:0;;;;;;;;;;;47144:9;47160:1;47156;:5;;;;;;;46931:346;-1:-1:-1;;;;;46931:346:0:o;16232:623::-;16378:4;16372:11;16412:4;16430:21;;;16286:12;;16372:11;16502:4;16538;16465:307;16569:7;16561:6;16558:19;16465:307;;;16754:1;16746:6;16741:15;16732:6;16725:4;16719;16715:15;16711:28;16703:54;16619:4;16607:17;;;;;-1:-1:-1;;16652:17:0;16465:307;;;-1:-1:-1;;;16809:4:0;16799:15;;16793:4;16786:29;16799:15;16232:623;-1:-1:-1;;16232:623:0:o;11963:370::-;12030:19;12085:2;12071:3;:10;:16;;12063:52;;;;-1:-1:-1;;;12063:52:0;;;;;;;;;12136:17;12142:3;12147:1;12150:2;12136:5;:17::i;:::-;12127:26;;12186:1;12175:3;12179:2;12175:7;;;;;;;;;;;;;;12169:18;;;;;;:23;;12191:1;12169:23;12165:136;;;12226:4;12221:10;;12209:6;12216:1;12209:9;;;;;;;;;;;:22;-1:-1:-1;;;;;12209:22:0;;;;;;;;;12165:136;;;12283:4;12278:10;;12266:6;12273:1;12266:9;;;;;;;;;;;:22;-1:-1:-1;;;;;12266:22:0;;;;;;;;;11963:370;;;:::o;15706:364::-;15848:4;15842:11;;15880:1;15867:15;;15924:3;15920:11;;;;15913:4;15903:15;;15896:36;16024:4;16014:15;;16001:29;;15842:11;15706:364::o;15436:110::-;15486:12;15518:20;15535:1;15529:8;;15518:10;:20::i;17021:620::-;17164:4;17158:11;17198:4;17216:21;;;17074:12;;17158:11;17288:4;17324;17251:307;17355:7;17347:6;17344:19;17251:307;;;17540:1;17532:6;17527:15;17518:6;17511:4;17505;17501:15;17497:28;17489:54;17405:4;17393:17;;;;;-1:-1:-1;;17438:17:0;17251:307;;;-1:-1:-1;;;17595:4:0;17585:15;;17579:4;17572:29;17585:15;17021:620;-1:-1:-1;;17021:620:0:o;44887:192::-;44973:7;45009:12;45001:6;;;;44993:29;;;;-1:-1:-1;;;44993:29:0;;;;;;;;;;-1:-1:-1;;;45045:5:0;;;44887:192::o;23567:608::-;23645:6;23653:7;23695:4;:11;23681:6;23690:1;23681:10;:25;;:48;;;;;23719:6;23728:1;23719:10;23710:6;:19;23681:48;23673:95;;;;-1:-1:-1;;;23673:95:0;;;;;;;;;23789:8;23854:4;23848:11;23914:6;23907:4;23901;23897:15;23893:28;23887:35;23965:6;23959:4;23954:18;23944:8;23936:37;24024:6;24021:1;24016:15;24009:4;23999:8;23995:19;23987:45;-1:-1:-1;24073:4:0;24059:19;;;24053:4;24046:33;-1:-1:-1;;24104:19:0;;;24098:26;;24156:10;;;-1:-1:-1;;;;23567:608:0:o;57097:14652::-;;;;;;;;;-1:-1:-1;57097:14652:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;-1:-1:-1;57097:14652:0;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57097:14652:0;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:128;217:13;;235:30;217:13;235:30;;277:134;355:13;;373:33;355:13;373:33;;432:336;;;546:3;539:4;531:6;527:17;523:27;513:2;;564:1;561;554:12;513:2;-1:-1;584:20;;-1:-1;;;;;613:30;;610:2;;;656:1;653;646:12;610:2;690:4;682:6;678:17;666:29;;741:3;733:4;725:6;721:17;711:8;707:32;704:41;701:2;;;758:1;755;748:12;777:432;;874:3;867:4;859:6;855:17;851:27;841:2;;892:1;889;882:12;841:2;929:6;916:20;951:60;966:44;1003:6;966:44;;;951:60;;;942:69;;1031:6;1024:5;1017:21;1067:4;1059:6;1055:17;1100:4;1093:5;1089:16;1135:3;1126:6;1121:3;1117:16;1114:25;1111:2;;;1152:1;1149;1142:12;1111:2;1162:41;1196:6;1191:3;1186;1162:41;;;834:375;;;;;;;;1667:442;;1779:3;1772:4;1764:6;1760:17;1756:27;1746:2;;1797:1;1794;1787:12;1746:2;1827:6;1821:13;1849:64;1864:48;1905:6;1864:48;;1849:64;1840:73;;1933:6;1926:5;1919:21;1969:4;1961:6;1957:17;2002:4;1995:5;1991:16;2037:3;2028:6;2023:3;2019:16;2016:25;2013:2;;;2054:1;2051;2044:12;2013:2;2064:39;2096:6;2091:3;2086;2064:39;;2258:132;2335:13;;2353:32;2335:13;2353:32;;2397:128;2463:20;;2488:32;2463:20;2488:32;;2532:241;;2636:2;2624:9;2615:7;2611:23;2607:32;2604:2;;;2652:1;2649;2642:12;2604:2;2687:1;2704:53;2749:7;2729:9;2704:53;;2780:257;;2892:2;2880:9;2871:7;2867:23;2863:32;2860:2;;;2908:1;2905;2898:12;2860:2;2943:1;2960:61;3013:7;2993:9;2960:61;;3044:263;;3159:2;3147:9;3138:7;3134:23;3130:32;3127:2;;;3175:1;3172;3165:12;3127:2;3210:1;3227:64;3283:7;3263:9;3227:64;;3314:337;;3423:2;3411:9;3402:7;3398:23;3394:32;3391:2;;;3439:1;3436;3429:12;3391:2;3474:31;;-1:-1;;;;;3514:30;;3511:2;;;3557:1;3554;3547:12;3511:2;3577:58;3627:7;3618:6;3607:9;3603:22;3577:58;;4010:360;;4134:2;4122:9;4113:7;4109:23;4105:32;4102:2;;;4150:1;4147;4140:12;4102:2;4185:24;;-1:-1;;;;;4218:30;;4215:2;;;4261:1;4258;4251:12;4215:2;4281:73;4346:7;4337:6;4326:9;4322:22;4281:73;;4377:574;;;4516:2;4504:9;4495:7;4491:23;4487:32;4484:2;;;4532:1;4529;4522:12;4484:2;4567:31;;-1:-1;;;;;4607:30;;4604:2;;;4650:1;4647;4640:12;4604:2;4670:62;4724:7;4715:6;4704:9;4700:22;4670:62;;;4660:72;;4546:192;4797:2;4786:9;4782:18;4769:32;-1:-1;;;;;4813:6;4810:30;4807:2;;;4853:1;4850;4843:12;4807:2;4873:62;4927:7;4918:6;4907:9;4903:22;4873:62;;;4863:72;;4748:193;4478:473;;;;;;4958:803;;;;5123:2;5111:9;5102:7;5098:23;5094:32;5091:2;;;5139:1;5136;5129:12;5091:2;5174:31;;-1:-1;;;;;5214:30;;5211:2;;;5257:1;5254;5247:12;5211:2;5277:62;5331:7;5322:6;5311:9;5307:22;5277:62;;;5267:72;;5153:192;5404:2;5393:9;5389:18;5376:32;-1:-1;;;;;5420:6;5417:30;5414:2;;;5460:1;5457;5450:12;5414:2;5480:62;5534:7;5525:6;5514:9;5510:22;5480:62;;;5470:72;;5355:193;5607:2;5596:9;5592:18;5579:32;-1:-1;;;;;5623:6;5620:30;5617:2;;;5663:1;5660;5653:12;5617:2;5683:62;5737:7;5728:6;5717:9;5713:22;5683:62;;;5673:72;;5558:193;5085:676;;;;;;5768:1263;;;;;;5985:3;5973:9;5964:7;5960:23;5956:33;5953:2;;;6002:1;5999;5992:12;5953:2;6037:31;;-1:-1;;;;;6077:30;;6074:2;;;6120:1;6117;6110:12;6074:2;6140:62;6194:7;6185:6;6174:9;6170:22;6140:62;;;6130:72;;6016:192;6267:2;6256:9;6252:18;6239:32;-1:-1;;;;;6283:6;6280:30;6277:2;;;6323:1;6320;6313:12;6277:2;6343:62;6397:7;6388:6;6377:9;6373:22;6343:62;;;6333:72;;6218:193;6470:2;6459:9;6455:18;6442:32;-1:-1;;;;;6486:6;6483:30;6480:2;;;6526:1;6523;6516:12;6480:2;6546:62;6600:7;6591:6;6580:9;6576:22;6546:62;;;6536:72;;6421:193;6673:2;6662:9;6658:18;6645:32;-1:-1;;;;;6689:6;6686:30;6683:2;;;6729:1;6726;6719:12;6683:2;6749:62;6803:7;6794:6;6783:9;6779:22;6749:62;;;6739:72;;6624:193;6876:3;6865:9;6861:19;6848:33;-1:-1;;;;;6893:6;6890:30;6887:2;;;6933:1;6930;6923:12;6887:2;6953:62;7007:7;6998:6;6987:9;6983:22;6953:62;;;6943:72;;6827:194;5947:1084;;;;;;;;;7308:261;;7422:2;7410:9;7401:7;7397:23;7393:32;7390:2;;;7438:1;7435;7428:12;7390:2;7473:1;7490:63;7545:7;7525:9;7490:63;;7576:239;;7679:2;7667:9;7658:7;7654:23;7650:32;7647:2;;;7695:1;7692;7685:12;7647:2;7730:1;7747:52;7791:7;7771:9;7747:52;;7822:987;;;;;;;;8033:3;8021:9;8012:7;8008:23;8004:33;8001:2;;;8050:1;8047;8040:12;8001:2;8085:1;8102:52;8146:7;8126:9;8102:52;;;8092:62;;8064:96;8219:2;8208:9;8204:18;8191:32;-1:-1;;;;;8235:6;8232:30;8229:2;;;8275:1;8272;8265:12;8229:2;8303:64;8359:7;8350:6;8339:9;8335:22;8303:64;;;8293:74;;;;8170:203;8432:2;8421:9;8417:18;8404:32;-1:-1;;;;;8448:6;8445:30;8442:2;;;8488:1;8485;8478:12;8442:2;8516:64;8572:7;8563:6;8552:9;8548:22;8516:64;;;8506:74;;;;8383:203;8645:2;8634:9;8630:18;8617:32;-1:-1;;;;;8661:6;8658:30;8655:2;;;8701:1;8698;8691:12;8655:2;8729:64;8785:7;8776:6;8765:9;8761:22;8729:64;;;8719:74;;;;8596:203;7995:814;;;;;;;;;;;8816:142;8907:45;8946:5;8907:45;;;8902:3;8895:58;8889:69;;;8965:113;9048:24;9066:5;9048:24;;9085:152;9186:45;9206:24;9224:5;9206:24;;;9186:45;;9244:104;9321:21;9336:5;9321:21;;9355:148;9454:43;9473:23;9490:5;9473:23;;;9454:43;;9510:113;9593:24;9611:5;9593:24;;9630:152;9731:45;9751:24;9769:5;9751:24;;9789:148;9888:43;9907:23;9924:5;9907:23;;9967:297;;10081:70;10144:6;10139:3;10081:70;;;10074:77;;10163:43;10199:6;10194:3;10187:5;10163:43;;;10228:29;10250:6;10228:29;;;10219:39;;;;10067:197;-1:-1;;;10067:197;10272:343;;10382:38;10414:5;10382:38;;;10432:70;10495:6;10490:3;10432:70;;;10425:77;;10507:52;10552:6;10547:3;10540:4;10533:5;10529:16;10507:52;;;10580:29;10602:6;10580:29;;10622:356;;10750:38;10782:5;10750:38;;;10800:88;10881:6;10876:3;10800:88;;;10793:95;;10893:52;10938:6;10933:3;10926:4;10919:5;10915:16;10893:52;;;10957:16;;;;;10730:248;-1:-1;;10730:248;12037:320;;12197:67;12261:2;12256:3;12197:67;;;-1:-1;;;12277:43;;12348:2;12339:12;;12183:174;-1:-1;;12183:174;12366:329;;12526:67;12590:2;12585:3;12526:67;;;12626:31;12606:52;;12686:2;12677:12;;12512:183;-1:-1;;12512:183;12704:376;;12864:67;12928:2;12923:3;12864:67;;;12964:34;12944:55;;-1:-1;;;13028:2;13019:12;;13012:31;13071:2;13062:12;;12850:230;-1:-1;;12850:230;13089:331;;13249:67;13313:2;13308:3;13249:67;;;13349:33;13329:54;;13411:2;13402:12;;13235:185;-1:-1;;13235:185;13429:374;;13589:67;13653:2;13648:3;13589:67;;;13689:34;13669:55;;-1:-1;;;13753:2;13744:12;;13737:29;13794:2;13785:12;;13575:228;-1:-1;;13575:228;13812:378;;13972:67;14036:2;14031:3;13972:67;;;14072:34;14052:55;;-1:-1;;;14136:2;14127:12;;14120:33;14181:2;14172:12;;13958:232;-1:-1;;13958:232;14199:372;;14359:67;14423:2;14418:3;14359:67;;;14459:34;14439:55;;-1:-1;;;14523:2;14514:12;;14507:27;14562:2;14553:12;;14345:226;-1:-1;;14345:226;14580:327;;14740:67;14804:2;14799:3;14740:67;;;14840:29;14820:50;;14898:2;14889:12;;14726:181;-1:-1;;14726:181;14916:375;;15076:67;15140:2;15135:3;15076:67;;;15176:34;15156:55;;-1:-1;;;15240:2;15231:12;;15224:30;15282:2;15273:12;;15062:229;-1:-1;;15062:229;15300:332;;15460:67;15524:2;15519:3;15460:67;;;15560:34;15540:55;;15623:2;15614:12;;15446:186;-1:-1;;15446:186;15641:441;;15801:67;15865:2;15860:3;15801:67;;;15901:34;15881:55;;15970:34;15965:2;15956:12;;15949:56;-1:-1;;;16034:2;16025:12;;16018:27;16073:2;16064:12;;15787:295;-1:-1;;15787:295;16091:375;;16251:67;16315:2;16310:3;16251:67;;;16351:34;16331:55;;-1:-1;;;16415:2;16406:12;;16399:30;16457:2;16448:12;;16237:229;-1:-1;;16237:229;16475:372;;16635:67;16699:2;16694:3;16635:67;;;16735:34;16715:55;;-1:-1;;;16799:2;16790:12;;16783:27;16838:2;16829:12;;16621:226;-1:-1;;16621:226;16856:324;;17016:67;17080:2;17075:3;17016:67;;;17116:26;17096:47;;17171:2;17162:12;;17002:178;-1:-1;;17002:178;17189:321;;17349:67;17413:2;17408:3;17349:67;;;-1:-1;;;17429:44;;17501:2;17492:12;;17335:175;-1:-1;;17335:175;17519:316;;17679:67;17743:2;17738:3;17679:67;;;-1:-1;;;17759:39;;17826:2;17817:12;;17665:170;-1:-1;;17665:170;17844:386;;18004:67;18068:2;18063:3;18004:67;;;18104:34;18084:55;;-1:-1;;;18168:2;18159:12;;18152:41;18221:2;18212:12;;17990:240;-1:-1;;17990:240;18239:319;;18399:67;18463:2;18458:3;18399:67;;;-1:-1;;;18479:42;;18549:2;18540:12;;18385:173;-1:-1;;18385:173;18567:319;;18727:67;18791:2;18786:3;18727:67;;;-1:-1;;;18807:42;;18877:2;18868:12;;18713:173;-1:-1;;18713:173;18895:399;;19055:67;19119:2;19114:3;19055:67;;;19155:34;19135:55;;19224:32;19219:2;19210:12;;19203:54;19285:2;19276:12;;19041:253;-1:-1;;19041:253;19303:380;;19463:67;19527:2;19522:3;19463:67;;;19563:34;19543:55;;-1:-1;;;19627:2;19618:12;;19611:35;19674:2;19665:12;;19449:234;-1:-1;;19449:234;19692:396;;19852:67;19916:2;19911:3;19852:67;;;19952:34;19932:55;;20021:29;20016:2;20007:12;;20000:51;20079:2;20070:12;;19838:250;-1:-1;;19838:250;20097:323;;20257:67;20321:2;20316:3;20257:67;;;20357:25;20337:46;;20411:2;20402:12;;20243:177;-1:-1;;20243:177;20429:321;;20589:67;20653:2;20648:3;20589:67;;;-1:-1;;;20669:44;;20741:2;20732:12;;20575:175;-1:-1;;20575:175;20759:332;;20919:67;20983:2;20978:3;20919:67;;;21019:34;20999:55;;21082:2;21073:12;;20905:186;-1:-1;;20905:186;21100:320;;21260:67;21324:2;21319:3;21260:67;;;-1:-1;;;21340:43;;21411:2;21402:12;;21246:174;-1:-1;;21246:174;21429:383;;21589:67;21653:2;21648:3;21589:67;;;21689:34;21669:55;;-1:-1;;;21753:2;21744:12;;21737:38;21803:2;21794:12;;21575:237;-1:-1;;21575:237;21821:332;;21981:67;22045:2;22040:3;21981:67;;;22081:34;22061:55;;22144:2;22135:12;;21967:186;-1:-1;;21967:186;22162:327;;22322:67;22386:2;22381:3;22322:67;;;22422:29;22402:50;;22480:2;22471:12;;22308:181;-1:-1;;22308:181;22498:377;;22658:67;22722:2;22717:3;22658:67;;;22758:34;22738:55;;-1:-1;;;22822:2;22813:12;;22806:32;22866:2;22857:12;;22644:231;-1:-1;;22644:231;22884:382;;23044:67;23108:2;23103:3;23044:67;;;23144:34;23124:55;;-1:-1;;;23208:2;23199:12;;23192:37;23257:2;23248:12;;23030:236;-1:-1;;23030:236;23275:332;;23435:67;23499:2;23494:3;23435:67;;;23535:34;23515:55;;23598:2;23589:12;;23421:186;-1:-1;;23421:186;23616:393;;23776:67;23840:2;23835:3;23776:67;;;23876:34;23856:55;;23945:26;23940:2;23931:12;;23924:48;24000:2;23991:12;;23762:247;-1:-1;;23762:247;24018:356;;24196:85;24278:2;24273:3;24196:85;;;-1:-1;;;24294:43;;24365:2;24356:12;;24182:192;-1:-1;;24182:192;24383:376;;24543:67;24607:2;24602:3;24543:67;;;24643:34;24623:55;;-1:-1;;;24707:2;24698:12;;24691:31;24750:2;24741:12;;24529:230;-1:-1;;24529:230;24768:314;;24928:67;24992:2;24987:3;24928:67;;;-1:-1;;;25008:37;;25073:2;25064:12;;24914:168;-1:-1;;24914:168;25091:323;;25251:67;25315:2;25310:3;25251:67;;;25351:25;25331:46;;25405:2;25396:12;;25237:177;-1:-1;;25237:177;25423:322;;25583:67;25647:2;25642:3;25583:67;;;-1:-1;;;25663:45;;25736:2;25727:12;;25569:176;-1:-1;;25569:176;25754:392;;25914:67;25978:2;25973:3;25914:67;;;26014:34;25994:55;;26083:25;26078:2;26069:12;;26062:47;26137:2;26128:12;;25900:246;-1:-1;;25900:246;26155:371;;26315:67;26379:2;26374:3;26315:67;;;26415:34;26395:55;;-1:-1;;;26479:2;26470:12;;26463:26;26517:2;26508:12;;26301:225;-1:-1;;26301:225;26535:393;;26695:67;26759:2;26754:3;26695:67;;;26795:34;26775:55;;26864:26;26859:2;26850:12;;26843:48;26919:2;26910:12;;26681:247;-1:-1;;26681:247;26937:320;;27097:67;27161:2;27156:3;27097:67;;;-1:-1;;;27177:43;;27248:2;27239:12;;27083:174;-1:-1;;27083:174;27266:441;;27426:67;27490:2;27485:3;27426:67;;;27526:34;27506:55;;27595:34;27590:2;27581:12;;27574:56;-1:-1;;;27659:2;27650:12;;27643:27;27698:2;27689:12;;27412:295;-1:-1;;27412:295;27716:332;;27876:67;27940:2;27935:3;27876:67;;;27976:34;27956:55;;28039:2;28030:12;;27862:186;-1:-1;;27862:186;28057:371;;28217:67;28281:2;28276:3;28217:67;;;28317:34;28297:55;;-1:-1;;;28381:2;28372:12;;28365:26;28419:2;28410:12;;28203:225;-1:-1;;28203:225;28437:323;;28597:67;28661:2;28656:3;28597:67;;;28697:25;28677:46;;28751:2;28742:12;;28583:177;-1:-1;;28583:177;28769:371;;28929:67;28993:2;28988:3;28929:67;;;29029:34;29009:55;;-1:-1;;;29093:2;29084:12;;29077:26;29131:2;29122:12;;28915:225;-1:-1;;28915:225;29149:385;;29309:67;29373:2;29368:3;29309:67;;;29409:34;29389:55;;-1:-1;;;29473:2;29464:12;;29457:40;29525:2;29516:12;;29295:239;-1:-1;;29295:239;29543:371;;29703:67;29767:2;29762:3;29703:67;;;29803:34;29783:55;;-1:-1;;;29867:2;29858:12;;29851:26;29905:2;29896:12;;29689:225;-1:-1;;29689:225;29923:373;;30083:67;30147:2;30142:3;30083:67;;;30183:34;30163:55;;-1:-1;;;30247:2;30238:12;;30231:28;30287:2;30278:12;;30069:227;-1:-1;;30069:227;30305:379;;30465:67;30529:2;30524:3;30465:67;;;30565:34;30545:55;;-1:-1;;;30629:2;30620:12;;30613:34;30675:2;30666:12;;30451:233;-1:-1;;30451:233;30692:124;30774:36;30804:5;30774:36;;30823:110;30904:23;30921:5;30904:23;;30940:110;31021:23;31038:5;31021:23;;31057:107;31136:22;31152:5;31136:22;;31171:401;;31336:75;31407:3;31398:6;31336:75;;;31433:2;31428:3;31424:12;31417:19;;31454:93;31543:3;31534:6;31454:93;;31579:517;;31752:73;31821:3;31812:6;31752:73;;;31847:1;31842:3;31838:11;31831:18;;31860:75;31931:3;31922:6;31860:75;;;31957:2;31952:3;31948:12;31941:19;;31971:75;32042:3;32033:6;31971:75;;;-1:-1;32068:2;32059:12;;31740:356;-1:-1;;;31740:356;32103:396;;32266:73;32335:3;32326:6;32266:73;;;32361:1;32356:3;32352:11;32345:18;;32381:93;32470:3;32461:6;32381:93;;32506:244;;32625:75;32696:3;32687:6;32625:75;;;-1:-1;32722:2;32713:12;;32613:137;-1:-1;32613:137;32757:396;;32920:73;32989:3;32980:6;32920:73;;;33015:1;33010:3;33006:11;32999:18;;33035:93;33124:3;33115:6;33035:93;;33160:254;;33300:89;33385:3;33376:6;33300:89;;33690:419;;33880:93;33969:3;33960:6;33880:93;;;33873:100;;33991:93;34080:3;34071:6;33991:93;;34116:1204;;34536:93;34625:3;34616:6;34536:93;;;34529:100;;34647:93;34736:3;34727:6;34647:93;;;34640:100;;34758:93;34847:3;34838:6;34758:93;;;34751:100;;34869:93;34958:3;34949:6;34869:93;;;34862:100;;34980:93;35069:3;35060:6;34980:93;;;34973:100;;35091:93;35180:3;35171:6;35091:93;;;35084:100;;35202:93;35291:3;35282:6;35202:93;;;35195:100;34517:803;-1:-1;;;;;;;;;34517:803;35327:529;;35572:93;35661:3;35652:6;35572:93;;;35565:100;;35683:148;35827:3;35683:148;;35863:213;35981:2;35966:18;;35995:71;35970:9;36039:6;35995:71;;36083:229;36209:2;36194:18;;36223:79;36198:9;36275:6;36223:79;;36319:201;36431:2;36416:18;;36445:65;36420:9;36483:6;36445:65;;36527:213;36645:2;36630:18;;36659:71;36634:9;36703:6;36659:71;;36747:539;36945:3;36930:19;;36960:71;36934:9;37004:6;36960:71;;;37042:68;37106:2;37095:9;37091:18;37082:6;37042:68;;;37121:72;37189:2;37178:9;37174:18;37165:6;37121:72;;;37204;37272:2;37261:9;37257:18;37248:6;37204:72;;37293:297;37429:2;37443:47;;;37414:18;;37504:76;37414:18;37566:6;37504:76;;37597:943;37897:3;37912:47;;;37882:19;;37973:76;37882:19;38035:6;37973:76;;;37965:84;;38060:80;38136:2;38125:9;38121:18;38112:6;38060:80;;;38151:70;38217:2;38206:9;38202:18;38193:6;38151:70;;;38269:9;38263:4;38259:20;38254:2;38243:9;38239:18;38232:48;38294:86;38375:4;38366:6;38358;38294:86;;;38286:94;;38429:9;38423:4;38419:20;38413:3;38402:9;38398:19;38391:49;38454:76;38525:4;38516:6;38454:76;;;38446:84;37868:672;-1:-1;;;;;;;;37868:672;38547:599;38755:2;38769:47;;;38740:18;;38830:76;38740:18;38892:6;38830:76;;;38822:84;;38954:9;38948:4;38944:20;38939:2;38928:9;38924:18;38917:48;38979:76;39050:4;39041:6;38979:76;;;38971:84;;39066:70;39132:2;39121:9;39117:18;39108:6;39066:70;;39461:407;39652:2;39666:47;;;39637:18;;39727:131;39637:18;39727:131;;39875:407;40066:2;40080:47;;;40051:18;;40141:131;40051:18;40141:131;;40289:407;40480:2;40494:47;;;40465:18;;40555:131;40465:18;40555:131;;40703:407;40894:2;40908:47;;;40879:18;;40969:131;40879:18;40969:131;;41117:407;41308:2;41322:47;;;41293:18;;41383:131;41293:18;41383:131;;41531:407;41722:2;41736:47;;;41707:18;;41797:131;41707:18;41797:131;;41945:407;42136:2;42150:47;;;42121:18;;42211:131;42121:18;42211:131;;42359:407;42550:2;42564:47;;;42535:18;;42625:131;42535:18;42625:131;;42773:407;42964:2;42978:47;;;42949:18;;43039:131;42949:18;43039:131;;43187:407;43378:2;43392:47;;;43363:18;;43453:131;43363:18;43453:131;;43601:407;43792:2;43806:47;;;43777:18;;43867:131;43777:18;43867:131;;44015:407;44206:2;44220:47;;;44191:18;;44281:131;44191:18;44281:131;;44429:407;44620:2;44634:47;;;44605:18;;44695:131;44605:18;44695:131;;44843:407;45034:2;45048:47;;;45019:18;;45109:131;45019:18;45109:131;;45257:407;45448:2;45462:47;;;45433:18;;45523:131;45433:18;45523:131;;45671:407;45862:2;45876:47;;;45847:18;;45937:131;45847:18;45937:131;;46085:407;46276:2;46290:47;;;46261:18;;46351:131;46261:18;46351:131;;46499:407;46690:2;46704:47;;;46675:18;;46765:131;46675:18;46765:131;;46913:407;47104:2;47118:47;;;47089:18;;47179:131;47089:18;47179:131;;47327:407;47518:2;47532:47;;;47503:18;;47593:131;47503:18;47593:131;;47741:407;47932:2;47946:47;;;47917:18;;48007:131;47917:18;48007:131;;48155:407;48346:2;48360:47;;;48331:18;;48421:131;48331:18;48421:131;;48569:407;48760:2;48774:47;;;48745:18;;48835:131;48745:18;48835:131;;48983:407;49174:2;49188:47;;;49159:18;;49249:131;49159:18;49249:131;;49397:407;49588:2;49602:47;;;49573:18;;49663:131;49573:18;49663:131;;49811:407;50002:2;50016:47;;;49987:18;;50077:131;49987:18;50077:131;;50225:407;50416:2;50430:47;;;50401:18;;50491:131;50401:18;50491:131;;50639:407;50830:2;50844:47;;;50815:18;;50905:131;50815:18;50905:131;;51053:407;51244:2;51258:47;;;51229:18;;51319:131;51229:18;51319:131;;51467:407;51658:2;51672:47;;;51643:18;;51733:131;51643:18;51733:131;;51881:407;52072:2;52086:47;;;52057:18;;52147:131;52057:18;52147:131;;52295:407;52486:2;52500:47;;;52471:18;;52561:131;52471:18;52561:131;;52709:407;52900:2;52914:47;;;52885:18;;52975:131;52885:18;52975:131;;53123:407;53314:2;53328:47;;;53299:18;;53389:131;53299:18;53389:131;;53537:407;53728:2;53742:47;;;53713:18;;53803:131;53713:18;53803:131;;53951:407;54142:2;54156:47;;;54127:18;;54217:131;54127:18;54217:131;;54365:407;54556:2;54570:47;;;54541:18;;54631:131;54541:18;54631:131;;54779:407;54970:2;54984:47;;;54955:18;;55045:131;54955:18;55045:131;;55193:407;55384:2;55398:47;;;55369:18;;55459:131;55369:18;55459:131;;55607:407;55798:2;55812:47;;;55783:18;;55873:131;55783:18;55873:131;;56021:407;56212:2;56226:47;;;56197:18;;56287:131;56197:18;56287:131;;56435:407;56626:2;56640:47;;;56611:18;;56701:131;56611:18;56701:131;;56849:407;57040:2;57054:47;;;57025:18;;57115:131;57025:18;57115:131;;57263:407;57454:2;57468:47;;;57439:18;;57529:131;57439:18;57529:131;;57677:407;57868:2;57882:47;;;57853:18;;57943:131;57853:18;57943:131;;58091:407;58282:2;58296:47;;;58267:18;;58357:131;58267:18;58357:131;;58505:407;58696:2;58710:47;;;58681:18;;58771:131;58681:18;58771:131;;58919:407;59110:2;59124:47;;;59095:18;;59185:131;59095:18;59185:131;;59333:407;59524:2;59538:47;;;59509:18;;59599:131;59509:18;59599:131;;59747:407;59938:2;59952:47;;;59923:18;;60013:131;59923:18;60013:131;;60161:209;60277:2;60262:18;;60291:69;60266:9;60333:6;60291:69;;60377:406;60540:2;60525:18;;60554:70;60529:9;60597:6;60554:70;;;60672:9;60666:4;60662:20;60657:2;60646:9;60642:18;60635:48;60697:76;60768:4;60759:6;60697:76;;60790:209;60906:2;60891:18;;60920:69;60895:9;60962:6;60920:69;;61006:320;61150:2;61135:18;;61164:69;61139:9;61206:6;61164:69;;;61244:72;61312:2;61301:9;61297:18;61288:6;61244:72;;61333:771;61575:3;61560:19;;61590:69;61564:9;61632:6;61590:69;;;61707:9;61701:4;61697:20;61692:2;61681:9;61677:18;61670:48;61732:72;61799:4;61790:6;61732:72;;;61724:80;;61852:9;61846:4;61842:20;61837:2;61826:9;61822:18;61815:48;61877:72;61944:4;61935:6;61877:72;;;61869:80;;61997:9;61991:4;61987:20;61982:2;61971:9;61967:18;61960:48;62022:72;62089:4;62080:6;62022:72;;;62014:80;61546:558;-1:-1;;;;;;61546:558;62111:256;62173:2;62167:9;62199:17;;;-1:-1;;;;;62259:34;;62295:22;;;62256:62;62253:2;;;62331:1;62328;62321:12;62253:2;62347;62340:22;62151:216;;-1:-1;62151:216;62374:317;;-1:-1;;;;;62505:6;62502:30;62499:2;;;62545:1;62542;62535:12;62499:2;-1:-1;62676:4;62612;62589:17;;;;-1:-1;;62585:33;62666:15;;62436:255;63026:117;63109:12;;63080:63;63408:162;63510:19;;;63559:4;63550:14;;63503:67;64057:91;;64119:24;64137:5;64119:24;;64155:85;64221:13;64214:21;;64197:43;64247:144;-1:-1;;;;;;64308:78;;64291:100;64398:72;64460:5;64443:27;64477:144;-1:-1;;;;;;64538:78;;64521:100;64628:121;-1:-1;;;;;64690:54;;64673:76;64835:88;64907:10;64896:22;;64879:44;64930:96;-1:-1;;;;;64991:30;;64974:52;65033:81;65104:4;65093:16;;65076:38;65121:129;;65208:37;65239:5;65257:121;65336:37;65367:5;65336:37;;65500:106;;65578:23;65595:5;65578:23;;65614:145;65695:6;65690:3;65685;65672:30;-1:-1;65751:1;65733:16;;65726:27;65665:94;65768:268;65833:1;65840:101;65854:6;65851:1;65848:13;65840:101;;;65921:11;;;65915:18;65902:11;;;65895:39;65876:2;65869:10;65840:101;;;65956:6;65953:1;65950:13;65947:2;;;66021:1;66012:6;66007:3;66003:16;65996:27;65947:2;65817:219;;;;;66044:95;;66108:26;66128:5;66387:89;66451:20;66465:5;66451:20;;66483:97;66571:2;66551:14;-1:-1;;66547:28;;66531:49;66588:94;66662:2;66658:14;;66630:52;66690:117;66759:24;66777:5;66759:24;;;66752:5;66749:35;66739:2;;66798:1;66795;66788:12;66814:111;66880:21;66895:5;66880:21;;66932:117;67001:24;67019:5;67001:24;;67180:115;67248:23;67265:5;67248:23;;67302:115;67370:23;67387:5;67370:23;
Swarm Source
bzzr://a9d6245213ee3a62077ae8be794cd326c79e975395163981b0e369d773535ea3
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.