Feature Tip: Add private address tag to any address under My Name Tag !
Overview
Max Total Supply
0
Holders
0
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ProxyOFTWithFee
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-08 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @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 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. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract 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() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(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 virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; } interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion(uint16 _version) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion(uint16 _version) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; } interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload ) external; // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam ) external view returns (uint nativeFee, uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress(address _userApplication) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress(address _userApplication) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion(address _userApplication) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion(address _userApplication) external view returns (uint16); } /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ library BytesLib { function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore( 0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. ) ) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) 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) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask))) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice(bytes memory _bytes, uint _start, uint _length) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); 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. 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) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1, "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint _start) internal pure returns (uint) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // 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 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } 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) // Decode the length of the stored array like in concatStorage(). 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 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage 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(uint256(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; } } /* * a generic LzReceiver implementation */ abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig { using BytesLib for bytes; // ua can not send payload larger than this by default, but it can be changed by the ua owner uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000; ILayerZeroEndpoint public immutable lzEndpoint; mapping(uint16 => bytes) public trustedRemoteLookup; mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup; mapping(uint16 => uint) public payloadSizeLimitLookup; address public precrime; event SetPrecrime(address precrime); event SetTrustedRemote(uint16 _remoteChainId, bytes _path); event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress); event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas); constructor(address _endpoint) { lzEndpoint = ILayerZeroEndpoint(_endpoint); } function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override { // lzReceive must be called by the endpoint for security require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller"); bytes memory trustedRemote = trustedRemoteLookup[_srcChainId]; // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote. require( _srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract" ); _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual; function _lzSend( uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee ) internal virtual { bytes memory trustedRemote = trustedRemoteLookup[_dstChainId]; require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source"); _checkPayloadSize(_dstChainId, _payload.length); lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams); } function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual { uint providedGasLimit = _getGasLimit(_adapterParams); uint minGasLimit = minDstGasLookup[_dstChainId][_type]; require(minGasLimit > 0, "LzApp: minGasLimit not set"); require(providedGasLimit >= minGasLimit + _extraGas, "LzApp: gas limit is too low"); } function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) { require(_adapterParams.length >= 34, "LzApp: invalid adapterParams"); assembly { gasLimit := mload(add(_adapterParams, 34)) } } function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual { uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId]; if (payloadSizeLimit == 0) { // use default if not set payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT; } require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large"); } //---------------------------UserApplication config---------------------------------------- function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) { return lzEndpoint.getConfig(_version, _chainId, address(this), _configType); } // generic config for LayerZero user Application function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner { lzEndpoint.setConfig(_version, _chainId, _configType, _config); } function setSendVersion(uint16 _version) external override onlyOwner { lzEndpoint.setSendVersion(_version); } function setReceiveVersion(uint16 _version) external override onlyOwner { lzEndpoint.setReceiveVersion(_version); } function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner { lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress); } // _path = abi.encodePacked(remoteAddress, localAddress) // this function set the trusted path for the cross-chain communication function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner { trustedRemoteLookup[_remoteChainId] = _path; emit SetTrustedRemote(_remoteChainId, _path); } function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner { trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this)); emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress); } function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) { bytes memory path = trustedRemoteLookup[_remoteChainId]; require(path.length != 0, "LzApp: no trusted path record"); return path.slice(0, path.length - 20); // the last 20 bytes should be address(this) } function setPrecrime(address _precrime) external onlyOwner { precrime = _precrime; emit SetPrecrime(_precrime); } function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner { minDstGasLookup[_dstChainId][_packetType] = _minGas; emit SetMinDstGas(_dstChainId, _packetType, _minGas); } // if the size is 0, it means default size limit function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner { payloadSizeLimitLookup[_dstChainId] = _size; } //--------------------------- VIEW FUNCTION ---------------------------------------- function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) { bytes memory trustedSource = trustedRemoteLookup[_srcChainId]; return keccak256(trustedSource) == keccak256(_srcAddress); } } library ExcessivelySafeCall { uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeCall(address _target, uint _gas, uint16 _maxCopy, bytes memory _calldata) internal returns (bool, bytes memory) { // set up for assembly call uint _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := call( _gas, // gas _target, // recipient 0, // ether value add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /// @notice Use when you _really_ really _really_ don't trust the called /// contract. This prevents the called contract from causing reversion of /// the caller in as many ways as we can. /// @dev The main difference between this and a solidity low-level call is /// that we limit the number of bytes that the callee can cause to be /// copied to caller memory. This prevents stupid things like malicious /// contracts returning 10,000,000 bytes causing a local OOG when copying /// to memory. /// @param _target The address to call /// @param _gas The amount of gas to forward to the remote contract /// @param _maxCopy The maximum number of bytes of returndata to copy /// to memory. /// @param _calldata The data to send to the remote contract /// @return success and returndata, as `.call()`. Returndata is capped to /// `_maxCopy` bytes. function excessivelySafeStaticCall( address _target, uint _gas, uint16 _maxCopy, bytes memory _calldata ) internal view returns (bool, bytes memory) { // set up for assembly call uint _toCopy; bool _success; bytes memory _returnData = new bytes(_maxCopy); // dispatch message to recipient // by assembly calling "handle" function // we call via assembly to avoid memcopying a very large returndata // returned by a malicious contract assembly { _success := staticcall( _gas, // gas _target, // recipient add(_calldata, 0x20), // inloc mload(_calldata), // inlen 0, // outloc 0 // outlen ) // limit our copy to 256 bytes _toCopy := returndatasize() if gt(_toCopy, _maxCopy) { _toCopy := _maxCopy } // Store the length of the copied bytes mstore(_returnData, _toCopy) // copy the bytes from returndata[0:_toCopy] returndatacopy(add(_returnData, 0x20), 0, _toCopy) } return (_success, _returnData); } /** * @notice Swaps function selectors in encoded contract calls * @dev Allows reuse of encoded calldata for functions with identical * argument types but different names. It simply swaps out the first 4 bytes * for the new selector. This function modifies memory in place, and should * only be used with caution. * @param _newSelector The new 4-byte selector * @param _buf The encoded contract args */ function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure { require(_buf.length >= 4); uint _mask = LOW_28_MASK; assembly { // load the first word of let _word := mload(add(_buf, 0x20)) // mask out the top 4 bytes // /x _word := and(_word, _mask) _word := or(_newSelector, _word) mstore(add(_buf, 0x20), _word) } } } /* * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress) */ abstract contract NonblockingLzApp is LzApp { using ExcessivelySafeCall for address; constructor(address _endpoint) LzApp(_endpoint) {} mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages; event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason); event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash); // overriding the virtual function in LzReceiver function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override { (bool success, bytes memory reason) = address(this).excessivelySafeCall( gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload) ); if (!success) { _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason); } } function _storeFailedMessage( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason ) internal virtual { failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason); } function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual { // only internal transaction require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp"); _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } //@notice override this function function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual; function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual { // assert there is message to retry bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce]; require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message"); require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload"); // clear the stored message failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0); // execute the message. revert if it fails again _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload); emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Interface of the IOFT core standard */ interface ICommonOFT is IERC165 { struct LzCallParams { address payable refundAddress; address zroPaymentAddress; bytes adapterParams; } /** * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`) * _dstChainId - L0 defined chain id to send tokens too * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain * _amount - amount of the tokens to transfer * _useZro - indicates to use zro to pay L0 fees * _adapterParam - flexible bytes array to indicate messaging adapter services in L0 */ function estimateSendFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams ) external view returns (uint nativeFee, uint zroFee); function estimateSendAndCallFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, bool _useZro, bytes calldata _adapterParams ) external view returns (uint nativeFee, uint zroFee); /** * @dev returns the circulating amount of tokens on current chain */ function circulatingSupply() external view returns (uint); /** * @dev returns the address of the ERC20 token */ function token() external view returns (address); } interface IOFTReceiverV2 { /** * @dev Called by the OFT contract when tokens are received from source chain. * @param _srcChainId The chain id of the source chain. * @param _srcAddress The address of the OFT token contract on the source chain. * @param _nonce The nonce of the transaction on the source chain. * @param _from The address of the account who calls the sendAndCall() on the source chain. * @param _amount The amount of tokens to transfer. * @param _payload Additional data with no specified format. */ function onOFTReceived( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes32 _from, uint _amount, bytes calldata _payload ) external; } abstract contract OFTCoreV2 is NonblockingLzApp { using BytesLib for bytes; using ExcessivelySafeCall for address; uint public constant NO_EXTRA_GAS = 0; // packet type uint8 public constant PT_SEND = 0; uint8 public constant PT_SEND_AND_CALL = 1; uint8 public immutable sharedDecimals; mapping(uint16 => mapping(bytes => mapping(uint64 => bool))) public creditedPackets; /** * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`) * `_nonce` is the outbound nonce */ event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes32 indexed _toAddress, uint _amount); /** * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain. * `_nonce` is the inbound nonce. */ event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount); event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash); event NonContractAddress(address _address); // _sharedDecimals should be the minimum decimals on all chains constructor(uint8 _sharedDecimals, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) { sharedDecimals = _sharedDecimals; } /************************************************************************ * public functions ************************************************************************/ function callOnOFTReceived( uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes32 _from, address _to, uint _amount, bytes calldata _payload, uint _gasForCall ) public virtual { require(_msgSender() == address(this), "OFTCore: caller must be OFTCore"); // send _amount = _transferFrom(address(this), _to, _amount); emit ReceiveFromChain(_srcChainId, _to, _amount); // call IOFTReceiverV2(_to).onOFTReceived{gas: _gasForCall}(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload); } /************************************************************************ * internal functions ************************************************************************/ function _estimateSendFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes memory _adapterParams ) internal view virtual returns (uint nativeFee, uint zroFee) { // mock the payload for sendFrom() bytes memory payload = _encodeSendPayload(_toAddress, _ld2sd(_amount)); return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams); } function _estimateSendAndCallFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes memory _payload, uint64 _dstGasForCall, bool _useZro, bytes memory _adapterParams ) internal view virtual returns (uint nativeFee, uint zroFee) { // mock the payload for sendAndCall() bytes memory payload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(_amount), _payload, _dstGasForCall); return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams); } function _nonblockingLzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload ) internal virtual override { uint8 packetType = _payload.toUint8(0); if (packetType == PT_SEND) { _sendAck(_srcChainId, _srcAddress, _nonce, _payload); } else if (packetType == PT_SEND_AND_CALL) { _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload); } else { revert("OFTCore: unknown packet type"); } } function _send( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams ) internal virtual returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS); (amount, ) = _removeDust(_amount); amount = _debitFrom(_from, _dstChainId, _toAddress, amount); // amount returned should not have dust require(amount > 0, "OFTCore: amount too small"); bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount)); _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value); emit SendToChain(_dstChainId, _from, _toAddress, amount); } function _sendAck(uint16 _srcChainId, bytes memory, uint64, bytes memory _payload) internal virtual { (address to, uint64 amountSD) = _decodeSendPayload(_payload); if (to == address(0)) { to = address(0xdead); } uint amount = _sd2ld(amountSD); amount = _creditTo(_srcChainId, to, amount); emit ReceiveFromChain(_srcChainId, to, amount); } function _sendAndCall( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes memory _payload, uint64 _dstGasForCall, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams ) internal virtual returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall); (amount, ) = _removeDust(_amount); amount = _debitFrom(_from, _dstChainId, _toAddress, amount); require(amount > 0, "OFTCore: amount too small"); // encode the msg.sender into the payload instead of _from bytes memory lzPayload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall); _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value); emit SendToChain(_dstChainId, _from, _toAddress, amount); } function _sendAndCallAck(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual { (bytes32 from, address to, uint64 amountSD, bytes memory payloadForCall, uint64 gasForCall) = _decodeSendAndCallPayload(_payload); bool credited = creditedPackets[_srcChainId][_srcAddress][_nonce]; uint amount = _sd2ld(amountSD); // credit to this contract first, and then transfer to receiver only if callOnOFTReceived() succeeds if (!credited) { amount = _creditTo(_srcChainId, address(this), amount); creditedPackets[_srcChainId][_srcAddress][_nonce] = true; } if (!_isContract(to)) { emit NonContractAddress(to); return; } // workaround for stack too deep uint16 srcChainId = _srcChainId; bytes memory srcAddress = _srcAddress; uint64 nonce = _nonce; bytes memory payload = _payload; bytes32 from_ = from; address to_ = to; uint amount_ = amount; bytes memory payloadForCall_ = payloadForCall; // no gas limit for the call if retry uint gas = credited ? gasleft() : gasForCall; (bool success, bytes memory reason) = address(this).excessivelySafeCall( gasleft(), 150, abi.encodeWithSelector(this.callOnOFTReceived.selector, srcChainId, srcAddress, nonce, from_, to_, amount_, payloadForCall_, gas) ); if (success) { bytes32 hash = keccak256(payload); emit CallOFTReceivedSuccess(srcChainId, srcAddress, nonce, hash); } else { // store the failed message into the nonblockingLzApp _storeFailedMessage(srcChainId, srcAddress, nonce, payload, reason); } } function _isContract(address _account) internal view returns (bool) { return _account.code.length > 0; } function _ld2sd(uint _amount) internal view virtual returns (uint64) { uint amountSD = _amount / _ld2sdRate(); require(amountSD <= type(uint64).max, "OFTCore: amountSD overflow"); return uint64(amountSD); } function _sd2ld(uint64 _amountSD) internal view virtual returns (uint) { return _amountSD * _ld2sdRate(); } function _removeDust(uint _amount) internal view virtual returns (uint amountAfter, uint dust) { dust = _amount % _ld2sdRate(); amountAfter = _amount - dust; } function _encodeSendPayload(bytes32 _toAddress, uint64 _amountSD) internal view virtual returns (bytes memory) { return abi.encodePacked(PT_SEND, _toAddress, _amountSD); } function _decodeSendPayload(bytes memory _payload) internal view virtual returns (address to, uint64 amountSD) { require(_payload.toUint8(0) == PT_SEND && _payload.length == 41, "OFTCore: invalid payload"); to = _payload.toAddress(13); // drop the first 12 bytes of bytes32 amountSD = _payload.toUint64(33); } function _encodeSendAndCallPayload( address _from, bytes32 _toAddress, uint64 _amountSD, bytes memory _payload, uint64 _dstGasForCall ) internal view virtual returns (bytes memory) { return abi.encodePacked(PT_SEND_AND_CALL, _toAddress, _amountSD, _addressToBytes32(_from), _dstGasForCall, _payload); } function _decodeSendAndCallPayload( bytes memory _payload ) internal view virtual returns (bytes32 from, address to, uint64 amountSD, bytes memory payload, uint64 dstGasForCall) { require(_payload.toUint8(0) == PT_SEND_AND_CALL, "OFTCore: invalid payload"); to = _payload.toAddress(13); // drop the first 12 bytes of bytes32 amountSD = _payload.toUint64(33); from = _payload.toBytes32(41); dstGasForCall = _payload.toUint64(73); payload = _payload.slice(81, _payload.length - 81); } function _addressToBytes32(address _address) internal pure virtual returns (bytes32) { return bytes32(uint(uint160(_address))); } function _debitFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount) internal virtual returns (uint); function _creditTo(uint16 _srcChainId, address _toAddress, uint _amount) internal virtual returns (uint); function _transferFrom(address _from, address _to, uint _amount) internal virtual returns (uint); function _ld2sdRate() internal view virtual returns (uint); } /** * @dev Interface of the IOFT core standard */ interface IOFTWithFee is ICommonOFT { /** * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from` * `_from` the owner of token * `_dstChainId` the destination chain identifier * `_toAddress` can be any size depending on the `dstChainId`. * `_amount` the quantity of tokens in wei * `_minAmount` the minimum amount of tokens to receive on dstChain * `_refundAddress` the address LayerZero refunds if too much message fee is sent * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token) * `_adapterParams` is a flexible bytes array to indicate messaging adapter services */ function sendFrom( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams ) external payable; function sendAndCall( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams ) external payable; } abstract contract Fee is Ownable { uint public constant BP_DENOMINATOR = 10000; mapping(uint16 => FeeConfig) public chainIdToFeeBps; uint16 public defaultFeeBp; address public feeOwner; // defaults to owner struct FeeConfig { uint16 feeBP; bool enabled; } event SetFeeBp(uint16 dstchainId, bool enabled, uint16 feeBp); event SetDefaultFeeBp(uint16 feeBp); event SetFeeOwner(address feeOwner); constructor() { feeOwner = owner(); } function setDefaultFeeBp(uint16 _feeBp) public virtual onlyOwner { require(_feeBp <= BP_DENOMINATOR, "Fee: fee bp must be <= BP_DENOMINATOR"); defaultFeeBp = _feeBp; emit SetDefaultFeeBp(defaultFeeBp); } function setFeeBp(uint16 _dstChainId, bool _enabled, uint16 _feeBp) public virtual onlyOwner { require(_feeBp <= BP_DENOMINATOR, "Fee: fee bp must be <= BP_DENOMINATOR"); chainIdToFeeBps[_dstChainId] = FeeConfig(_feeBp, _enabled); emit SetFeeBp(_dstChainId, _enabled, _feeBp); } function setFeeOwner(address _feeOwner) public virtual onlyOwner { require(_feeOwner != address(0x0), "Fee: feeOwner cannot be 0x"); feeOwner = _feeOwner; emit SetFeeOwner(_feeOwner); } function quoteOFTFee(uint16 _dstChainId, uint _amount) public view virtual returns (uint fee) { FeeConfig memory config = chainIdToFeeBps[_dstChainId]; if (config.enabled) { fee = (_amount * config.feeBP) / BP_DENOMINATOR; } else if (defaultFeeBp > 0) { fee = (_amount * defaultFeeBp) / BP_DENOMINATOR; } else { fee = 0; } } function _payOFTFee(address _from, uint16 _dstChainId, uint _amount) internal virtual returns (uint amount, uint fee) { fee = quoteOFTFee(_dstChainId, _amount); amount = _amount - fee; if (fee > 0) { _transferFrom(_from, feeOwner, fee); } } function _transferFrom(address _from, address _to, uint _amount) internal virtual returns (uint); } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } abstract contract BaseOFTWithFee is OFTCoreV2, Fee, ERC165, IOFTWithFee { constructor(uint8 _sharedDecimals, address _lzEndpoint) OFTCoreV2(_sharedDecimals, _lzEndpoint) {} /************************************************************************ * public functions ************************************************************************/ function sendFrom( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams ) public payable virtual override { (_amount, ) = _payOFTFee(_from, _dstChainId, _amount); _amount = _send( _from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams ); require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); } function sendAndCall( address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams ) public payable virtual override { (_amount, ) = _payOFTFee(_from, _dstChainId, _amount); _amount = _sendAndCall( _from, _dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams ); require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); } /************************************************************************ * public view functions ************************************************************************/ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IOFTWithFee).interfaceId || super.supportsInterface(interfaceId); } function estimateSendFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams ) public view virtual override returns (uint nativeFee, uint zroFee) { return _estimateSendFee(_dstChainId, _toAddress, _amount, _useZro, _adapterParams); } function estimateSendAndCallFee( uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, bool _useZro, bytes calldata _adapterParams ) public view virtual override returns (uint nativeFee, uint zroFee) { return _estimateSendAndCallFee(_dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _useZro, _adapterParams); } function circulatingSupply() public view virtual override returns (uint); function token() public view virtual override returns (address); function _transferFrom(address _from, address _to, uint _amount) internal virtual override(Fee, OFTCoreV2) returns (uint); } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is 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. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } contract ProxyOFTWithFee is BaseOFTWithFee { using SafeERC20 for IERC20; IERC20 internal immutable innerToken; uint internal immutable ld2sdRate; // total amount is transferred from this chain to other chains, ensuring the total is less than uint64.max in sd uint public outboundAmount; constructor(address _token, uint8 _sharedDecimals, address _lzEndpoint) BaseOFTWithFee(_sharedDecimals, _lzEndpoint) { innerToken = IERC20(_token); (bool success, bytes memory data) = _token.staticcall(abi.encodeWithSignature("decimals()")); require(success, "ProxyOFTWithFee: failed to get token decimals"); uint8 decimals = abi.decode(data, (uint8)); require(_sharedDecimals <= decimals, "ProxyOFTWithFee: sharedDecimals must be <= decimals"); ld2sdRate = 10 ** (decimals - _sharedDecimals); } /************************************************************************ * public functions ************************************************************************/ function circulatingSupply() public view virtual override returns (uint) { return innerToken.totalSupply() - outboundAmount; } function token() public view virtual override returns (address) { return address(innerToken); } /************************************************************************ * internal functions ************************************************************************/ function _debitFrom(address _from, uint16, bytes32, uint _amount) internal virtual override returns (uint) { require(_from == _msgSender(), "ProxyOFTWithFee: owner is not send caller"); _amount = _transferFrom(_from, address(this), _amount); // _amount still may have dust if the token has transfer fee, then give the dust back to the sender (uint amount, uint dust) = _removeDust(_amount); if (dust > 0) innerToken.safeTransfer(_from, dust); // check total outbound amount outboundAmount += amount; uint cap = _sd2ld(type(uint64).max); require(cap >= outboundAmount, "ProxyOFTWithFee: outboundAmount overflow"); return amount; } function _creditTo(uint16, address _toAddress, uint _amount) internal virtual override returns (uint) { outboundAmount -= _amount; // tokens are already in this contract, so no need to transfer if (_toAddress == address(this)) { return _amount; } return _transferFrom(address(this), _toAddress, _amount); } function _transferFrom(address _from, address _to, uint _amount) internal virtual override returns (uint) { uint before = innerToken.balanceOf(_to); if (_from == address(this)) { innerToken.safeTransfer(_to, _amount); } else { innerToken.safeTransferFrom(_from, _to, _amount); } return innerToken.balanceOf(_to) - before; } function _ld2sdRate() internal view virtual override returns (uint) { return ld2sdRate; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint8","name":"_sharedDecimals","type":"uint8"},{"internalType":"address","name":"_lzEndpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"CallOFTReceivedSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"NonContractAddress","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":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"feeBp","type":"uint16"}],"name":"SetDefaultFeeBp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"dstchainId","type":"uint16"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"},{"indexed":false,"internalType":"uint16","name":"feeBp","type":"uint16"}],"name":"SetFeeBp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeOwner","type":"address"}],"name":"SetFeeOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"inputs":[],"name":"BP_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NO_EXTRA_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_SEND","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_SEND_AND_CALL","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes32","name":"_from","type":"bytes32"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint256","name":"_gasForCall","type":"uint256"}],"name":"callOnOFTReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"chainIdToFeeBps","outputs":[{"internalType":"uint16","name":"feeBP","type":"uint16"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"creditedPackets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultFeeBp","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint64","name":"_dstGasForCall","type":"uint64"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendAndCallFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"outboundAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"payloadSizeLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"quoteOFTFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minAmount","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint64","name":"_dstGasForCall","type":"uint64"},{"components":[{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"address","name":"zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"adapterParams","type":"bytes"}],"internalType":"struct ICommonOFT.LzCallParams","name":"_callParams","type":"tuple"}],"name":"sendAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes32","name":"_toAddress","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minAmount","type":"uint256"},{"components":[{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"address","name":"zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"adapterParams","type":"bytes"}],"internalType":"struct ICommonOFT.LzCallParams","name":"_callParams","type":"tuple"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_feeBp","type":"uint16"}],"name":"setDefaultFeeBp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bool","name":"_enabled","type":"bool"},{"internalType":"uint16","name":"_feeBp","type":"uint16"}],"name":"setFeeBp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeOwner","type":"address"}],"name":"setFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b506040516200498f3803806200498f8339810160408190526200003591620002c6565b818181818080620000463362000247565b6001600160a01b0316608052505060ff1660a0526200006d6000546001600160a01b031690565b600880546001600160a01b03928316620100000262010000600160b01b0319909116179055851660c081905260408051600481526024810182526020810180516001600160e01b031663313ce56760e01b179052905160009450849350620000d6919062000310565b600060405180830381855afa9150503d806000811462000113576040519150601f19603f3d011682016040523d82523d6000602084013e62000118565b606091505b509150915081620001865760405162461bcd60e51b815260206004820152602d60248201527f50726f78794f4654576974684665653a206661696c656420746f20676574207460448201526c6f6b656e20646563696d616c7360981b60648201526084015b60405180910390fd5b6000818060200190518101906200019e919062000341565b90508060ff168560ff1611156200021e5760405162461bcd60e51b815260206004820152603360248201527f50726f78794f4654576974684665653a20736861726564446563696d616c732060448201527f6d757374206265203c3d20646563696d616c730000000000000000000000000060648201526084016200017d565b6200022a85826200037c565b6200023790600a6200049b565b60e05250620004ac945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620002af57600080fd5b919050565b805160ff81168114620002af57600080fd5b600080600060608486031215620002dc57600080fd5b620002e78462000297565b9250620002f760208501620002b4565b9150620003076040850162000297565b90509250925092565b6000825160005b8181101562000333576020818601810151858301520162000317565b506000920191825250919050565b6000602082840312156200035457600080fd5b6200035f82620002b4565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff828116828216039081111562000398576200039862000366565b92915050565b600181815b80851115620003df578160001904821115620003c357620003c362000366565b80851615620003d157918102915b93841c9390800290620003a3565b509250929050565b600082620003f85750600162000398565b81620004075750600062000398565b81600181146200042057600281146200042b576200044b565b600191505062000398565b60ff8411156200043f576200043f62000366565b50506001821b62000398565b5060208310610133831016604e8410600b841016171562000470575081810a62000398565b6200047c83836200039e565b806000190482111562000493576200049362000366565b029392505050565b60006200035f60ff841683620003e7565b60805160a05160c05160e0516144326200055d600039600081816126df0152818161287e0152612ee001526000818161092c015281816113580152818161234f015281816123d9015281816124120152818161245b01526127b4015260006105780152600081816107290152818161095301528181610bd901528181610c8101528181610e9c0152818161167601528181611c1601528181611f040152818161229d0152612a2501526144326000f3fe6080604052600436106102875760003560e01c80639358928b1161015a578063c83330ce116100c1578063eaffd49a1161007a578063eaffd49a1461087d578063eb8d72b71461089d578063ecd8f212146108bd578063f2fde38b146108dd578063f5ecbdbc146108fd578063fc0c546a1461091d57600080fd5b8063c83330ce14610791578063cbed8b9c146107e7578063d1deba1f14610807578063d88829681461081a578063df2a5b3b14610848578063e6a20ae61461086857600080fd5b8063a6c3d16511610113578063a6c3d165146106e1578063abe685cd14610701578063b353aaa714610717578063b9818be11461074b578063baf3292d14610771578063c44618341461070157600080fd5b80639358928b14610604578063950c8a74146106195780639689cb05146106395780639bdb98121461064f5780639f38369a146106a1578063a4c51df5146106c157600080fd5b8063455ba27d116101fe578063715018a6116101b7578063715018a6146105045780637533d7881461051957806379c0ad4b14610546578063857749b0146105665780638cfd8f5c1461059a5780638da5cb5b146105d257600080fd5b8063455ba27d1461041b5780634b104eff1461042e5780634c42899a1461044e5780635a359dc5146104755780635b8c41e61461049557806366ad5c8a146104e457600080fd5b80632cdf0b95116102505780632cdf0b9514610343578063365260b4146103565780633d8b38f61461038b5780633f1f4fa4146103ab57806342d65a8d146103e6578063447705151461040657600080fd5b80621d35671461028c57806301ffc9a7146102ae57806307e0db17146102e35780630df374831461030357806310ddb13714610323575b600080fd5b34801561029857600080fd5b506102ac6102a7366004613484565b610950565b005b3480156102ba57600080fd5b506102ce6102c9366004613517565b610b81565b60405190151581526020015b60405180910390f35b3480156102ef57600080fd5b506102ac6102fe366004613541565b610bb8565b34801561030f57600080fd5b506102ac61031e36600461355c565b610c41565b34801561032f57600080fd5b506102ac61033e366004613541565b610c60565b6102ac6103513660046135b3565b610cb8565b34801561036257600080fd5b5061037661037136600461363c565b610d5b565b604080519283526020830191909152016102da565b34801561039757600080fd5b506102ce6103a63660046136a3565b610db0565b3480156103b757600080fd5b506103d86103c6366004613541565b60036020526000908152604090205481565b6040519081526020016102da565b3480156103f257600080fd5b506102ac6104013660046136a3565b610e7d565b34801561041257600080fd5b506103d8600081565b6102ac6104293660046136f5565b610f03565b34801561043a57600080fd5b506102ac6104493660046137b1565b610fe4565b34801561045a57600080fd5b50610463600081565b60405160ff90911681526020016102da565b34801561048157600080fd5b506102ac610490366004613541565b6110a1565b3480156104a157600080fd5b506103d86104b036600461383b565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156104f057600080fd5b506102ac6104ff366004613484565b611113565b34801561051057600080fd5b506102ac6111e7565b34801561052557600080fd5b50610539610534366004613541565b6111fb565b6040516102da919061392b565b34801561055257600080fd5b506102ac61056136600461393e565b611295565b34801561057257600080fd5b506104637f000000000000000000000000000000000000000000000000000000000000000081565b3480156105a657600080fd5b506103d86105b536600461397a565b600260209081526000928352604080842090915290825290205481565b3480156105de57600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016102da565b34801561061057600080fd5b506103d8611351565b34801561062557600080fd5b506004546105ec906001600160a01b031681565b34801561064557600080fd5b506103d860095481565b34801561065b57600080fd5b506102ce61066a36600461383b565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205460ff1681565b3480156106ad57600080fd5b506105396106bc366004613541565b6113e7565b3480156106cd57600080fd5b506103766106dc3660046139ad565b6114f6565b3480156106ed57600080fd5b506102ac6106fc3660046136a3565b611585565b34801561070d57600080fd5b506103d861271081565b34801561072357600080fd5b506105ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561075757600080fd5b506008546105ec906201000090046001600160a01b031681565b34801561077d57600080fd5b506102ac61078c3660046137b1565b611601565b34801561079d57600080fd5b506107cd6107ac366004613541565b60076020526000908152604090205461ffff81169062010000900460ff1682565b6040805161ffff90931683529015156020830152016102da565b3480156107f357600080fd5b506102ac610802366004613a6a565b611657565b6102ac610815366004613484565b6116e1565b34801561082657600080fd5b506008546108359061ffff1681565b60405161ffff90911681526020016102da565b34801561085457600080fd5b506102ac610863366004613ad8565b6118f7565b34801561087457600080fd5b50610463600181565b34801561088957600080fd5b506102ac610898366004613b14565b611961565b3480156108a957600080fd5b506102ac6108b83660046136a3565b611a80565b3480156108c957600080fd5b506103d86108d836600461355c565b611ada565b3480156108e957600080fd5b506102ac6108f83660046137b1565b611b6c565b34801561090957600080fd5b50610539610918366004613bdc565b611be5565b34801561092957600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006105ec565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146109cd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff8616600090815260016020526040812080546109eb90613c29565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1790613c29565b8015610a645780601f10610a3957610100808354040283529160200191610a64565b820191906000526020600020905b815481529060010190602001808311610a4757829003601f168201915b50505050509050805186869050148015610a7f575060008151115b8015610aa7575080516020820120604051610a9d9088908890613c5d565b6040518091039020145b610b025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b60648201526084016109c4565b610b788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250611c9892505050565b50505050505050565b60006001600160e01b03198216630d30953d60e31b1480610bb257506301ffc9a760e01b6001600160e01b03198316145b92915050565b610bc0611d11565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610c2657600080fd5b505af1158015610c3a573d6000803e3d6000fd5b5050505050565b610c49611d11565b61ffff909116600090815260036020526040902055565b610c68611d11565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610c0c565b610cc3868685611d6b565b509250610d3186868686610cda60208701876137b1565b610cea60408801602089016137b1565b610cf76040890189613c6d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611db492505050565b925081831015610d535760405162461bcd60e51b81526004016109c490613cb3565b505050505050565b600080610da18888888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ed892505050565b91509150965096945050505050565b61ffff831660009081526001602052604081208054829190610dd190613c29565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfd90613c29565b8015610e4a5780601f10610e1f57610100808354040283529160200191610e4a565b820191906000526020600020905b815481529060010190602001808311610e2d57829003601f168201915b505050505090508383604051610e61929190613c5d565b60405180910390208180519060200120149150505b9392505050565b610e85611d11565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d90610ed590869086908690600401613d29565b600060405180830381600087803b158015610eef57600080fd5b505af1158015610b78573d6000803e3d6000fd5b610f0e898988611d6b565b5080965050610fb78989898988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250610f6091505060208901896137b1565b610f7060408a0160208b016137b1565b610f7d60408b018b613c6d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f9092505050565b955084861015610fd95760405162461bcd60e51b81526004016109c490613cb3565b505050505050505050565b610fec611d11565b6001600160a01b0381166110425760405162461bcd60e51b815260206004820152601a60248201527f4665653a206665654f776e65722063616e6e6f7420626520307800000000000060448201526064016109c4565b6008805462010000600160b01b031916620100006001600160a01b038416908102919091179091556040519081527f047912631afa564eebd3db2efe191a0dec62da1fede6bbbc1ffc89d87845b1b5906020015b60405180910390a150565b6110a9611d11565b6127108161ffff1611156110cf5760405162461bcd60e51b81526004016109c490613d47565b6008805461ffff191661ffff83169081179091556040519081527fd26030ef4a8c225ee12b646eb4466acb41fb96b6cd4660b22d0ba0124e7bdc7490602001611096565b3330146111715760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b60648201526084016109c4565b610d538686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f89018190048102820181019092528781528993509150879087908190840183828082843760009201919091525061208c92505050565b6111ef611d11565b6111f96000612113565b565b6001602052600090815260409020805461121490613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461124090613c29565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b505050505081565b61129d611d11565b6127108161ffff1611156112c35760405162461bcd60e51b81526004016109c490613d47565b60408051808201825261ffff83811680835285151560208085018281528985166000818152600784528890209651875492511515620100000262ffffff1990931696169590951717909455845192835292820192909252918201527fdd9c9685af3e6dcb56d8f4b88d2595d4add6837a150034e7781c46b6dcf8aaab906060015b60405180910390a1505050565b60006009547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d89190613d8c565b6113e29190613dbb565b905090565b61ffff811660009081526001602052604081208054606092919061140a90613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461143690613c29565b80156114835780601f1061145857610100808354040283529160200191611483565b820191906000526020600020905b81548152906001019060200180831161146657829003601f168201915b5050505050905080516000036114db5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f726400000060448201526064016109c4565b610e766000601483516114ee9190613dbb565b839190612163565b6000806115738b8b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8d018190048102820181019092528b81528e93508d9250908c908c908190840183828082843760009201919091525061227092505050565b91509150995099975050505050505050565b61158d611d11565b8181306040516020016115a293929190613dce565b60408051601f1981840301815291815261ffff85166000908152600160205220906115cd9082613e3a565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce83838360405161134493929190613d29565b611609611d11565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611096565b61165f611d11565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c906116b39088908890889088908890600401613ef9565b600060405180830381600087803b1580156116cd57600080fd5b505af1158015610fd9573d6000803e3d6000fd5b61ffff861660009081526005602052604080822090516117049088908890613c5d565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806117845760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b60648201526084016109c4565b808383604051611795929190613c5d565b6040518091039020146117f45760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b60648201526084016109c4565b61ffff871660009081526005602052604080822090516118179089908990613c5d565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526118af918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061208c92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516118e6959493929190613f27565b60405180910390a150505050505050565b6118ff611d11565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611344565b3330146119b05760405162461bcd60e51b815260206004820152601f60248201527f4f4654436f72653a2063616c6c6572206d757374206265204f4654436f72650060448201526064016109c4565b6119bb30868661232b565b9350846001600160a01b03168a61ffff167fbf551ec93859b170f9b2141bd9298bf3f64322c6f7beb2543a0cb669834118bf866040516119fd91815260200190565b60405180910390a3604051633fe79aed60e11b81526001600160a01b03861690637fcf35da908390611a41908e908e908e908e908e908d908d908d90600401613f62565b600060405180830381600088803b158015611a5b57600080fd5b5087f1158015611a6f573d6000803e3d6000fd5b505050505050505050505050505050565b611a88611d11565b61ffff83166000908152600160205260409020611aa6828483613fbd565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab83838360405161134493929190613d29565b61ffff828116600090815260076020908152604080832081518083019092525493841681526201000090930460ff1615801591840191909152909190611b3f57805161271090611b2e9061ffff168561407c565b611b3891906140a9565b9150611b65565b60085461ffff1615611b605760085461271090611b2e9061ffff168561407c565b600091505b5092915050565b611b74611d11565b6001600160a01b038116611bd95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c4565b611be281612113565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015611c65573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c8d91908101906140bd565b90505b949350505050565b600080611cfb5a60966366ad5c8a60e01b89898989604051602401611cc0949392919061412a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906124db565b9150915081610d5357610d538686868685612565565b6000546001600160a01b031633146111f95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c4565b600080611d788484611ada565b9050611d848184613dbb565b91508015611dac57600854611daa9086906201000090046001600160a01b03168361232b565b505b935093915050565b6000611dc287828481612602565b611dcb856126d7565b509050611dda88888884612717565b905060008111611e285760405162461bcd60e51b815260206004820152601960248201527813d19510dbdc994e88185b5bdd5b9d081d1bdbc81cdb585b1b603a1b60448201526064016109c4565b6000611e7387611e3784612876565b6040805160006020820152602181019390935260c09190911b6001600160c01b0319166041830152805160298184030181526049909201905290565b9050611e838882878787346128fc565b86896001600160a01b03168961ffff167fd81fc9b8523134ed613870ed029d6170cbb73aa6a6bc311b9a642689fb9df59a85604051611ec491815260200190565b60405180910390a450979650505050505050565b6000806000611eea87611e3788612876565b60405163040a7bb160e41b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb1090611f41908b90309086908b908b90600401614168565b6040805180830381865afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8191906141bc565b92509250509550959350505050565b6000611fa8896001846001600160401b038916612602565b611fb1876126d7565b509050611fc08a8a8a84612717565b90506000811161200e5760405162461bcd60e51b815260206004820152601960248201527813d19510dbdc994e88185b5bdd5b9d081d1bdbc81cdb585b1b603a1b60448201526064016109c4565b6000612025338a61201e85612876565b8a8a612aa1565b90506120358a82878787346128fc565b888b6001600160a01b03168b61ffff167fd81fc9b8523134ed613870ed029d6170cbb73aa6a6bc311b9a642689fb9df59a8560405161207691815260200190565b60405180910390a4509998505050505050505050565b60006120988282612ae2565b905060ff81166120b3576120ae85858585612b3e565b610c3a565b60001960ff8216016120cb576120ae85858585612bce565b60405162461bcd60e51b815260206004820152601c60248201527f4f4654436f72653a20756e6b6e6f776e207061636b657420747970650000000060448201526064016109c4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60608161217181601f6141e0565b10156121b05760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016109c4565b6121ba82846141e0565b845110156121fe5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016109c4565b60608215801561221d5760405191506000825260208201604052612267565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561225657805183526020928301920161223e565b5050858452601f01601f1916604052505b50949350505050565b6000806000612283338a61201e8b612876565b60405163040a7bb160e41b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb10906122da908d90309086908b908b90600401614168565b6040805180830381865afa1580156122f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231a91906141bc565b925092505097509795505050505050565b6040516370a0823160e01b81526001600160a01b03838116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ba9190613d8c565b9050306001600160a01b03861603612405576124006001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585612ddd565b61243a565b61243a6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016868686612e45565b6040516370a0823160e01b81526001600160a01b03858116600483015282917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa1580156124a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c89190613d8c565b6124d29190613dbb565b95945050505050565b6000606060008060008661ffff166001600160401b03811115612500576125006137ce565b6040519080825280601f01601f19166020018201604052801561252a576020820181803683370190505b50905060008087516020890160008d8df191503d92508683111561254c578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff1681526020019081526020016000208560405161259691906141f3565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906125f3908790879087908790879061420f565b60405180910390a15050505050565b600061260d83612e7d565b61ffff8087166000908152600260209081526040808320938916835292905220549091508061267e5760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f742073657400000000000060448201526064016109c4565b61268883826141e0565b821015610d535760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f77000000000060448201526064016109c4565b6000806127047f000000000000000000000000000000000000000000000000000000000000000084614261565b90506127108184613dbb565b9150915091565b60006001600160a01b03851633146127835760405162461bcd60e51b815260206004820152602960248201527f50726f78794f4654576974684665653a206f776e6572206973206e6f7420736560448201526837321031b0b63632b960b91b60648201526084016109c4565b61278e85308461232b565b915060008061279c846126d7565b909250905080156127db576127db6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168883612ddd565b81600960008282546127ed91906141e0565b90915550600090506128056001600160401b03612ed9565b905060095481101561286a5760405162461bcd60e51b815260206004820152602860248201527f50726f78794f4654576974684665653a206f7574626f756e64416d6f756e74206044820152676f766572666c6f7760c01b60648201526084016109c4565b50909695505050505050565b6000806128a37f0000000000000000000000000000000000000000000000000000000000000000846140a9565b90506001600160401b03811115610bb25760405162461bcd60e51b815260206004820152601a60248201527f4f4654436f72653a20616d6f756e745344206f766572666c6f7700000000000060448201526064016109c4565b61ffff86166000908152600160205260408120805461291a90613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461294690613c29565b80156129935780601f1061296857610100808354040283529160200191612993565b820191906000526020600020905b81548152906001019060200180831161297657829003601f168201915b505050505090508051600003612a045760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b60648201526084016109c4565b612a0f878751612f0e565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490612a66908b9086908c908c908c908c90600401614275565b6000604051808303818588803b158015612a7f57600080fd5b505af1158015612a93573d6000803e3d6000fd5b505050505050505050505050565b6060600185856001600160a01b0389168587604051602001612ac8969594939291906142dc565b604051602081830303815290604052905095945050505050565b6000612aef8260016141e0565b83511015612b355760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016109c4565b50016001015190565b600080612b4a83612f7f565b90925090506001600160a01b038216612b635761dead91505b6000612b6e82612ed9565b9050612b7b878483613004565b9050826001600160a01b03168761ffff167fbf551ec93859b170f9b2141bd9298bf3f64322c6f7beb2543a0cb669834118bf83604051612bbd91815260200190565b60405180910390a350505050505050565b6000806000806000612bdf8661303f565b945094509450945094506000600660008b61ffff1661ffff16815260200190815260200160002089604051612c1491906141f3565b90815260408051602092819003830190206001600160401b038b166000908152925281205460ff169150612c4785612ed9565b905081612cb557612c598b3083613004565b61ffff8c16600090815260066020526040908190209051919250600191612c81908d906141f3565b90815260408051602092819003830190206001600160401b038d16600090815292529020805460ff19169115159190911790555b6001600160a01b0386163b612d0c576040516001600160a01b03871681527f9aedf5fdba8716db3b6705ca00150643309995d4f818a249ed6dde6677e7792d9060200160405180910390a150505050505050612dd7565b8a8a8a8a8a8a868a60008a612d2a578b6001600160401b0316612d2c565b5a5b9050600080612d5e5a609663eaffd49a60e01b8e8e8e8d8d8d8d8d604051602401611cc098979695949392919061433d565b915091508115612db7578751602089012060405161ffff8d16907fb8890edbfc1c74692f527444645f95489c3703cc2df42e4a366f5d06fa6cd88490612da9908e908e9086906143b1565b60405180910390a250612dc4565b612dc48b8b8b8b85612565565b5050505050505050505050505050505050505b50505050565b6040516001600160a01b038316602482015260448101829052612e4090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526130f6565b505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612dd79085906323b872dd60e01b90608401612e09565b6000602282511015612ed15760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d730000000060448201526064016109c4565b506022015190565b6000610bb27f00000000000000000000000000000000000000000000000000000000000000006001600160401b03841661407c565b61ffff821660009081526003602052604081205490819003612f2f57506127105b80821115612e405760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c6172676560448201526064016109c4565b60008080612f8d8482612ae2565b60ff16148015612f9e575082516029145b612fe55760405162461bcd60e51b815260206004820152601860248201527713d19510dbdc994e881a5b9d985b1a59081c185e5b1bd85960421b60448201526064016109c4565b612ff083600d6131cb565b9150612ffd836021613230565b9050915091565b600081600960008282546130189190613dbb565b9091555050306001600160a01b03841603613034575080610e76565b611c9030848461232b565b6000808060608160016130528783612ae2565b60ff161461309d5760405162461bcd60e51b815260206004820152601860248201527713d19510dbdc994e881a5b9d985b1a59081c185e5b1bd85960421b60448201526064016109c4565b6130a886600d6131cb565b93506130b5866021613230565b92506130c286602961328d565b94506130cf866049613230565b90506130eb60518088516130e39190613dbb565b889190612163565b915091939590929450565b600061314b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166132eb9092919063ffffffff16565b905080516000148061316c57508080602001905181019061316c91906143df565b612e405760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c4565b60006131d88260146141e0565b835110156132205760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016109c4565b500160200151600160601b900490565b600061323d8260086141e0565b835110156132845760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016109c4565b50016008015190565b600061329a8260206141e0565b835110156132e25760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b60448201526064016109c4565b50016020015190565b6060611c90848460008585600080866001600160a01b0316858760405161331291906141f3565b60006040518083038185875af1925050503d806000811461334f576040519150601f19603f3d011682016040523d82523d6000602084013e613354565b606091505b509150915061336587838387613370565b979650505050505050565b606083156133df5782516000036133d8576001600160a01b0385163b6133d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c4565b5081611c90565b611c9083838151156133f45781518083602001fd5b8060405162461bcd60e51b81526004016109c4919061392b565b803561ffff8116811461342057600080fd5b919050565b60008083601f84011261343757600080fd5b5081356001600160401b0381111561344e57600080fd5b60208301915083602082850101111561346657600080fd5b9250929050565b80356001600160401b038116811461342057600080fd5b6000806000806000806080878903121561349d57600080fd5b6134a68761340e565b955060208701356001600160401b03808211156134c257600080fd5b6134ce8a838b01613425565b90975095508591506134e260408a0161346d565b945060608901359150808211156134f857600080fd5b5061350589828a01613425565b979a9699509497509295939492505050565b60006020828403121561352957600080fd5b81356001600160e01b031981168114610e7657600080fd5b60006020828403121561355357600080fd5b610e768261340e565b6000806040838503121561356f57600080fd5b6135788361340e565b946020939093013593505050565b6001600160a01b0381168114611be257600080fd5b6000606082840312156135ad57600080fd5b50919050565b60008060008060008060c087890312156135cc57600080fd5b86356135d781613586565b95506135e56020880161340e565b945060408701359350606087013592506080870135915060a08701356001600160401b0381111561361557600080fd5b61362189828a0161359b565b9150509295509295509295565b8015158114611be257600080fd5b60008060008060008060a0878903121561365557600080fd5b61365e8761340e565b95506020870135945060408701359350606087013561367c8161362e565b925060808701356001600160401b0381111561369757600080fd5b61350589828a01613425565b6000806000604084860312156136b857600080fd5b6136c18461340e565b925060208401356001600160401b038111156136dc57600080fd5b6136e886828701613425565b9497909650939450505050565b60008060008060008060008060006101008a8c03121561371457600080fd5b893561371f81613586565b985061372d60208b0161340e565b975060408a0135965060608a0135955060808a0135945060a08a01356001600160401b038082111561375e57600080fd5b61376a8d838e01613425565b909650945084915061377e60c08d0161346d565b935060e08c013591508082111561379457600080fd5b506137a18c828d0161359b565b9150509295985092959850929598565b6000602082840312156137c357600080fd5b8135610e7681613586565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561380c5761380c6137ce565b604052919050565b60006001600160401b0382111561382d5761382d6137ce565b50601f01601f191660200190565b60008060006060848603121561385057600080fd5b6138598461340e565b925060208401356001600160401b0381111561387457600080fd5b8401601f8101861361388557600080fd5b803561389861389382613814565b6137e4565b8181528760208385010111156138ad57600080fd5b816020840160208301376000602083830101528094505050506138d26040850161346d565b90509250925092565b60005b838110156138f65781810151838201526020016138de565b50506000910152565b600081518084526139178160208601602086016138db565b601f01601f19169290920160200192915050565b602081526000610e7660208301846138ff565b60008060006060848603121561395357600080fd5b61395c8461340e565b9250602084013561396c8161362e565b91506138d26040850161340e565b6000806040838503121561398d57600080fd5b6139968361340e565b91506139a46020840161340e565b90509250929050565b600080600080600080600080600060e08a8c0312156139cb57600080fd5b6139d48a61340e565b985060208a0135975060408a0135965060608a01356001600160401b03808211156139fe57600080fd5b613a0a8d838e01613425565b9098509650869150613a1e60808d0161346d565b955060a08c01359150613a308261362e565b90935060c08b01359080821115613a4657600080fd5b50613a538c828d01613425565b915080935050809150509295985092959850929598565b600080600080600060808688031215613a8257600080fd5b613a8b8661340e565b9450613a996020870161340e565b93506040860135925060608601356001600160401b03811115613abb57600080fd5b613ac788828901613425565b969995985093965092949392505050565b600080600060608486031215613aed57600080fd5b613af68461340e565b9250613b046020850161340e565b9150604084013590509250925092565b6000806000806000806000806000806101008b8d031215613b3457600080fd5b613b3d8b61340e565b995060208b01356001600160401b0380821115613b5957600080fd5b613b658e838f01613425565b909b509950899150613b7960408e0161346d565b985060608d0135975060808d01359150613b9282613586565b90955060a08c0135945060c08c01359080821115613baf57600080fd5b50613bbc8d828e01613425565b9150809450508092505060e08b013590509295989b9194979a5092959850565b60008060008060808587031215613bf257600080fd5b613bfb8561340e565b9350613c096020860161340e565b92506040850135613c1981613586565b9396929550929360600135925050565b600181811c90821680613c3d57607f821691505b6020821081036135ad57634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6000808335601e19843603018112613c8457600080fd5b8301803591506001600160401b03821115613c9e57600080fd5b60200191503681900382131561346657600080fd5b6020808252602d908201527f426173654f4654576974684665653a20616d6f756e74206973206c657373207460408201526c1a185b881b5a5b905b5bdd5b9d609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000611c8d604083018486613d00565b60208082526025908201527f4665653a20666565206270206d757374206265203c3d2042505f44454e4f4d496040820152642720aa27a960d91b606082015260800190565b600060208284031215613d9e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bb257610bb2613da5565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f821115612e4057600081815260208120601f850160051c81016020861015613e1b5750805b601f850160051c820191505b81811015610d5357828155600101613e27565b81516001600160401b03811115613e5357613e536137ce565b613e6781613e618454613c29565b84613df4565b602080601f831160018114613e9c5760008415613e845750858301515b600019600386901b1c1916600185901b178555610d53565b600085815260208120601f198616915b82811015613ecb57888601518255948401946001909101908401613eac565b5085821015613ee95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600061ffff808816835280871660208401525084604083015260806060830152613365608083018486613d00565b61ffff86168152608060208201526000613f45608083018688613d00565b6001600160401b0394909416604083015250606001529392505050565b61ffff8916815260c060208201526000613f8060c08301898b613d00565b6001600160401b038816604084015286606084015285608084015282810360a0840152613fae818587613d00565b9b9a5050505050505050505050565b6001600160401b03831115613fd457613fd46137ce565b613fe883613fe28354613c29565b83613df4565b6000601f84116001811461401c57600085156140045750838201355b600019600387901b1c1916600186901b178355610c3a565b600083815260209020601f19861690835b8281101561404d578685013582556020948501946001909201910161402d565b508682101561406a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b8082028115828204841417610bb257610bb2613da5565b634e487b7160e01b600052601260045260246000fd5b6000826140b8576140b8614093565b500490565b6000602082840312156140cf57600080fd5b81516001600160401b038111156140e557600080fd5b8201601f810184136140f657600080fd5b805161410461389382613814565b81815285602083850101111561411957600080fd5b6124d28260208301602086016138db565b61ffff8516815260806020820152600061414760808301866138ff565b6001600160401b0385166040840152828103606084015261336581856138ff565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614196908301866138ff565b841515606084015282810360808401526141b081856138ff565b98975050505050505050565b600080604083850312156141cf57600080fd5b505080516020909101519092909150565b80820180821115610bb257610bb2613da5565b600082516142058184602087016138db565b9190910192915050565b61ffff8616815260a06020820152600061422c60a08301876138ff565b6001600160401b0386166040840152828103606084015261424d81866138ff565b905082810360808401526141b081856138ff565b60008261427057614270614093565b500690565b61ffff8716815260c06020820152600061429260c08301886138ff565b82810360408401526142a481886138ff565b6001600160a01b0387811660608601528616608085015283810360a085015290506142cf81856138ff565b9998505050505050505050565b60ff60f81b8760f81b16815285600182015260006001600160401b0360c01b808760c01b166021840152856029840152808560c01b16604984015250825161432b8160518501602087016138db565b91909101605101979650505050505050565b600061010061ffff8b16835280602084015261435b8184018b6138ff565b6001600160401b038a166040850152606084018990526001600160a01b038816608085015260a0840187905283810360c0850152905061439b81866138ff565b9150508260e08301529998505050505050505050565b6060815260006143c460608301866138ff565b6001600160401b039490941660208301525060400152919050565b6000602082840312156143f157600080fd5b8151610e768161362e56fea26469706673582212204495807a73f54df216e7031f0d93c92bdc992182a5b4b976b789686dedbed27264736f6c63430008140033000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Deployed Bytecode
0x6080604052600436106102875760003560e01c80639358928b1161015a578063c83330ce116100c1578063eaffd49a1161007a578063eaffd49a1461087d578063eb8d72b71461089d578063ecd8f212146108bd578063f2fde38b146108dd578063f5ecbdbc146108fd578063fc0c546a1461091d57600080fd5b8063c83330ce14610791578063cbed8b9c146107e7578063d1deba1f14610807578063d88829681461081a578063df2a5b3b14610848578063e6a20ae61461086857600080fd5b8063a6c3d16511610113578063a6c3d165146106e1578063abe685cd14610701578063b353aaa714610717578063b9818be11461074b578063baf3292d14610771578063c44618341461070157600080fd5b80639358928b14610604578063950c8a74146106195780639689cb05146106395780639bdb98121461064f5780639f38369a146106a1578063a4c51df5146106c157600080fd5b8063455ba27d116101fe578063715018a6116101b7578063715018a6146105045780637533d7881461051957806379c0ad4b14610546578063857749b0146105665780638cfd8f5c1461059a5780638da5cb5b146105d257600080fd5b8063455ba27d1461041b5780634b104eff1461042e5780634c42899a1461044e5780635a359dc5146104755780635b8c41e61461049557806366ad5c8a146104e457600080fd5b80632cdf0b95116102505780632cdf0b9514610343578063365260b4146103565780633d8b38f61461038b5780633f1f4fa4146103ab57806342d65a8d146103e6578063447705151461040657600080fd5b80621d35671461028c57806301ffc9a7146102ae57806307e0db17146102e35780630df374831461030357806310ddb13714610323575b600080fd5b34801561029857600080fd5b506102ac6102a7366004613484565b610950565b005b3480156102ba57600080fd5b506102ce6102c9366004613517565b610b81565b60405190151581526020015b60405180910390f35b3480156102ef57600080fd5b506102ac6102fe366004613541565b610bb8565b34801561030f57600080fd5b506102ac61031e36600461355c565b610c41565b34801561032f57600080fd5b506102ac61033e366004613541565b610c60565b6102ac6103513660046135b3565b610cb8565b34801561036257600080fd5b5061037661037136600461363c565b610d5b565b604080519283526020830191909152016102da565b34801561039757600080fd5b506102ce6103a63660046136a3565b610db0565b3480156103b757600080fd5b506103d86103c6366004613541565b60036020526000908152604090205481565b6040519081526020016102da565b3480156103f257600080fd5b506102ac6104013660046136a3565b610e7d565b34801561041257600080fd5b506103d8600081565b6102ac6104293660046136f5565b610f03565b34801561043a57600080fd5b506102ac6104493660046137b1565b610fe4565b34801561045a57600080fd5b50610463600081565b60405160ff90911681526020016102da565b34801561048157600080fd5b506102ac610490366004613541565b6110a1565b3480156104a157600080fd5b506103d86104b036600461383b565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156104f057600080fd5b506102ac6104ff366004613484565b611113565b34801561051057600080fd5b506102ac6111e7565b34801561052557600080fd5b50610539610534366004613541565b6111fb565b6040516102da919061392b565b34801561055257600080fd5b506102ac61056136600461393e565b611295565b34801561057257600080fd5b506104637f000000000000000000000000000000000000000000000000000000000000000881565b3480156105a657600080fd5b506103d86105b536600461397a565b600260209081526000928352604080842090915290825290205481565b3480156105de57600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016102da565b34801561061057600080fd5b506103d8611351565b34801561062557600080fd5b506004546105ec906001600160a01b031681565b34801561064557600080fd5b506103d860095481565b34801561065b57600080fd5b506102ce61066a36600461383b565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205460ff1681565b3480156106ad57600080fd5b506105396106bc366004613541565b6113e7565b3480156106cd57600080fd5b506103766106dc3660046139ad565b6114f6565b3480156106ed57600080fd5b506102ac6106fc3660046136a3565b611585565b34801561070d57600080fd5b506103d861271081565b34801561072357600080fd5b506105ec7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67581565b34801561075757600080fd5b506008546105ec906201000090046001600160a01b031681565b34801561077d57600080fd5b506102ac61078c3660046137b1565b611601565b34801561079d57600080fd5b506107cd6107ac366004613541565b60076020526000908152604090205461ffff81169062010000900460ff1682565b6040805161ffff90931683529015156020830152016102da565b3480156107f357600080fd5b506102ac610802366004613a6a565b611657565b6102ac610815366004613484565b6116e1565b34801561082657600080fd5b506008546108359061ffff1681565b60405161ffff90911681526020016102da565b34801561085457600080fd5b506102ac610863366004613ad8565b6118f7565b34801561087457600080fd5b50610463600181565b34801561088957600080fd5b506102ac610898366004613b14565b611961565b3480156108a957600080fd5b506102ac6108b83660046136a3565b611a80565b3480156108c957600080fd5b506103d86108d836600461355c565b611ada565b3480156108e957600080fd5b506102ac6108f83660046137b1565b611b6c565b34801561090957600080fd5b50610539610918366004613bdc565b611be5565b34801561092957600080fd5b507f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb96105ec565b337f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316146109cd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff8616600090815260016020526040812080546109eb90613c29565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1790613c29565b8015610a645780601f10610a3957610100808354040283529160200191610a64565b820191906000526020600020905b815481529060010190602001808311610a4757829003601f168201915b50505050509050805186869050148015610a7f575060008151115b8015610aa7575080516020820120604051610a9d9088908890613c5d565b6040518091039020145b610b025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b60648201526084016109c4565b610b788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250611c9892505050565b50505050505050565b60006001600160e01b03198216630d30953d60e31b1480610bb257506301ffc9a760e01b6001600160e01b03198316145b92915050565b610bc0611d11565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610c2657600080fd5b505af1158015610c3a573d6000803e3d6000fd5b5050505050565b610c49611d11565b61ffff909116600090815260036020526040902055565b610c68611d11565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906310ddb13790602401610c0c565b610cc3868685611d6b565b509250610d3186868686610cda60208701876137b1565b610cea60408801602089016137b1565b610cf76040890189613c6d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611db492505050565b925081831015610d535760405162461bcd60e51b81526004016109c490613cb3565b505050505050565b600080610da18888888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ed892505050565b91509150965096945050505050565b61ffff831660009081526001602052604081208054829190610dd190613c29565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfd90613c29565b8015610e4a5780601f10610e1f57610100808354040283529160200191610e4a565b820191906000526020600020905b815481529060010190602001808311610e2d57829003601f168201915b505050505090508383604051610e61929190613c5d565b60405180910390208180519060200120149150505b9392505050565b610e85611d11565b6040516342d65a8d60e01b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906342d65a8d90610ed590869086908690600401613d29565b600060405180830381600087803b158015610eef57600080fd5b505af1158015610b78573d6000803e3d6000fd5b610f0e898988611d6b565b5080965050610fb78989898988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250610f6091505060208901896137b1565b610f7060408a0160208b016137b1565b610f7d60408b018b613c6d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f9092505050565b955084861015610fd95760405162461bcd60e51b81526004016109c490613cb3565b505050505050505050565b610fec611d11565b6001600160a01b0381166110425760405162461bcd60e51b815260206004820152601a60248201527f4665653a206665654f776e65722063616e6e6f7420626520307800000000000060448201526064016109c4565b6008805462010000600160b01b031916620100006001600160a01b038416908102919091179091556040519081527f047912631afa564eebd3db2efe191a0dec62da1fede6bbbc1ffc89d87845b1b5906020015b60405180910390a150565b6110a9611d11565b6127108161ffff1611156110cf5760405162461bcd60e51b81526004016109c490613d47565b6008805461ffff191661ffff83169081179091556040519081527fd26030ef4a8c225ee12b646eb4466acb41fb96b6cd4660b22d0ba0124e7bdc7490602001611096565b3330146111715760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b60648201526084016109c4565b610d538686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f89018190048102820181019092528781528993509150879087908190840183828082843760009201919091525061208c92505050565b6111ef611d11565b6111f96000612113565b565b6001602052600090815260409020805461121490613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461124090613c29565b801561128d5780601f106112625761010080835404028352916020019161128d565b820191906000526020600020905b81548152906001019060200180831161127057829003601f168201915b505050505081565b61129d611d11565b6127108161ffff1611156112c35760405162461bcd60e51b81526004016109c490613d47565b60408051808201825261ffff83811680835285151560208085018281528985166000818152600784528890209651875492511515620100000262ffffff1990931696169590951717909455845192835292820192909252918201527fdd9c9685af3e6dcb56d8f4b88d2595d4add6837a150034e7781c46b6dcf8aaab906060015b60405180910390a1505050565b60006009547f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb96001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d89190613d8c565b6113e29190613dbb565b905090565b61ffff811660009081526001602052604081208054606092919061140a90613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461143690613c29565b80156114835780601f1061145857610100808354040283529160200191611483565b820191906000526020600020905b81548152906001019060200180831161146657829003601f168201915b5050505050905080516000036114db5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f726400000060448201526064016109c4565b610e766000601483516114ee9190613dbb565b839190612163565b6000806115738b8b8b8b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8d018190048102820181019092528b81528e93508d9250908c908c908190840183828082843760009201919091525061227092505050565b91509150995099975050505050505050565b61158d611d11565b8181306040516020016115a293929190613dce565b60408051601f1981840301815291815261ffff85166000908152600160205220906115cd9082613e3a565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce83838360405161134493929190613d29565b611609611d11565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90602001611096565b61165f611d11565b6040516332fb62e760e21b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063cbed8b9c906116b39088908890889088908890600401613ef9565b600060405180830381600087803b1580156116cd57600080fd5b505af1158015610fd9573d6000803e3d6000fd5b61ffff861660009081526005602052604080822090516117049088908890613c5d565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806117845760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b60648201526084016109c4565b808383604051611795929190613c5d565b6040518091039020146117f45760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b60648201526084016109c4565b61ffff871660009081526005602052604080822090516118179089908990613c5d565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526118af918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061208c92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516118e6959493929190613f27565b60405180910390a150505050505050565b6118ff611d11565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611344565b3330146119b05760405162461bcd60e51b815260206004820152601f60248201527f4f4654436f72653a2063616c6c6572206d757374206265204f4654436f72650060448201526064016109c4565b6119bb30868661232b565b9350846001600160a01b03168a61ffff167fbf551ec93859b170f9b2141bd9298bf3f64322c6f7beb2543a0cb669834118bf866040516119fd91815260200190565b60405180910390a3604051633fe79aed60e11b81526001600160a01b03861690637fcf35da908390611a41908e908e908e908e908e908d908d908d90600401613f62565b600060405180830381600088803b158015611a5b57600080fd5b5087f1158015611a6f573d6000803e3d6000fd5b505050505050505050505050505050565b611a88611d11565b61ffff83166000908152600160205260409020611aa6828483613fbd565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab83838360405161134493929190613d29565b61ffff828116600090815260076020908152604080832081518083019092525493841681526201000090930460ff1615801591840191909152909190611b3f57805161271090611b2e9061ffff168561407c565b611b3891906140a9565b9150611b65565b60085461ffff1615611b605760085461271090611b2e9061ffff168561407c565b600091505b5092915050565b611b74611d11565b6001600160a01b038116611bd95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c4565b611be281612113565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015611c65573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c8d91908101906140bd565b90505b949350505050565b600080611cfb5a60966366ad5c8a60e01b89898989604051602401611cc0949392919061412a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906124db565b9150915081610d5357610d538686868685612565565b6000546001600160a01b031633146111f95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c4565b600080611d788484611ada565b9050611d848184613dbb565b91508015611dac57600854611daa9086906201000090046001600160a01b03168361232b565b505b935093915050565b6000611dc287828481612602565b611dcb856126d7565b509050611dda88888884612717565b905060008111611e285760405162461bcd60e51b815260206004820152601960248201527813d19510dbdc994e88185b5bdd5b9d081d1bdbc81cdb585b1b603a1b60448201526064016109c4565b6000611e7387611e3784612876565b6040805160006020820152602181019390935260c09190911b6001600160c01b0319166041830152805160298184030181526049909201905290565b9050611e838882878787346128fc565b86896001600160a01b03168961ffff167fd81fc9b8523134ed613870ed029d6170cbb73aa6a6bc311b9a642689fb9df59a85604051611ec491815260200190565b60405180910390a450979650505050505050565b6000806000611eea87611e3788612876565b60405163040a7bb160e41b81529091506001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906340a7bb1090611f41908b90309086908b908b90600401614168565b6040805180830381865afa158015611f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8191906141bc565b92509250509550959350505050565b6000611fa8896001846001600160401b038916612602565b611fb1876126d7565b509050611fc08a8a8a84612717565b90506000811161200e5760405162461bcd60e51b815260206004820152601960248201527813d19510dbdc994e88185b5bdd5b9d081d1bdbc81cdb585b1b603a1b60448201526064016109c4565b6000612025338a61201e85612876565b8a8a612aa1565b90506120358a82878787346128fc565b888b6001600160a01b03168b61ffff167fd81fc9b8523134ed613870ed029d6170cbb73aa6a6bc311b9a642689fb9df59a8560405161207691815260200190565b60405180910390a4509998505050505050505050565b60006120988282612ae2565b905060ff81166120b3576120ae85858585612b3e565b610c3a565b60001960ff8216016120cb576120ae85858585612bce565b60405162461bcd60e51b815260206004820152601c60248201527f4f4654436f72653a20756e6b6e6f776e207061636b657420747970650000000060448201526064016109c4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60608161217181601f6141e0565b10156121b05760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016109c4565b6121ba82846141e0565b845110156121fe5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016109c4565b60608215801561221d5760405191506000825260208201604052612267565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561225657805183526020928301920161223e565b5050858452601f01601f1916604052505b50949350505050565b6000806000612283338a61201e8b612876565b60405163040a7bb160e41b81529091506001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906340a7bb10906122da908d90309086908b908b90600401614168565b6040805180830381865afa1580156122f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231a91906141bc565b925092505097509795505050505050565b6040516370a0823160e01b81526001600160a01b03838116600483015260009182917f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb916906370a0823190602401602060405180830381865afa158015612396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ba9190613d8c565b9050306001600160a01b03861603612405576124006001600160a01b037f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9168585612ddd565b61243a565b61243a6001600160a01b037f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb916868686612e45565b6040516370a0823160e01b81526001600160a01b03858116600483015282917f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9909116906370a0823190602401602060405180830381865afa1580156124a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c89190613d8c565b6124d29190613dbb565b95945050505050565b6000606060008060008661ffff166001600160401b03811115612500576125006137ce565b6040519080825280601f01601f19166020018201604052801561252a576020820181803683370190505b50905060008087516020890160008d8df191503d92508683111561254c578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff1681526020019081526020016000208560405161259691906141f3565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c906125f3908790879087908790879061420f565b60405180910390a15050505050565b600061260d83612e7d565b61ffff8087166000908152600260209081526040808320938916835292905220549091508061267e5760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f742073657400000000000060448201526064016109c4565b61268883826141e0565b821015610d535760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f77000000000060448201526064016109c4565b6000806127047f00000000000000000000000000000000000000000000000000000002540be40084614261565b90506127108184613dbb565b9150915091565b60006001600160a01b03851633146127835760405162461bcd60e51b815260206004820152602960248201527f50726f78794f4654576974684665653a206f776e6572206973206e6f7420736560448201526837321031b0b63632b960b91b60648201526084016109c4565b61278e85308461232b565b915060008061279c846126d7565b909250905080156127db576127db6001600160a01b037f000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9168883612ddd565b81600960008282546127ed91906141e0565b90915550600090506128056001600160401b03612ed9565b905060095481101561286a5760405162461bcd60e51b815260206004820152602860248201527f50726f78794f4654576974684665653a206f7574626f756e64416d6f756e74206044820152676f766572666c6f7760c01b60648201526084016109c4565b50909695505050505050565b6000806128a37f00000000000000000000000000000000000000000000000000000002540be400846140a9565b90506001600160401b03811115610bb25760405162461bcd60e51b815260206004820152601a60248201527f4f4654436f72653a20616d6f756e745344206f766572666c6f7700000000000060448201526064016109c4565b61ffff86166000908152600160205260408120805461291a90613c29565b80601f016020809104026020016040519081016040528092919081815260200182805461294690613c29565b80156129935780601f1061296857610100808354040283529160200191612993565b820191906000526020600020905b81548152906001019060200180831161297657829003601f168201915b505050505090508051600003612a045760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b60648201526084016109c4565b612a0f878751612f0e565b60405162c5803160e81b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063c5803100908490612a66908b9086908c908c908c908c90600401614275565b6000604051808303818588803b158015612a7f57600080fd5b505af1158015612a93573d6000803e3d6000fd5b505050505050505050505050565b6060600185856001600160a01b0389168587604051602001612ac8969594939291906142dc565b604051602081830303815290604052905095945050505050565b6000612aef8260016141e0565b83511015612b355760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016109c4565b50016001015190565b600080612b4a83612f7f565b90925090506001600160a01b038216612b635761dead91505b6000612b6e82612ed9565b9050612b7b878483613004565b9050826001600160a01b03168761ffff167fbf551ec93859b170f9b2141bd9298bf3f64322c6f7beb2543a0cb669834118bf83604051612bbd91815260200190565b60405180910390a350505050505050565b6000806000806000612bdf8661303f565b945094509450945094506000600660008b61ffff1661ffff16815260200190815260200160002089604051612c1491906141f3565b90815260408051602092819003830190206001600160401b038b166000908152925281205460ff169150612c4785612ed9565b905081612cb557612c598b3083613004565b61ffff8c16600090815260066020526040908190209051919250600191612c81908d906141f3565b90815260408051602092819003830190206001600160401b038d16600090815292529020805460ff19169115159190911790555b6001600160a01b0386163b612d0c576040516001600160a01b03871681527f9aedf5fdba8716db3b6705ca00150643309995d4f818a249ed6dde6677e7792d9060200160405180910390a150505050505050612dd7565b8a8a8a8a8a8a868a60008a612d2a578b6001600160401b0316612d2c565b5a5b9050600080612d5e5a609663eaffd49a60e01b8e8e8e8d8d8d8d8d604051602401611cc098979695949392919061433d565b915091508115612db7578751602089012060405161ffff8d16907fb8890edbfc1c74692f527444645f95489c3703cc2df42e4a366f5d06fa6cd88490612da9908e908e9086906143b1565b60405180910390a250612dc4565b612dc48b8b8b8b85612565565b5050505050505050505050505050505050505b50505050565b6040516001600160a01b038316602482015260448101829052612e4090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526130f6565b505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612dd79085906323b872dd60e01b90608401612e09565b6000602282511015612ed15760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d730000000060448201526064016109c4565b506022015190565b6000610bb27f00000000000000000000000000000000000000000000000000000002540be4006001600160401b03841661407c565b61ffff821660009081526003602052604081205490819003612f2f57506127105b80821115612e405760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c6172676560448201526064016109c4565b60008080612f8d8482612ae2565b60ff16148015612f9e575082516029145b612fe55760405162461bcd60e51b815260206004820152601860248201527713d19510dbdc994e881a5b9d985b1a59081c185e5b1bd85960421b60448201526064016109c4565b612ff083600d6131cb565b9150612ffd836021613230565b9050915091565b600081600960008282546130189190613dbb565b9091555050306001600160a01b03841603613034575080610e76565b611c9030848461232b565b6000808060608160016130528783612ae2565b60ff161461309d5760405162461bcd60e51b815260206004820152601860248201527713d19510dbdc994e881a5b9d985b1a59081c185e5b1bd85960421b60448201526064016109c4565b6130a886600d6131cb565b93506130b5866021613230565b92506130c286602961328d565b94506130cf866049613230565b90506130eb60518088516130e39190613dbb565b889190612163565b915091939590929450565b600061314b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166132eb9092919063ffffffff16565b905080516000148061316c57508080602001905181019061316c91906143df565b612e405760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c4565b60006131d88260146141e0565b835110156132205760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016109c4565b500160200151600160601b900490565b600061323d8260086141e0565b835110156132845760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016109c4565b50016008015190565b600061329a8260206141e0565b835110156132e25760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b60448201526064016109c4565b50016020015190565b6060611c90848460008585600080866001600160a01b0316858760405161331291906141f3565b60006040518083038185875af1925050503d806000811461334f576040519150601f19603f3d011682016040523d82523d6000602084013e613354565b606091505b509150915061336587838387613370565b979650505050505050565b606083156133df5782516000036133d8576001600160a01b0385163b6133d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c4565b5081611c90565b611c9083838151156133f45781518083602001fd5b8060405162461bcd60e51b81526004016109c4919061392b565b803561ffff8116811461342057600080fd5b919050565b60008083601f84011261343757600080fd5b5081356001600160401b0381111561344e57600080fd5b60208301915083602082850101111561346657600080fd5b9250929050565b80356001600160401b038116811461342057600080fd5b6000806000806000806080878903121561349d57600080fd5b6134a68761340e565b955060208701356001600160401b03808211156134c257600080fd5b6134ce8a838b01613425565b90975095508591506134e260408a0161346d565b945060608901359150808211156134f857600080fd5b5061350589828a01613425565b979a9699509497509295939492505050565b60006020828403121561352957600080fd5b81356001600160e01b031981168114610e7657600080fd5b60006020828403121561355357600080fd5b610e768261340e565b6000806040838503121561356f57600080fd5b6135788361340e565b946020939093013593505050565b6001600160a01b0381168114611be257600080fd5b6000606082840312156135ad57600080fd5b50919050565b60008060008060008060c087890312156135cc57600080fd5b86356135d781613586565b95506135e56020880161340e565b945060408701359350606087013592506080870135915060a08701356001600160401b0381111561361557600080fd5b61362189828a0161359b565b9150509295509295509295565b8015158114611be257600080fd5b60008060008060008060a0878903121561365557600080fd5b61365e8761340e565b95506020870135945060408701359350606087013561367c8161362e565b925060808701356001600160401b0381111561369757600080fd5b61350589828a01613425565b6000806000604084860312156136b857600080fd5b6136c18461340e565b925060208401356001600160401b038111156136dc57600080fd5b6136e886828701613425565b9497909650939450505050565b60008060008060008060008060006101008a8c03121561371457600080fd5b893561371f81613586565b985061372d60208b0161340e565b975060408a0135965060608a0135955060808a0135945060a08a01356001600160401b038082111561375e57600080fd5b61376a8d838e01613425565b909650945084915061377e60c08d0161346d565b935060e08c013591508082111561379457600080fd5b506137a18c828d0161359b565b9150509295985092959850929598565b6000602082840312156137c357600080fd5b8135610e7681613586565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561380c5761380c6137ce565b604052919050565b60006001600160401b0382111561382d5761382d6137ce565b50601f01601f191660200190565b60008060006060848603121561385057600080fd5b6138598461340e565b925060208401356001600160401b0381111561387457600080fd5b8401601f8101861361388557600080fd5b803561389861389382613814565b6137e4565b8181528760208385010111156138ad57600080fd5b816020840160208301376000602083830101528094505050506138d26040850161346d565b90509250925092565b60005b838110156138f65781810151838201526020016138de565b50506000910152565b600081518084526139178160208601602086016138db565b601f01601f19169290920160200192915050565b602081526000610e7660208301846138ff565b60008060006060848603121561395357600080fd5b61395c8461340e565b9250602084013561396c8161362e565b91506138d26040850161340e565b6000806040838503121561398d57600080fd5b6139968361340e565b91506139a46020840161340e565b90509250929050565b600080600080600080600080600060e08a8c0312156139cb57600080fd5b6139d48a61340e565b985060208a0135975060408a0135965060608a01356001600160401b03808211156139fe57600080fd5b613a0a8d838e01613425565b9098509650869150613a1e60808d0161346d565b955060a08c01359150613a308261362e565b90935060c08b01359080821115613a4657600080fd5b50613a538c828d01613425565b915080935050809150509295985092959850929598565b600080600080600060808688031215613a8257600080fd5b613a8b8661340e565b9450613a996020870161340e565b93506040860135925060608601356001600160401b03811115613abb57600080fd5b613ac788828901613425565b969995985093965092949392505050565b600080600060608486031215613aed57600080fd5b613af68461340e565b9250613b046020850161340e565b9150604084013590509250925092565b6000806000806000806000806000806101008b8d031215613b3457600080fd5b613b3d8b61340e565b995060208b01356001600160401b0380821115613b5957600080fd5b613b658e838f01613425565b909b509950899150613b7960408e0161346d565b985060608d0135975060808d01359150613b9282613586565b90955060a08c0135945060c08c01359080821115613baf57600080fd5b50613bbc8d828e01613425565b9150809450508092505060e08b013590509295989b9194979a5092959850565b60008060008060808587031215613bf257600080fd5b613bfb8561340e565b9350613c096020860161340e565b92506040850135613c1981613586565b9396929550929360600135925050565b600181811c90821680613c3d57607f821691505b6020821081036135ad57634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6000808335601e19843603018112613c8457600080fd5b8301803591506001600160401b03821115613c9e57600080fd5b60200191503681900382131561346657600080fd5b6020808252602d908201527f426173654f4654576974684665653a20616d6f756e74206973206c657373207460408201526c1a185b881b5a5b905b5bdd5b9d609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000611c8d604083018486613d00565b60208082526025908201527f4665653a20666565206270206d757374206265203c3d2042505f44454e4f4d496040820152642720aa27a960d91b606082015260800190565b600060208284031215613d9e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bb257610bb2613da5565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b601f821115612e4057600081815260208120601f850160051c81016020861015613e1b5750805b601f850160051c820191505b81811015610d5357828155600101613e27565b81516001600160401b03811115613e5357613e536137ce565b613e6781613e618454613c29565b84613df4565b602080601f831160018114613e9c5760008415613e845750858301515b600019600386901b1c1916600185901b178555610d53565b600085815260208120601f198616915b82811015613ecb57888601518255948401946001909101908401613eac565b5085821015613ee95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600061ffff808816835280871660208401525084604083015260806060830152613365608083018486613d00565b61ffff86168152608060208201526000613f45608083018688613d00565b6001600160401b0394909416604083015250606001529392505050565b61ffff8916815260c060208201526000613f8060c08301898b613d00565b6001600160401b038816604084015286606084015285608084015282810360a0840152613fae818587613d00565b9b9a5050505050505050505050565b6001600160401b03831115613fd457613fd46137ce565b613fe883613fe28354613c29565b83613df4565b6000601f84116001811461401c57600085156140045750838201355b600019600387901b1c1916600186901b178355610c3a565b600083815260209020601f19861690835b8281101561404d578685013582556020948501946001909201910161402d565b508682101561406a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b8082028115828204841417610bb257610bb2613da5565b634e487b7160e01b600052601260045260246000fd5b6000826140b8576140b8614093565b500490565b6000602082840312156140cf57600080fd5b81516001600160401b038111156140e557600080fd5b8201601f810184136140f657600080fd5b805161410461389382613814565b81815285602083850101111561411957600080fd5b6124d28260208301602086016138db565b61ffff8516815260806020820152600061414760808301866138ff565b6001600160401b0385166040840152828103606084015261336581856138ff565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614196908301866138ff565b841515606084015282810360808401526141b081856138ff565b98975050505050505050565b600080604083850312156141cf57600080fd5b505080516020909101519092909150565b80820180821115610bb257610bb2613da5565b600082516142058184602087016138db565b9190910192915050565b61ffff8616815260a06020820152600061422c60a08301876138ff565b6001600160401b0386166040840152828103606084015261424d81866138ff565b905082810360808401526141b081856138ff565b60008261427057614270614093565b500690565b61ffff8716815260c06020820152600061429260c08301886138ff565b82810360408401526142a481886138ff565b6001600160a01b0387811660608601528616608085015283810360a085015290506142cf81856138ff565b9998505050505050505050565b60ff60f81b8760f81b16815285600182015260006001600160401b0360c01b808760c01b166021840152856029840152808560c01b16604984015250825161432b8160518501602087016138db565b91909101605101979650505050505050565b600061010061ffff8b16835280602084015261435b8184018b6138ff565b6001600160401b038a166040850152606084018990526001600160a01b038816608085015260a0840187905283810360c0850152905061439b81866138ff565b9150508260e08301529998505050505050505050565b6060815260006143c460608301866138ff565b6001600160401b039490941660208301525060400152919050565b6000602082840312156143f157600080fd5b8151610e768161362e56fea26469706673582212204495807a73f54df216e7031f0d93c92bdc992182a5b4b976b789686dedbed27264736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9000000000000000000000000000000000000000000000000000000000000000800000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
-----Decoded View---------------
Arg [0] : _token (address): 0xa6C0c097741D55ECd9a3A7DeF3A8253fD022ceB9
Arg [1] : _sharedDecimals (uint8): 8
Arg [2] : _lzEndpoint (address): 0x66A71Dcef29A0fFBDBE3c6a460a3B5BC225Cd675
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000a6c0c097741d55ecd9a3a7def3a8253fd022ceb9
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [2] : 00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Deployed Bytecode Sourcemap
88764:3158:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31536:799;;;;;;;;;;-1:-1:-1;31536:799:0;;;;;:::i;:::-;;:::i;:::-;;66249:218;;;;;;;;;;-1:-1:-1;66249:218:0;;;;;:::i;:::-;;:::i;:::-;;;2029:14:1;;2022:22;2004:41;;1992:2;1977:18;66249:218:0;;;;;;;;34945:123;;;;;;;;;;-1:-1:-1;34945:123:0;;;;;:::i;:::-;;:::i;36814:142::-;;;;;;;;;;-1:-1:-1;36814:142:0;;;;;:::i;:::-;;:::i;35076:129::-;;;;;;;;;;-1:-1:-1;35076:129:0;;;;;:::i;:::-;;:::i;64620:648::-;;;;;;:::i;:::-;;:::i;66475:344::-;;;;;;;;;;-1:-1:-1;66475:344:0;;;;;:::i;:::-;;:::i;:::-;;;;4638:25:1;;;4694:2;4679:18;;4672:34;;;;4611:18;66475:344:0;4464:248:1;37054:250:0;;;;;;;;;;-1:-1:-1;37054:250:0;;;;;:::i;:::-;;:::i;31078:53::-;;;;;;;;;;-1:-1:-1;31078:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;5349:25:1;;;5337:2;5322:18;31078:53:0;5203:177:1;35213:178:0;;;;;;;;;;-1:-1:-1;35213:178:0;;;;;:::i;:::-;;:::i;49148:37::-;;;;;;;;;;;;49184:1;49148:37;;65276:776;;;;;;:::i;:::-;;:::i;62270:217::-;;;;;;;;;;-1:-1:-1;62270:217:0;;;;;:::i;:::-;;:::i;49214:33::-;;;;;;;;;;;;49246:1;49214:33;;;;;6976:4:1;6964:17;;;6946:36;;6934:2;6919:18;49214:33:0;6804:184:1;61709:235:0;;;;;;;;;;-1:-1:-1;61709:235:0;;;;;:::i;:::-;;:::i;43291:85::-;;;;;;;;;;-1:-1:-1;43291:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44571:346;;;;;;;;;;-1:-1:-1;44571:346:0;;;;;:::i;:::-;;:::i;2658:103::-;;;;;;;;;;;;;:::i;30948:51::-;;;;;;;;;;-1:-1:-1;30948:51:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;61952:310::-;;;;;;;;;;-1:-1:-1;61952:310:0;;;;;:::i;:::-;;:::i;49305:37::-;;;;;;;;;;;;;;;31006:65;;;;;;;;;;-1:-1:-1;31006:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2017:87;;;;;;;;;;-1:-1:-1;2063:7:0;2090:6;-1:-1:-1;;;;;2090:6:0;2017:87;;;-1:-1:-1;;;;;10165:32:1;;;10147:51;;10135:2;10120:18;2017:87:0;10001:203:1;89837:140:0;;;;;;;;;;;;;:::i;31138:23::-;;;;;;;;;;-1:-1:-1;31138:23:0;;;;-1:-1:-1;;;;;31138:23:0;;;89052:26;;;;;;;;;;;;;;;;49351:83;;;;;;;;;;-1:-1:-1;49351:83:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36042:330;;;;;;;;;;-1:-1:-1;36042:330:0;;;;;:::i;:::-;;:::i;66827:450::-;;;;;;;;;;-1:-1:-1;66827:450:0;;;;;:::i;:::-;;:::i;35753:281::-;;;;;;;;;;-1:-1:-1;35753:281:0;;;;;:::i;:::-;;:::i;61221:43::-;;;;;;;;;;;;61259:5;61221:43;;30895:46;;;;;;;;;;;;;;;61364:23;;;;;;;;;;-1:-1:-1;61364:23:0;;;;;;;-1:-1:-1;;;;;61364:23:0;;;36380:136;;;;;;;;;;-1:-1:-1;36380:136:0;;;;;:::i;:::-;;:::i;61273:51::-;;;;;;;;;;-1:-1:-1;61273:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;11774:6:1;11762:19;;;11744:38;;11825:14;;11818:22;11813:2;11798:18;;11791:50;11717:18;61273:51:0;11578:269:1;34733:204:0;;;;;;;;;;-1:-1:-1;34733:204:0;;;;;:::i;:::-;;:::i;45103:767::-;;;;;;:::i;:::-;;:::i;61331:26::-;;;;;;;;;;-1:-1:-1;61331:26:0;;;;;;;;;;;12653:6:1;12641:19;;;12623:38;;12611:2;12596:18;61331:26:0;12479:188:1;36524:228:0;;;;;;;;;;-1:-1:-1;36524:228:0;;;;;:::i;:::-;;:::i;49254:42::-;;;;;;;;;;;;49295:1;49254:42;;50555:643;;;;;;;;;;-1:-1:-1;50555:643:0;;;;;:::i;:::-;;:::i;35538:207::-;;;;;;;;;;-1:-1:-1;35538:207:0;;;;;:::i;:::-;;:::i;62495:413::-;;;;;;;;;;-1:-1:-1;62495:413:0;;;;;:::i;:::-;;:::i;2916:201::-;;;;;;;;;;-1:-1:-1;2916:201:0;;;;;:::i;:::-;;:::i;34460:211::-;;;;;;;;;;-1:-1:-1;34460:211:0;;;;;:::i;:::-;;:::i;89985:109::-;;;;;;;;;;-1:-1:-1;90075:10:0;89985:109;;31536:799;736:10;31776;-1:-1:-1;;;;;31752:35:0;;31744:78;;;;-1:-1:-1;;;31744:78:0;;14878:2:1;31744:78:0;;;14860:21:1;14917:2;14897:18;;;14890:30;14956:32;14936:18;;;14929:60;15006:18;;31744:78:0;;;;;;;;;31864:32;;;31835:26;31864:32;;;:19;:32;;;;;31835:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32084:13;:20;32062:11;;:18;;:42;:70;;;;;32131:1;32108:13;:20;:24;32062:70;:124;;;;-1:-1:-1;32162:24:0;;;;;;32136:22;;;;32146:11;;;;32136:22;:::i;:::-;;;;;;;;:50;32062:124;32040:212;;;;-1:-1:-1;;;32040:212:0;;15898:2:1;32040:212:0;;;15880:21:1;15937:2;15917:18;;;15910:30;15976:34;15956:18;;;15949:62;-1:-1:-1;;;16027:18:1;;;16020:36;16073:19;;32040:212:0;15696:402:1;32040:212:0;32265:62;32284:11;32297;;32265:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32265:62:0;;;;;;;;;;;;;;;;;;;;;;32310:6;;-1:-1:-1;32265:62:0;-1:-1:-1;32318:8:0;;;;;;32265:62;;32318:8;;;;32265:62;;;;;;;;;-1:-1:-1;32265:18:0;;-1:-1:-1;;;32265:62:0:i;:::-;31667:668;31536:799;;;;;;:::o;66249:218::-;66351:4;-1:-1:-1;;;;;;66375:44:0;;-1:-1:-1;;;66375:44:0;;:84;;-1:-1:-1;;;;;;;;;;64196:40:0;;;66423:36;66368:91;66249:218;-1:-1:-1;;66249:218:0:o;34945:123::-;1903:13;:11;:13::i;:::-;35025:35:::1;::::0;-1:-1:-1;;;35025:35:0;;12653:6:1;12641:19;;35025:35:0::1;::::0;::::1;12623:38:1::0;35025:10:0::1;-1:-1:-1::0;;;;;35025:25:0::1;::::0;::::1;::::0;12596:18:1;;35025:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;34945:123:::0;:::o;36814:142::-;1903:13;:11;:13::i;:::-;36905:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;36814:142::o;35076:129::-;1903:13;:11;:13::i;:::-;35159:38:::1;::::0;-1:-1:-1;;;35159:38:0;;12653:6:1;12641:19;;35159:38:0::1;::::0;::::1;12623::1::0;35159:10:0::1;-1:-1:-1::0;;;;;35159:28:0::1;::::0;::::1;::::0;12596:18:1;;35159:38:0::1;12479:188:1::0;64620:648:0;64877:39;64888:5;64895:11;64908:7;64877:10;:39::i;:::-;-1:-1:-1;64863:53:0;-1:-1:-1;64937:233:0;64957:5;64977:11;65003:10;64863:53;65050:25;;;;:11;:25;:::i;:::-;65090:29;;;;;;;;:::i;:::-;65134:25;;;;:11;:25;:::i;:::-;64937:233;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64937:5:0;;-1:-1:-1;;;64937:233:0:i;:::-;64927:243;;65200:10;65189:7;:21;;65181:79;;;;-1:-1:-1;;;65181:79:0;;;;;;;:::i;:::-;64620:648;;;;;;:::o;66475:344::-;66689:14;66705:11;66736:75;66753:11;66766:10;66778:7;66787;66796:14;;66736:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66736:16:0;;-1:-1:-1;;;66736:75:0:i;:::-;66729:82;;;;66475:344;;;;;;;;;:::o;37054:250::-;37196:32;;;37150:4;37196:32;;;:19;:32;;;;;37167:61;;37150:4;;37196:32;37167:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37284:11;;37274:22;;;;;;;:::i;:::-;;;;;;;;37256:13;37246:24;;;;;;:50;37239:57;;;37054:250;;;;;;:::o;35213:178::-;1903:13;:11;:13::i;:::-;35328:55:::1;::::0;-1:-1:-1;;;35328:55:0;;-1:-1:-1;;;;;35328:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;35358:11;;35371;;;;35328:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;65276:776:::0;65602:39;65613:5;65620:11;65633:7;65602:10;:39::i;:::-;65588:53;;;;;65662:292;65689:5;65709:11;65735:10;65760:7;65782:8;;65662:292;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65805:14:0;;-1:-1:-1;65834:25:0;;-1:-1:-1;;65834:25:0;;;:11;:25;:::i;:::-;65874:29;;;;;;;;:::i;:::-;65918:25;;;;:11;:25;:::i;:::-;65662:292;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65662:12:0;;-1:-1:-1;;;65662:292:0:i;:::-;65652:302;;65984:10;65973:7;:21;;65965:79;;;;-1:-1:-1;;;65965:79:0;;;;;;;:::i;:::-;65276:776;;;;;;;;;:::o;62270:217::-;1903:13;:11;:13::i;:::-;-1:-1:-1;;;;;62354:25:0;::::1;62346:64;;;::::0;-1:-1:-1;;;62346:64:0;;18107:2:1;62346:64:0::1;::::0;::::1;18089:21:1::0;18146:2;18126:18;;;18119:30;18185:28;18165:18;;;18158:56;18231:18;;62346:64:0::1;17905:350:1::0;62346:64:0::1;62421:8;:20:::0;;-1:-1:-1;;;;;;62421:20:0::1;::::0;-1:-1:-1;;;;;62421:20:0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;62457:22:::1;::::0;10147:51:1;;;62457:22:0::1;::::0;10135:2:1;10120:18;62457:22:0::1;;;;;;;;62270:217:::0;:::o;61709:235::-;1903:13;:11;:13::i;:::-;61259:5:::1;61793:6;:24;;;;61785:74;;;;-1:-1:-1::0;;;61785:74:0::1;;;;;;;:::i;:::-;61870:12;:21:::0;;-1:-1:-1;;61870:21:0::1;;::::0;::::1;::::0;;::::1;::::0;;;61907:29:::1;::::0;12623:38:1;;;61907:29:0::1;::::0;12611:2:1;12596:18;61907:29:0::1;12479:188:1::0;44571:346:0;736:10;44785:4;44761:29;44753:80;;;;-1:-1:-1;;;44753:80:0;;18868:2:1;44753:80:0;;;18850:21:1;18907:2;18887:18;;;18880:30;18946:34;18926:18;;;18919:62;-1:-1:-1;;;18997:18:1;;;18990:36;19043:19;;44753:80:0;18666:402:1;44753:80:0;44844:65;44866:11;44879;;44844:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44844:65:0;;;;;;;;;;;;;;;;;;;;;;44892:6;;-1:-1:-1;44844:65:0;-1:-1:-1;44900:8:0;;;;;;44844:65;;44900:8;;;;44844:65;;;;;;;;;-1:-1:-1;44844:21:0;;-1:-1:-1;;;44844:65:0:i;2658:103::-;1903:13;:11;:13::i;:::-;2723:30:::1;2750:1;2723:18;:30::i;:::-;2658:103::o:0;30948:51::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61952:310::-;1903:13;:11;:13::i;:::-;61259:5:::1;62064:6;:24;;;;62056:74;;;;-1:-1:-1::0;;;62056:74:0::1;;;;;;;:::i;:::-;62172:27;::::0;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;;;::::0;;::::1;::::0;;;62141:28;;::::1;-1:-1:-1::0;62141:28:0;;;:15:::1;:28:::0;;;;;:58;;;;;;::::1;;::::0;::::1;-1:-1:-1::0;;62141:58:0;;;;::::1;::::0;;;;::::1;::::0;;;62215:39;;19290:34:1;;;19340:18;;;19333:50;;;;19399:18;;;19392:43;62215:39:0::1;::::0;19253:2:1;19238:18;62215:39:0::1;;;;;;;;61952:310:::0;;;:::o;89837:140::-;89904:4;89955:14;;89928:10;-1:-1:-1;;;;;89928:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;;:::i;:::-;89921:48;;89837:140;:::o;36042:330::-;36166:35;;;36146:17;36166:35;;;:19;:35;;;;;36146:55;;36121:12;;36146:17;36166:35;36146:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36220:4;:11;36235:1;36220:16;36212:58;;;;-1:-1:-1;;;36212:58:0;;20102:2:1;36212:58:0;;;20084:21:1;20141:2;20121:18;;;20114:30;20180:31;20160:18;;;20153:59;20229:18;;36212:58:0;19900:353:1;36212:58:0;36288:31;36299:1;36316:2;36302:4;:11;:16;;;;:::i;:::-;36288:4;;:31;:10;:31::i;66827:450::-;67114:14;67130:11;67161:108;67185:11;67198:10;67210:7;67219:8;;67161:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67161:108:0;;;;;;;;;;;;;;;;;;;;;;67229:14;;-1:-1:-1;67245:7:0;;-1:-1:-1;67161:108:0;67254:14;;;;;;67161:108;;67254:14;;;;67161:108;;;;;;;;;-1:-1:-1;67161:23:0;;-1:-1:-1;;;67161:108:0:i;:::-;67154:115;;;;66827:450;;;;;;;;;;;;:::o;35753:281::-;1903:13;:11;:13::i;:::-;35925:14:::1;;35949:4;35908:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;35908:47:0;;::::1;::::0;;;;;;35870:35:::1;::::0;::::1;;::::0;;;:19:::1;35908:47;35870:35:::0;;;:85:::1;::::0;:35;:85:::1;:::i;:::-;;35971:55;35995:14;36011;;35971:55;;;;;;;;:::i;36380:136::-:0;1903:13;:11;:13::i;:::-;36450:8:::1;:20:::0;;-1:-1:-1;;;;;;36450:20:0::1;-1:-1:-1::0;;;;;36450:20:0;::::1;::::0;;::::1;::::0;;;36486:22:::1;::::0;10147:51:1;;;36486:22:0::1;::::0;10135:2:1;10120:18;36486:22:0::1;10001:203:1::0;34733:204:0;1903:13;:11;:13::i;:::-;34867:62:::1;::::0;-1:-1:-1;;;34867:62:0;;-1:-1:-1;;;;;34867:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;34888:8;;34898;;34908:11;;34921:7;;;;34867:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;45103:767:::0;45314:27;;;45292:19;45314:27;;;:14;:27;;;;;;:40;;;;45342:11;;;;45314:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45314:48:0;;;;;;;;;;;;-1:-1:-1;45314:48:0;45373:73;;;;-1:-1:-1;;;45373:73:0;;23526:2:1;45373:73:0;;;23508:21:1;23565:2;23545:18;;;23538:30;23604:34;23584:18;;;23577:62;-1:-1:-1;;;23655:18:1;;;23648:33;23698:19;;45373:73:0;23324:399:1;45373:73:0;45488:11;45475:8;;45465:19;;;;;;;:::i;:::-;;;;;;;;:34;45457:80;;;;-1:-1:-1;;;45457:80:0;;23930:2:1;45457:80:0;;;23912:21:1;23969:2;23949:18;;;23942:30;24008:34;23988:18;;;23981:62;-1:-1:-1;;;24059:18:1;;;24052:31;24100:19;;45457:80:0;23728:397:1;45457:80:0;45585:27;;;45644:1;45585:27;;;:14;:27;;;;;;:40;;;;45613:11;;;;45585:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45585:48:0;;;;;;;;;;;;:61;;;;45715:65;;;;;;;;;;;;;;;;;;;45737:11;;45750;;45715:65;;;;;;45750:11;45715:65;;45750:11;45715:65;;;;;;;;;-1:-1:-1;;45715:65:0;;;;;;;;;;;;;;;;;;;;;;45763:6;;-1:-1:-1;45715:65:0;-1:-1:-1;45771:8:0;;;;;;45715:65;;45771:8;;;;45715:65;;;;;;;;;-1:-1:-1;45715:21:0;;-1:-1:-1;;;45715:65:0:i;:::-;45796:66;45816:11;45829;;45842:6;45850:11;45796:66;;;;;;;;;;:::i;:::-;;;;;;;;45236:634;45103:767;;;;;;:::o;36524:228::-;1903:13;:11;:13::i;:::-;36630:28:::1;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;36697:47;;24851:34:1;;;24901:18;;24894:43;;;;24953:18;;;24946:34;;;36697:47:0::1;::::0;24814:2:1;24799:18;36697:47:0::1;24628:358:1::0;50555:643:0;736:10;50867:4;50843:29;50835:73;;;;-1:-1:-1;;;50835:73:0;;25193:2:1;50835:73:0;;;25175:21:1;25232:2;25212:18;;;25205:30;25271:33;25251:18;;;25244:61;25322:18;;50835:73:0;24991:355:1;50835:73:0;50948:42;50970:4;50977:3;50982:7;50948:13;:42::i;:::-;50938:52;;51036:3;-1:-1:-1;;;;;51006:43:0;51023:11;51006:43;;;51041:7;51006:43;;;;5349:25:1;;5337:2;5322:18;;5203:177;51006:43:0;;;;;;;;51079:111;;-1:-1:-1;;;51079:111:0;;-1:-1:-1;;;;;51079:33:0;;;;;51118:11;;51079:111;;51131:11;;51144;;;;51157:6;;51165:5;;51172:7;;51181:8;;;;51079:111;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50555:643;;;;;;;;;;:::o;35538:207::-;1903:13;:11;:13::i;:::-;35639:35:::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;:43:::1;35677:5:::0;;35639:35;:43:::1;:::i;:::-;;35698:39;35715:14;35731:5;;35698:39;;;;;;;;:::i;62495:413::-:0;62626:28;;;;62579:8;62626:28;;;:15;:28;;;;;;;;62600:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62579:8;;62600:54;62665:236;;62717:12;;61259:5;;62707:22;;;;:7;:22;:::i;:::-;62706:41;;;;:::i;:::-;62700:47;;62665:236;;;62769:12;;;;:16;62765:136;;62819:12;;61259:5;;62809:22;;62819:12;;62809:7;:22;:::i;62765:136::-;62888:1;62882:7;;62765:136;62589:319;62495:413;;;;:::o;2916:201::-;1903:13;:11;:13::i;:::-;-1:-1:-1;;;;;3005:22:0;::::1;2997:73;;;::::0;-1:-1:-1;;;2997:73:0;;27948:2:1;2997:73:0::1;::::0;::::1;27930:21:1::0;27987:2;27967:18;;;27960:30;28026:34;28006:18;;;27999:62;-1:-1:-1;;;28077:18:1;;;28070:36;28123:19;;2997:73:0::1;27746:402:1::0;2997:73:0::1;3081:28;3100:8;3081:18;:28::i;:::-;2916:201:::0;:::o;34460:211::-;34595:68;;-1:-1:-1;;;34595:68:0;;28390:6:1;28423:15;;;34595:68:0;;;28405:34:1;28475:15;;28455:18;;;28448:43;34644:4:0;28507:18:1;;;28500:60;28576:18;;;28569:34;;;34563:12:0;;34595:10;-1:-1:-1;;;;;34595:20:0;;;;28352:19:1;;34595:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;34595:68:0;;;;;;;;;;;;:::i;:::-;34588:75;;34460:211;;;;;;;:::o;43660:520::-;43810:12;43824:19;43847:203;43895:9;43919:3;43960:34;;;43996:11;44009;44022:6;44030:8;43937:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;43937:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;43937:102:0;-1:-1:-1;;;;;;43937:102:0;;;;;;;;;;43855:4;;43847:203;;:33;:203::i;:::-;43809:241;;;;44066:7;44061:112;;44090:71;44110:11;44123;44136:6;44144:8;44154:6;44090:19;:71::i;2182:132::-;2063:7;2090:6;-1:-1:-1;;;;;2090:6:0;736:10;2246:23;2238:68;;;;-1:-1:-1;;;2238:68:0;;30028:2:1;2238:68:0;;;30010:21:1;;;30047:18;;;30040:30;30106:34;30086:18;;;30079:62;30158:18;;2238:68:0;29826:356:1;62916:294:0;63011:11;63024:8;63051:33;63063:11;63076:7;63051:11;:33::i;:::-;63045:39;-1:-1:-1;63104:13:0;63045:39;63104:7;:13;:::i;:::-;63095:22;-1:-1:-1;63132:7:0;;63128:75;;63177:8;;63156:35;;63170:5;;63177:8;;;-1:-1:-1;;;;;63177:8:0;63187:3;63156:13;:35::i;:::-;;63128:75;62916:294;;;;;;:::o;53035:840::-;53304:11;53328:66;53343:11;53304;53365:14;53304:11;53328:14;:66::i;:::-;53420:20;53432:7;53420:11;:20::i;:::-;-1:-1:-1;53407:33:0;-1:-1:-1;53460:50:0;53471:5;53478:11;53491:10;53407:33;53460:10;:50::i;:::-;53451:59;;53578:1;53569:6;:10;53561:48;;;;-1:-1:-1;;;53561:48:0;;30389:2:1;53561:48:0;;;30371:21:1;30428:2;30408:18;;;30401:30;-1:-1:-1;;;30447:18:1;;;30440:55;30512:18;;53561:48:0;30187:349:1;53561:48:0;53622:22;53647:46;53666:10;53678:14;53685:6;53678;:14::i;:::-;57995:48;;;49246:1;57995:48;;;35806:49:1;35871:11;;;35864:27;;;;35947:3;35925:16;;;;-1:-1:-1;;;;;;35921:51:1;35907:12;;;35900:73;57995:48:0;;;;;;;;;35989:12:1;;;;57995:48:0;;;57866:185;53647:46;53622:71;;53704:94;53712:11;53725:9;53736:14;53752:18;53772:14;53788:9;53704:7;:94::i;:::-;53848:10;53841:5;-1:-1:-1;;;;;53816:51:0;53828:11;53816:51;;;53860:6;53816:51;;;;5349:25:1;;5337:2;5322:18;;5203:177;53816:51:0;;;;;;;;53317:558;53035:840;;;;;;;;;:::o;51392:471::-;51598:14;51614:11;51682:20;51705:47;51724:10;51736:15;51743:7;51736:6;:15::i;51705:47::-;51770:85;;-1:-1:-1;;;51770:85:0;;51682:70;;-1:-1:-1;;;;;;51770:10:0;:23;;;;:85;;51794:11;;51815:4;;51682:70;;51831:7;;51840:14;;51770:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51763:92;;;;;51392:471;;;;;;;;:::o;54305:995::-;54645:11;54669:77;54684:11;49295:1;54715:14;-1:-1:-1;;;;;54669:77:0;;:14;:77::i;:::-;54772:20;54784:7;54772:11;:20::i;:::-;-1:-1:-1;54759:33:0;-1:-1:-1;54812:50:0;54823:5;54830:11;54843:10;54759:33;54812:10;:50::i;:::-;54803:59;;54890:1;54881:6;:10;54873:48;;;;-1:-1:-1;;;54873:48:0;;30389:2:1;54873:48:0;;;30371:21:1;30428:2;30408:18;;;30401:30;-1:-1:-1;;;30447:18:1;;;30440:55;30512:18;;54873:48:0;30187:349:1;54873:48:0;55002:22;55027:91;55053:10;55065;55077:14;55084:6;55077;:14::i;:::-;55093:8;55103:14;55027:25;:91::i;:::-;55002:116;;55129:94;55137:11;55150:9;55161:14;55177:18;55197:14;55213:9;55129:7;:94::i;:::-;55273:10;55266:5;-1:-1:-1;;;;;55241:51:0;55253:11;55241:51;;;55285:6;55241:51;;;;5349:25:1;;5337:2;5322:18;;5203:177;55241:51:0;;;;;;;;54658:642;54305:995;;;;;;;;;;;:::o;52469:558::-;52664:16;52683:19;:8;52664:16;52683;:19::i;:::-;52664:38;-1:-1:-1;52719:21:0;;;52715:305;;52757:52;52766:11;52779;52792:6;52800:8;52757;:52::i;:::-;52715:305;;;-1:-1:-1;;52831:30:0;;;;52827:193;;52878:59;52894:11;52907;52920:6;52928:8;52878:15;:59::i;52827:193::-;52970:38;;-1:-1:-1;;;52970:38:0;;31638:2:1;52970:38:0;;;31620:21:1;31677:2;31657:18;;;31650:30;31716;31696:18;;;31689:58;31764:18;;52970:38:0;31436:352:1;3277:191:0;3351:16;3370:6;;-1:-1:-1;;;;;3387:17:0;;;-1:-1:-1;;;;;;3387:17:0;;;;;;3420:40;;3370:6;;;;;;;3420:40;;3351:16;3420:40;3340:128;3277:191;:::o;20579:2799::-;20665:12;20714:7;20698:12;20714:7;20708:2;20698:12;:::i;:::-;:23;;20690:50;;;;-1:-1:-1;;;20690:50:0;;32125:2:1;20690:50:0;;;32107:21:1;32164:2;32144:18;;;32137:30;-1:-1:-1;;;32183:18:1;;;32176:44;32237:18;;20690:50:0;31923:338:1;20690:50:0;20776:16;20785:7;20776:6;:16;:::i;:::-;20759:6;:13;:33;;20751:63;;;;-1:-1:-1;;;20751:63:0;;32468:2:1;20751:63:0;;;32450:21:1;32507:2;32487:18;;;32480:30;-1:-1:-1;;;32526:18:1;;;32519:47;32583:18;;20751:63:0;32266:341:1;20751:63:0;20827:22;20893:15;;20922:2005;;;;23071:4;23065:11;23052:24;;23260:1;23249:9;23242:20;23310:4;23299:9;23295:20;23289:4;23282:34;20886:2445;;20922:2005;21107:4;21101:11;21088:24;;21776:2;21767:7;21763:16;22164:9;22157:17;22151:4;22147:28;22135:9;22124;22120:25;22116:60;22213:7;22209:2;22205:16;22470:6;22456:9;22449:17;22443:4;22439:28;22427:9;22419:6;22415:22;22411:57;22407:70;22241:434;22504:3;22500:2;22497:11;22241:434;;;22646:9;;22635:21;;22546:4;22538:13;;;;22579;22241:434;;;-1:-1:-1;;22695:26:0;;;22907:2;22890:11;-1:-1:-1;;22886:25:0;22880:4;22873:39;-1:-1:-1;20886:2445:0;-1:-1:-1;23361:9:0;20579:2799;-1:-1:-1;;;;20579:2799:0:o;51871:590::-;52148:14;52164:11;52235:20;52258:92;52284:10;52296;52308:15;52315:7;52308:6;:15::i;52258:92::-;52368:85;;-1:-1:-1;;;52368:85:0;;52235:115;;-1:-1:-1;;;;;;52368:10:0;:23;;;;:85;;52392:11;;52413:4;;52235:115;;52429:7;;52438:14;;52368:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52361:92;;;;;51871:590;;;;;;;;;;:::o;91409:399::-;91540:25;;-1:-1:-1;;;91540:25:0;;-1:-1:-1;;;;;10165:32:1;;;91540:25:0;;;10147:51:1;91509:4:0;;;;91540:10;:20;;;;10120:18:1;;91540:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91526:39;-1:-1:-1;91597:4:0;-1:-1:-1;;;;;91580:22:0;;;91576:173;;91619:37;-1:-1:-1;;;;;91619:10:0;:23;91643:3;91648:7;91619:23;:37::i;:::-;91576:173;;;91689:48;-1:-1:-1;;;;;91689:10:0;:27;91717:5;91724:3;91729:7;91689:27;:48::i;:::-;91766:25;;-1:-1:-1;;;91766:25:0;;-1:-1:-1;;;;;10165:32:1;;;91766:25:0;;;10147:51:1;91794:6:0;;91766:10;:20;;;;;;10120:18:1;;91766:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34;;;;:::i;:::-;91759:41;91409:399;-1:-1:-1;;;;;91409:399:0:o;38368:1266::-;38484:4;38490:12;38552;38575:13;38599:24;38636:8;38626:19;;-1:-1:-1;;;;;38626:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38626:19:0;;38599:46;;39155:1;39125;39087:9;39081:16;39048:4;39037:9;39033:20;38998:1;38959:7;38929:4;38906:275;38894:287;;39250:16;39239:27;;39295:8;39286:7;39283:21;39280:78;;;39335:8;39324:19;;39280:78;39445:7;39432:11;39425:28;39567:7;39564:1;39557:4;39544:11;39540:22;39525:50;39604:8;;;;-1:-1:-1;38368:1266:0;-1:-1:-1;;;;;;38368:1266:0:o;44188:375::-;44464:8;44454:19;;;;;;44403:14;:27;44418:11;44403:27;;;;;;;;;;;;;;;44431:11;44403:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44403:48:0;;;;;;;;;:70;;;;44489:66;;;;44503:11;;44516;;44444:6;;44537:8;;44547:7;;44489:66;:::i;:::-;;;;;;;;44188:375;;;;;:::o;33246:420::-;33382:21;33406:28;33419:14;33406:12;:28::i;:::-;33464;;;;33445:16;33464:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;33382:52;;-1:-1:-1;33518:15:0;33510:54;;;;-1:-1:-1;;;33510:54:0;;33827:2:1;33510:54:0;;;33809:21:1;33866:2;33846:18;;;33839:30;33905:28;33885:18;;;33878:56;33951:18;;33510:54:0;33625:350:1;33510:54:0;33603:23;33617:9;33603:11;:23;:::i;:::-;33583:16;:43;;33575:83;;;;-1:-1:-1;;;33575:83:0;;34182:2:1;33575:83:0;;;34164:21:1;34221:2;34201:18;;;34194:30;34260:29;34240:18;;;34233:57;34307:18;;33575:83:0;33980:351:1;57676:182:0;57742:16;;57789:22;91902:9;57789:7;:22;:::i;:::-;57782:29;-1:-1:-1;57836:14:0;57782:29;57836:7;:14;:::i;:::-;57822:28;;57676:182;;;:::o;90288:732::-;90389:4;-1:-1:-1;;;;;90414:21:0;;736:10;90414:21;90406:75;;;;-1:-1:-1;;;90406:75:0;;34655:2:1;90406:75:0;;;34637:21:1;34694:2;34674:18;;;34667:30;34733:34;34713:18;;;34706:62;-1:-1:-1;;;34784:18:1;;;34777:39;34833:19;;90406:75:0;34453:405:1;90406:75:0;90504:44;90518:5;90533:4;90540:7;90504:13;:44::i;:::-;90494:54;;90671:11;90684:9;90697:20;90709:7;90697:11;:20::i;:::-;90670:47;;-1:-1:-1;90670:47:0;-1:-1:-1;90732:8:0;;90728:50;;90742:36;-1:-1:-1;;;;;90742:10:0;:23;90766:5;90773:4;90742:23;:36::i;:::-;90849:6;90831:14;;:24;;;;;;;:::i;:::-;;;;-1:-1:-1;90866:8:0;;-1:-1:-1;90877:24:0;-1:-1:-1;;;;;90877:6:0;:24::i;:::-;90866:35;;90927:14;;90920:3;:21;;90912:74;;;;-1:-1:-1;;;90912:74:0;;35065:2:1;90912:74:0;;;35047:21:1;35104:2;35084:18;;;35077:30;35143:34;35123:18;;;35116:62;-1:-1:-1;;;35194:18:1;;;35187:38;35242:19;;90912:74:0;34863:404:1;90912:74:0;-1:-1:-1;91006:6:0;;90288:732;-1:-1:-1;;;;;;90288:732:0:o;57301:238::-;57362:6;;57397:22;91902:9;57397:7;:22;:::i;:::-;57381:38;-1:-1:-1;;;;;;57438:28:0;;;57430:67;;;;-1:-1:-1;;;57430:67:0;;35474:2:1;57430:67:0;;;35456:21:1;35513:2;35493:18;;;35486:30;35552:28;35532:18;;;35525:56;35598:18;;57430:67:0;35272:350:1;32624:614:0;32908:32;;;32879:26;32908:32;;;:19;:32;;;;;32879:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32959:13;:20;32983:1;32959:25;32951:86;;;;-1:-1:-1;;;32951:86:0;;36214:2:1;32951:86:0;;;36196:21:1;36253:2;36233:18;;;36226:30;36292:34;36272:18;;;36265:62;-1:-1:-1;;;36343:18:1;;;36336:46;36399:19;;32951:86:0;36012:412:1;32951:86:0;33048:47;33066:11;33079:8;:15;33048:17;:47::i;:::-;33106:124;;-1:-1:-1;;;33106:124:0;;-1:-1:-1;;;;;33106:10:0;:15;;;;33129:10;;33106:124;;33141:11;;33154:13;;33169:8;;33179:14;;33195:18;;33215:14;;33106:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32868:370;32624:614;;;;;;:::o;58410:366::-;58627:12;49295:1;58694:10;58706:9;-1:-1:-1;;;;;59460:23:0;;58743:14;58759:8;58659:109;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58652:116;;58410:366;;;;;;;:::o;23754:307::-;23828:5;23871:10;:6;23880:1;23871:10;:::i;:::-;23854:6;:13;:27;;23846:59;;;;-1:-1:-1;;;23846:59:0;;38205:2:1;23846:59:0;;;38187:21:1;38244:2;38224:18;;;38217:30;-1:-1:-1;;;38263:18:1;;;38256:49;38322:18;;23846:59:0;38003:343:1;23846:59:0;-1:-1:-1;23985:29:0;24001:3;23985:29;23979:36;;23754:307::o;53883:414::-;53995:10;54007:15;54026:28;54045:8;54026:18;:28::i;:::-;53994:60;;-1:-1:-1;53994:60:0;-1:-1:-1;;;;;;54069:16:0;;54065:69;;54115:6;54102:20;;54065:69;54146:11;54160:16;54167:8;54160:6;:16::i;:::-;54146:30;;54196:34;54206:11;54219:2;54223:6;54196:9;:34::i;:::-;54187:43;;54278:2;-1:-1:-1;;;;;54248:41:0;54265:11;54248:41;;;54282:6;54248:41;;;;5349:25:1;;5337:2;5322:18;;5203:177;54248:41:0;;;;;;;;53983:314;;;53883:414;;;;:::o;55308:1859::-;55446:12;55460:10;55472:15;55489:27;55518:17;55539:35;55565:8;55539:25;:35::i;:::-;55445:129;;;;;;;;;;55587:13;55603:15;:28;55619:11;55603:28;;;;;;;;;;;;;;;55632:11;55603:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55603:49:0;;;;;;;;;;;;;;-1:-1:-1;55677:16:0;55684:8;55677:6;:16::i;:::-;55663:30;;55821:8;55816:167;;55855:45;55865:11;55886:4;55893:6;55855:9;:45::i;:::-;55915:28;;;;;;;:15;:28;;;;;;;:41;;55846:54;;-1:-1:-1;55967:4:0;;55915:41;;55944:11;;55915:41;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55915:49:0;;;;;;;;;;:56;;-1:-1:-1;;55915:56:0;;;;;;;;;;55816:167;-1:-1:-1;;;;;57261:20:0;;;55995:97;;56037:22;;-1:-1:-1;;;;;10165:32:1;;10147:51;;56037:22:0;;10135:2:1;10120:18;56037:22:0;;;;;;;56074:7;;;;;;;;;55995:97;56166:11;56214;56251:6;56291:8;56326:4;56355:2;56383:6;56431:14;56146:17;56516:8;:33;;56539:10;-1:-1:-1;;;;;56516:33:0;;;;56527:9;56516:33;56505:44;;56561:12;56575:19;56598:230;56646:9;56670:3;56711:31;;;56744:10;56756;56768:5;56775;56782:3;56787:7;56796:15;56813:3;56688:129;;;;;;;;;;;;;;;:::i;56598:230::-;56560:268;;;;56845:7;56841:319;;;56884:18;;;;;;56922:59;;;;;;;;;;56957:10;;56969:5;;56884:18;;56922:59;:::i;:::-;;;;;;;;56854:139;56841:319;;;57081:67;57101:10;57113;57125:5;57132:7;57141:6;57081:19;:67::i;:::-;55434:1733;;;;;;;;;;;;;;;;;;55308:1859;;;;;:::o;82722:177::-;82832:58;;-1:-1:-1;;;;;39824:32:1;;82832:58:0;;;39806:51:1;39873:18;;;39866:34;;;82805:86:0;;82825:5;;-1:-1:-1;;;82855:23:0;39779:18:1;;82832:58:0;;;;-1:-1:-1;;82832:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;82832:58:0;-1:-1:-1;;;;;;82832:58:0;;;;;;;;;;82805:19;:86::i;:::-;82722:177;;;:::o;83144:205::-;83272:68;;-1:-1:-1;;;;;40169:15:1;;;83272:68:0;;;40151:34:1;40221:15;;40201:18;;;40194:43;40253:18;;;40246:34;;;83245:96:0;;83265:5;;-1:-1:-1;;;83295:27:0;40086:18:1;;83272:68:0;39911:375:1;33674:271:0;33756:13;33815:2;33790:14;:21;:27;;33782:68;;;;-1:-1:-1;;;33782:68:0;;40493:2:1;33782:68:0;;;40475:21:1;40532:2;40512:18;;;40505:30;40571;40551:18;;;40544:58;40619:18;;33782:68:0;40291:352:1;33782:68:0;-1:-1:-1;33923:2:0;33903:23;33897:30;;33674:271::o;57547:121::-;57612:4;57636:24;91902:9;-1:-1:-1;;;;;57636:24:0;;;:::i;33953:402::-;34076:35;;;34052:21;34076:35;;;:22;:35;;;;;;;34126:21;;;34122:138;;-1:-1:-1;30881:5:0;34122:138;34294:16;34278:12;:32;;34270:77;;;;-1:-1:-1;;;34270:77:0;;40850:2:1;34270:77:0;;;40832:21:1;;;40869:18;;;40862:30;40928:34;40908:18;;;40901:62;40980:18;;34270:77:0;40648:356:1;58059:343:0;58141:10;;;58189:19;:8;58141:10;58189:16;:19::i;:::-;:30;;;:55;;;;;58223:8;:15;58242:2;58223:21;58189:55;58181:92;;;;-1:-1:-1;;;58181:92:0;;41211:2:1;58181:92:0;;;41193:21:1;41250:2;41230:18;;;41223:30;-1:-1:-1;;;41269:18:1;;;41262:54;41333:18;;58181:92:0;41009:348:1;58181:92:0;58291:22;:8;58310:2;58291:18;:22::i;:::-;58286:27;-1:-1:-1;58373:21:0;:8;58391:2;58373:17;:21::i;:::-;58362:32;;58059:343;;;:::o;91028:373::-;91124:4;91159:7;91141:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;91277:4:0;-1:-1:-1;;;;;91255:27:0;;;91251:74;;-1:-1:-1;91306:7:0;91299:14;;91251:74;91344:49;91366:4;91373:10;91385:7;91344:13;:49::i;58784:557::-;58889:12;;;58932:20;58889:12;49295:1;58995:19;:8;58889:12;58995:16;:19::i;:::-;:39;;;58987:76;;;;-1:-1:-1;;;58987:76:0;;41211:2:1;58987:76:0;;;41193:21:1;41250:2;41230:18;;;41223:30;-1:-1:-1;;;41269:18:1;;;41262:54;41333:18;;58987:76:0;41009:348:1;58987:76:0;59081:22;:8;59100:2;59081:18;:22::i;:::-;59076:27;-1:-1:-1;59163:21:0;:8;59181:2;59163:17;:21::i;:::-;59152:32;-1:-1:-1;59202:22:0;:8;59221:2;59202:18;:22::i;:::-;59195:29;-1:-1:-1;59251:21:0;:8;59269:2;59251:17;:21::i;:::-;59235:37;;59293:40;59308:2;59330;59312:8;:15;:20;;;;:::i;:::-;59293:8;;:40;:14;:40::i;:::-;59283:50;;58784:557;;;;;;;:::o;87008:649::-;87432:23;87458:69;87486:4;87458:69;;;;;;;;;;;;;;;;;87466:5;-1:-1:-1;;;;;87458:27:0;;;:69;;;;;:::i;:::-;87432:95;;87546:10;:17;87567:1;87546:22;:56;;;;87583:10;87572:30;;;;;;;;;;;;:::i;:::-;87538:111;;;;-1:-1:-1;;;87538:111:0;;41814:2:1;87538:111:0;;;41796:21:1;41853:2;41833:18;;;41826:30;41892:34;41872:18;;;41865:62;-1:-1:-1;;;41943:18:1;;;41936:40;41993:19;;87538:111:0;41612:406:1;23386:360:0;23462:7;23507:11;:6;23516:2;23507:11;:::i;:::-;23490:6;:13;:28;;23482:62;;;;-1:-1:-1;;;23482:62:0;;42225:2:1;23482:62:0;;;42207:21:1;42264:2;42244:18;;;42237:30;-1:-1:-1;;;42283:18:1;;;42276:51;42344:18;;23482:62:0;42023:345:1;23482:62:0;-1:-1:-1;23636:30:0;23652:4;23636:30;23630:37;-1:-1:-1;;;23626:71:0;;;23386:360::o;24707:311::-;24782:6;24826:10;:6;24835:1;24826:10;:::i;:::-;24809:6;:13;:27;;24801:60;;;;-1:-1:-1;;;24801:60:0;;42575:2:1;24801:60:0;;;42557:21:1;42614:2;42594:18;;;42587:30;-1:-1:-1;;;42633:18:1;;;42626:50;42693:18;;24801:60:0;42373:344:1;24801:60:0;-1:-1:-1;24942:29:0;24958:3;24942:29;24936:36;;24707:311::o;25990:326::-;26066:7;26111:11;:6;26120:2;26111:11;:::i;:::-;26094:6;:13;:28;;26086:62;;;;-1:-1:-1;;;26086:62:0;;42924:2:1;26086:62:0;;;42906:21:1;42963:2;42943:18;;;42936:30;-1:-1:-1;;;42982:18:1;;;42975:51;43043:18;;26086:62:0;42722:345:1;26086:62:0;-1:-1:-1;26236:30:0;26252:4;26236:30;26230:37;;25990:326::o;76657:195::-;76760:12;76792:52;76814:6;76822:4;76828:1;76831:12;76760;77997;78011:23;78038:6;-1:-1:-1;;;;;78038:11:0;78057:5;78064:4;78038:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77996:73;;;;78087:69;78114:6;78122:7;78131:10;78143:12;78087:26;:69::i;:::-;78080:76;77709:455;-1:-1:-1;;;;;;;77709:455:0:o;80214:644::-;80399:12;80428:7;80424:427;;;80456:10;:17;80477:1;80456:22;80452:290;;-1:-1:-1;;;;;57261:20:0;;;80666:60;;;;-1:-1:-1;;;80666:60:0;;43681:2:1;80666:60:0;;;43663:21:1;43720:2;43700:18;;;43693:30;43759:31;43739:18;;;43732:59;43808:18;;80666:60:0;43479:353:1;80666:60:0;-1:-1:-1;80763:10:0;80756:17;;80424:427;80806:33;80814:10;80826:12;81527:17;;:21;81523:388;;81759:10;81753:17;81816:15;81803:10;81799:2;81795:19;81788:44;81523:388;81886:12;81879:20;;-1:-1:-1;;;81879:20:0;;;;;;;;:::i;14:159:1:-;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;;1024:2;1013:9;1009:18;996:32;-1:-1:-1;;;;;1088:2:1;1080:6;1077:14;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:286::-;1631:6;1684:2;1672:9;1663:7;1659:23;1655:32;1652:52;;;1700:1;1697;1690:12;1652:52;1726:23;;-1:-1:-1;;;;;;1778:32:1;;1768:43;;1758:71;;1825:1;1822;1815:12;2056:184;2114:6;2167:2;2155:9;2146:7;2142:23;2138:32;2135:52;;;2183:1;2180;2173:12;2135:52;2206:28;2224:9;2206:28;:::i;2245:252::-;2312:6;2320;2373:2;2361:9;2352:7;2348:23;2344:32;2341:52;;;2389:1;2386;2379:12;2341:52;2412:28;2430:9;2412:28;:::i;:::-;2402:38;2487:2;2472:18;;;;2459:32;;-1:-1:-1;;;2245:252:1:o;2502:131::-;-1:-1:-1;;;;;2577:31:1;;2567:42;;2557:70;;2623:1;2620;2613:12;2638:160;2703:5;2748:2;2739:6;2734:3;2730:16;2726:25;2723:45;;;2764:1;2761;2754:12;2723:45;-1:-1:-1;2786:6:1;2638:160;-1:-1:-1;2638:160:1:o;2803:780::-;2938:6;2946;2954;2962;2970;2978;3031:3;3019:9;3010:7;3006:23;3002:33;2999:53;;;3048:1;3045;3038:12;2999:53;3087:9;3074:23;3106:31;3131:5;3106:31;:::i;:::-;3156:5;-1:-1:-1;3180:37:1;3213:2;3198:18;;3180:37;:::i;:::-;3170:47;;3264:2;3253:9;3249:18;3236:32;3226:42;;3315:2;3304:9;3300:18;3287:32;3277:42;;3366:3;3355:9;3351:19;3338:33;3328:43;;3422:3;3411:9;3407:19;3394:33;-1:-1:-1;;;;;3442:6:1;3439:30;3436:50;;;3482:1;3479;3472:12;3436:50;3505:72;3569:7;3560:6;3549:9;3545:22;3505:72;:::i;:::-;3495:82;;;2803:780;;;;;;;;:::o;3588:118::-;3674:5;3667:13;3660:21;3653:5;3650:32;3640:60;;3696:1;3693;3686:12;3711:748;3813:6;3821;3829;3837;3845;3853;3906:3;3894:9;3885:7;3881:23;3877:33;3874:53;;;3923:1;3920;3913:12;3874:53;3946:28;3964:9;3946:28;:::i;:::-;3936:38;;4021:2;4010:9;4006:18;3993:32;3983:42;;4072:2;4061:9;4057:18;4044:32;4034:42;;4126:2;4115:9;4111:18;4098:32;4139:28;4161:5;4139:28;:::i;:::-;4186:5;-1:-1:-1;4242:3:1;4227:19;;4214:33;-1:-1:-1;;;;;4259:30:1;;4256:50;;;4302:1;4299;4292:12;4256:50;4341:58;4391:7;4382:6;4371:9;4367:22;4341:58;:::i;4717:481::-;4795:6;4803;4811;4864:2;4852:9;4843:7;4839:23;4835:32;4832:52;;;4880:1;4877;4870:12;4832:52;4903:28;4921:9;4903:28;:::i;:::-;4893:38;;4982:2;4971:9;4967:18;4954:32;-1:-1:-1;;;;;5001:6:1;4998:30;4995:50;;;5041:1;5038;5031:12;4995:50;5080:58;5130:7;5121:6;5110:9;5106:22;5080:58;:::i;:::-;4717:481;;5157:8;;-1:-1:-1;5054:84:1;;-1:-1:-1;;;;4717:481:1:o;5385:1162::-;5548:6;5556;5564;5572;5580;5588;5596;5604;5612;5665:3;5653:9;5644:7;5640:23;5636:33;5633:53;;;5682:1;5679;5672:12;5633:53;5721:9;5708:23;5740:31;5765:5;5740:31;:::i;:::-;5790:5;-1:-1:-1;5814:37:1;5847:2;5832:18;;5814:37;:::i;:::-;5804:47;;5898:2;5887:9;5883:18;5870:32;5860:42;;5949:2;5938:9;5934:18;5921:32;5911:42;;6000:3;5989:9;5985:19;5972:33;5962:43;;6056:3;6045:9;6041:19;6028:33;-1:-1:-1;;;;;6121:2:1;6113:6;6110:14;6107:34;;;6137:1;6134;6127:12;6107:34;6176:58;6226:7;6217:6;6206:9;6202:22;6176:58;:::i;:::-;6253:8;;-1:-1:-1;6150:84:1;-1:-1:-1;6150:84:1;;-1:-1:-1;6307:38:1;6340:3;6325:19;;6307:38;:::i;:::-;6297:48;;6398:3;6387:9;6383:19;6370:33;6354:49;;6428:2;6418:8;6415:16;6412:36;;;6444:1;6441;6434:12;6412:36;;6467:74;6533:7;6522:8;6511:9;6507:24;6467:74;:::i;:::-;6457:84;;;5385:1162;;;;;;;;;;;:::o;6552:247::-;6611:6;6664:2;6652:9;6643:7;6639:23;6635:32;6632:52;;;6680:1;6677;6670:12;6632:52;6719:9;6706:23;6738:31;6763:5;6738:31;:::i;6993:127::-;7054:10;7049:3;7045:20;7042:1;7035:31;7085:4;7082:1;7075:15;7109:4;7106:1;7099:15;7125:275;7196:2;7190:9;7261:2;7242:13;;-1:-1:-1;;7238:27:1;7226:40;;-1:-1:-1;;;;;7281:34:1;;7317:22;;;7278:62;7275:88;;;7343:18;;:::i;:::-;7379:2;7372:22;7125:275;;-1:-1:-1;7125:275:1:o;7405:186::-;7453:4;-1:-1:-1;;;;;7478:6:1;7475:30;7472:56;;;7508:18;;:::i;:::-;-1:-1:-1;7574:2:1;7553:15;-1:-1:-1;;7549:29:1;7580:4;7545:40;;7405:186::o;7596:815::-;7680:6;7688;7696;7749:2;7737:9;7728:7;7724:23;7720:32;7717:52;;;7765:1;7762;7755:12;7717:52;7788:28;7806:9;7788:28;:::i;:::-;7778:38;;7867:2;7856:9;7852:18;7839:32;-1:-1:-1;;;;;7886:6:1;7883:30;7880:50;;;7926:1;7923;7916:12;7880:50;7949:22;;8002:4;7994:13;;7990:27;-1:-1:-1;7980:55:1;;8031:1;8028;8021:12;7980:55;8067:2;8054:16;8092:48;8108:31;8136:2;8108:31;:::i;:::-;8092:48;:::i;:::-;8163:2;8156:5;8149:17;8203:7;8198:2;8193;8189;8185:11;8181:20;8178:33;8175:53;;;8224:1;8221;8214:12;8175:53;8279:2;8274;8270;8266:11;8261:2;8254:5;8250:14;8237:45;8323:1;8318:2;8313;8306:5;8302:14;8298:23;8291:34;8344:5;8334:15;;;;;8368:37;8401:2;8390:9;8386:18;8368:37;:::i;:::-;8358:47;;7596:815;;;;;:::o;8598:250::-;8683:1;8693:113;8707:6;8704:1;8701:13;8693:113;;;8783:11;;;8777:18;8764:11;;;8757:39;8729:2;8722:10;8693:113;;;-1:-1:-1;;8840:1:1;8822:16;;8815:27;8598:250::o;8853:270::-;8894:3;8932:5;8926:12;8959:6;8954:3;8947:19;8975:76;9044:6;9037:4;9032:3;9028:14;9021:4;9014:5;9010:16;8975:76;:::i;:::-;9105:2;9084:15;-1:-1:-1;;9080:29:1;9071:39;;;;9112:4;9067:50;;8853:270;-1:-1:-1;;8853:270:1:o;9128:217::-;9275:2;9264:9;9257:21;9238:4;9295:44;9335:2;9324:9;9320:18;9312:6;9295:44;:::i;9350:385::-;9422:6;9430;9438;9491:2;9479:9;9470:7;9466:23;9462:32;9459:52;;;9507:1;9504;9497:12;9459:52;9530:28;9548:9;9530:28;:::i;:::-;9520:38;;9608:2;9597:9;9593:18;9580:32;9621:28;9643:5;9621:28;:::i;:::-;9668:5;-1:-1:-1;9692:37:1;9725:2;9710:18;;9692:37;:::i;9740:256::-;9806:6;9814;9867:2;9855:9;9846:7;9842:23;9838:32;9835:52;;;9883:1;9880;9873:12;9835:52;9906:28;9924:9;9906:28;:::i;:::-;9896:38;;9953:37;9986:2;9975:9;9971:18;9953:37;:::i;:::-;9943:47;;9740:256;;;;;:::o;10209:1130::-;10339:6;10347;10355;10363;10371;10379;10387;10395;10403;10456:3;10444:9;10435:7;10431:23;10427:33;10424:53;;;10473:1;10470;10463:12;10424:53;10496:28;10514:9;10496:28;:::i;:::-;10486:38;;10571:2;10560:9;10556:18;10543:32;10533:42;;10622:2;10611:9;10607:18;10594:32;10584:42;;10677:2;10666:9;10662:18;10649:32;-1:-1:-1;;;;;10741:2:1;10733:6;10730:14;10727:34;;;10757:1;10754;10747:12;10727:34;10796:58;10846:7;10837:6;10826:9;10822:22;10796:58;:::i;:::-;10873:8;;-1:-1:-1;10770:84:1;-1:-1:-1;10770:84:1;;-1:-1:-1;10927:38:1;10960:3;10945:19;;10927:38;:::i;:::-;10917:48;;11015:3;11004:9;11000:19;10987:33;10974:46;;11029:28;11051:5;11029:28;:::i;:::-;11076:5;;-1:-1:-1;11134:3:1;11119:19;;11106:33;;11151:16;;;11148:36;;;11180:1;11177;11170:12;11148:36;;11219:60;11271:7;11260:8;11249:9;11245:24;11219:60;:::i;:::-;11193:86;;11298:8;11288:18;;;11325:8;11315:18;;;10209:1130;;;;;;;;;;;:::o;11852:622::-;11947:6;11955;11963;11971;11979;12032:3;12020:9;12011:7;12007:23;12003:33;12000:53;;;12049:1;12046;12039:12;12000:53;12072:28;12090:9;12072:28;:::i;:::-;12062:38;;12119:37;12152:2;12141:9;12137:18;12119:37;:::i;:::-;12109:47;;12203:2;12192:9;12188:18;12175:32;12165:42;;12258:2;12247:9;12243:18;12230:32;-1:-1:-1;;;;;12277:6:1;12274:30;12271:50;;;12317:1;12314;12307:12;12271:50;12356:58;12406:7;12397:6;12386:9;12382:22;12356:58;:::i;:::-;11852:622;;;;-1:-1:-1;11852:622:1;;-1:-1:-1;12433:8:1;;12330:84;11852:622;-1:-1:-1;;;11852:622:1:o;12672:324::-;12747:6;12755;12763;12816:2;12804:9;12795:7;12791:23;12787:32;12784:52;;;12832:1;12829;12822:12;12784:52;12855:28;12873:9;12855:28;:::i;:::-;12845:38;;12902:37;12935:2;12924:9;12920:18;12902:37;:::i;:::-;12892:47;;12986:2;12975:9;12971:18;12958:32;12948:42;;12672:324;;;;;:::o;13001:1205::-;13143:6;13151;13159;13167;13175;13183;13191;13199;13207;13215;13268:3;13256:9;13247:7;13243:23;13239:33;13236:53;;;13285:1;13282;13275:12;13236:53;13308:28;13326:9;13308:28;:::i;:::-;13298:38;;13387:2;13376:9;13372:18;13359:32;-1:-1:-1;;;;;13451:2:1;13443:6;13440:14;13437:34;;;13467:1;13464;13457:12;13437:34;13506:58;13556:7;13547:6;13536:9;13532:22;13506:58;:::i;:::-;13583:8;;-1:-1:-1;13480:84:1;-1:-1:-1;13480:84:1;;-1:-1:-1;13637:37:1;13670:2;13655:18;;13637:37;:::i;:::-;13627:47;;13721:2;13710:9;13706:18;13693:32;13683:42;;13775:3;13764:9;13760:19;13747:33;13734:46;;13789:31;13814:5;13789:31;:::i;:::-;13839:5;;-1:-1:-1;13891:3:1;13876:19;;13863:33;;-1:-1:-1;13949:3:1;13934:19;;13921:33;;13966:16;;;13963:36;;;13995:1;13992;13985:12;13963:36;;14034:60;14086:7;14075:8;14064:9;14060:24;14034:60;:::i;:::-;14008:86;;14113:8;14103:18;;;14140:8;14130:18;;;14195:3;14184:9;14180:19;14167:33;14157:43;;13001:1205;;;;;;;;;;;;;:::o;14211:460::-;14295:6;14303;14311;14319;14372:3;14360:9;14351:7;14347:23;14343:33;14340:53;;;14389:1;14386;14379:12;14340:53;14412:28;14430:9;14412:28;:::i;:::-;14402:38;;14459:37;14492:2;14481:9;14477:18;14459:37;:::i;:::-;14449:47;;14546:2;14535:9;14531:18;14518:32;14559:31;14584:5;14559:31;:::i;:::-;14211:460;;;;-1:-1:-1;14609:5:1;;14661:2;14646:18;14633:32;;-1:-1:-1;;14211:460:1:o;15035:380::-;15114:1;15110:12;;;;15157;;;15178:61;;15232:4;15224:6;15220:17;15210:27;;15178:61;15285:2;15277:6;15274:14;15254:18;15251:38;15248:161;;15331:10;15326:3;15322:20;15319:1;15312:31;15366:4;15363:1;15356:15;15394:4;15391:1;15384:15;15420:271;15603:6;15595;15590:3;15577:33;15559:3;15629:16;;15654:13;;;15629:16;15420:271;-1:-1:-1;15420:271:1:o;16363:521::-;16440:4;16446:6;16506:11;16493:25;16600:2;16596:7;16585:8;16569:14;16565:29;16561:43;16541:18;16537:68;16527:96;;16619:1;16616;16609:12;16527:96;16646:33;;16698:20;;;-1:-1:-1;;;;;;16730:30:1;;16727:50;;;16773:1;16770;16763:12;16727:50;16806:4;16794:17;;-1:-1:-1;16837:14:1;16833:27;;;16823:38;;16820:58;;;16874:1;16871;16864:12;16889:409;17091:2;17073:21;;;17130:2;17110:18;;;17103:30;17169:34;17164:2;17149:18;;17142:62;-1:-1:-1;;;17235:2:1;17220:18;;17213:43;17288:3;17273:19;;16889:409::o;17303:266::-;17391:6;17386:3;17379:19;17443:6;17436:5;17429:4;17424:3;17420:14;17407:43;-1:-1:-1;17495:1:1;17470:16;;;17488:4;17466:27;;;17459:38;;;;17551:2;17530:15;;;-1:-1:-1;;17526:29:1;17517:39;;;17513:50;;17303:266::o;17574:326::-;17769:6;17761;17757:19;17746:9;17739:38;17813:2;17808;17797:9;17793:18;17786:30;17720:4;17833:61;17890:2;17879:9;17875:18;17867:6;17859;17833:61;:::i;18260:401::-;18462:2;18444:21;;;18501:2;18481:18;;;18474:30;18540:34;18535:2;18520:18;;18513:62;-1:-1:-1;;;18606:2:1;18591:18;;18584:35;18651:3;18636:19;;18260:401::o;19446:184::-;19516:6;19569:2;19557:9;19548:7;19544:23;19540:32;19537:52;;;19585:1;19582;19575:12;19537:52;-1:-1:-1;19608:16:1;;19446:184;-1:-1:-1;19446:184:1:o;19635:127::-;19696:10;19691:3;19687:20;19684:1;19677:31;19727:4;19724:1;19717:15;19751:4;19748:1;19741:15;19767:128;19834:9;;;19855:11;;;19852:37;;;19869:18;;:::i;20258:360::-;20469:6;20461;20456:3;20443:33;20539:2;20535:15;;;;-1:-1:-1;;20531:53:1;20495:16;;20520:65;;;20609:2;20601:11;;20258:360;-1:-1:-1;20258:360:1:o;20748:544::-;20849:2;20844:3;20841:11;20838:448;;;20885:1;20910:5;20906:2;20899:17;20955:4;20951:2;20941:19;21025:2;21013:10;21009:19;21006:1;21002:27;20996:4;20992:38;21061:4;21049:10;21046:20;21043:47;;;-1:-1:-1;21084:4:1;21043:47;21139:2;21134:3;21130:12;21127:1;21123:20;21117:4;21113:31;21103:41;;21194:82;21212:2;21205:5;21202:13;21194:82;;;21257:17;;;21238:1;21227:13;21194:82;;21468:1348;21592:3;21586:10;-1:-1:-1;;;;;21611:6:1;21608:30;21605:56;;;21641:18;;:::i;:::-;21670:96;21759:6;21719:38;21751:4;21745:11;21719:38;:::i;:::-;21713:4;21670:96;:::i;:::-;21821:4;;21885:2;21874:14;;21902:1;21897:662;;;;22603:1;22620:6;22617:89;;;-1:-1:-1;22672:19:1;;;22666:26;22617:89;-1:-1:-1;;21425:1:1;21421:11;;;21417:24;21413:29;21403:40;21449:1;21445:11;;;21400:57;22719:81;;21867:943;;21897:662;20695:1;20688:14;;;20732:4;20719:18;;-1:-1:-1;;21933:20:1;;;22050:236;22064:7;22061:1;22058:14;22050:236;;;22153:19;;;22147:26;22132:42;;22245:27;;;;22213:1;22201:14;;;;22080:19;;22050:236;;;22054:3;22314:6;22305:7;22302:19;22299:201;;;22375:19;;;22369:26;-1:-1:-1;;22458:1:1;22454:14;;;22470:3;22450:24;22446:37;22442:42;22427:58;22412:74;;22299:201;-1:-1:-1;;;;;22546:1:1;22530:14;;;22526:22;22513:36;;-1:-1:-1;21468:1348:1:o;22821:498::-;23021:4;23050:6;23095:2;23087:6;23083:15;23072:9;23065:34;23147:2;23139:6;23135:15;23130:2;23119:9;23115:18;23108:43;;23187:6;23182:2;23171:9;23167:18;23160:34;23230:3;23225:2;23214:9;23210:18;23203:31;23251:62;23308:3;23297:9;23293:19;23285:6;23277;23251:62;:::i;24130:493::-;24379:6;24371;24367:19;24356:9;24349:38;24423:3;24418:2;24407:9;24403:18;24396:31;24330:4;24444:62;24501:3;24490:9;24486:19;24478:6;24470;24444:62;:::i;:::-;-1:-1:-1;;;;;24542:31:1;;;;24537:2;24522:18;;24515:59;-1:-1:-1;24605:2:1;24590:18;24583:34;24436:70;24130:493;-1:-1:-1;;;24130:493:1:o;25351:753::-;25684:6;25676;25672:19;25661:9;25654:38;25728:3;25723:2;25712:9;25708:18;25701:31;25635:4;25755:62;25812:3;25801:9;25797:19;25789:6;25781;25755:62;:::i;:::-;-1:-1:-1;;;;;25857:6:1;25853:31;25848:2;25837:9;25833:18;25826:59;25921:6;25916:2;25905:9;25901:18;25894:34;25965:6;25959:3;25948:9;25944:19;25937:35;26021:9;26013:6;26009:22;26003:3;25992:9;25988:19;25981:51;26049:49;26091:6;26083;26075;26049:49;:::i;:::-;26041:57;25351:753;-1:-1:-1;;;;;;;;;;;25351:753:1:o;26109:1202::-;-1:-1:-1;;;;;26226:3:1;26223:27;26220:53;;;26253:18;;:::i;:::-;26282:93;26371:3;26331:38;26363:4;26357:11;26331:38;:::i;:::-;26325:4;26282:93;:::i;:::-;26401:1;26426:2;26421:3;26418:11;26443:1;26438:615;;;;27097:1;27114:3;27111:93;;;-1:-1:-1;27170:19:1;;;27157:33;27111:93;-1:-1:-1;;21425:1:1;21421:11;;;21417:24;21413:29;21403:40;21449:1;21445:11;;;21400:57;27217:78;;26411:894;;26438:615;20695:1;20688:14;;;20732:4;20719:18;;-1:-1:-1;;26474:17:1;;;26574:9;26596:229;26610:7;26607:1;26604:14;26596:229;;;26699:19;;;26686:33;26671:49;;26806:4;26791:20;;;;26759:1;26747:14;;;;26626:12;26596:229;;;26600:3;26853;26844:7;26841:16;26838:159;;;26977:1;26973:6;26967:3;26961;26958:1;26954:11;26950:21;26946:34;26942:39;26929:9;26924:3;26920:19;26907:33;26903:79;26895:6;26888:95;26838:159;;;27040:1;27034:3;27031:1;27027:11;27023:19;27017:4;27010:33;26411:894;;26109:1202;;;:::o;27316:168::-;27389:9;;;27420;;27437:15;;;27431:22;;27417:37;27407:71;;27458:18;;:::i;27489:127::-;27550:10;27545:3;27541:20;27538:1;27531:31;27581:4;27578:1;27571:15;27605:4;27602:1;27595:15;27621:120;27661:1;27687;27677:35;;27692:18;;:::i;:::-;-1:-1:-1;27726:9:1;;27621:120::o;28614:647::-;28693:6;28746:2;28734:9;28725:7;28721:23;28717:32;28714:52;;;28762:1;28759;28752:12;28714:52;28795:9;28789:16;-1:-1:-1;;;;;28820:6:1;28817:30;28814:50;;;28860:1;28857;28850:12;28814:50;28883:22;;28936:4;28928:13;;28924:27;-1:-1:-1;28914:55:1;;28965:1;28962;28955:12;28914:55;28994:2;28988:9;29019:48;29035:31;29063:2;29035:31;:::i;29019:48::-;29090:2;29083:5;29076:17;29130:7;29125:2;29120;29116;29112:11;29108:20;29105:33;29102:53;;;29151:1;29148;29141:12;29102:53;29164:67;29228:2;29223;29216:5;29212:14;29207:2;29203;29199:11;29164:67;:::i;29266:555::-;29523:6;29515;29511:19;29500:9;29493:38;29567:3;29562:2;29551:9;29547:18;29540:31;29474:4;29594:45;29634:3;29623:9;29619:19;29611:6;29594:45;:::i;:::-;-1:-1:-1;;;;;29679:6:1;29675:31;29670:2;29659:9;29655:18;29648:59;29755:9;29747:6;29743:22;29738:2;29727:9;29723:18;29716:50;29783:32;29808:6;29800;29783:32;:::i;30541:640::-;30822:6;30810:19;;30792:38;;-1:-1:-1;;;;;30866:32:1;;30861:2;30846:18;;30839:60;30886:3;30930:2;30915:18;;30908:31;;;-1:-1:-1;;30962:45:1;;30987:19;;30979:6;30962:45;:::i;:::-;31057:6;31050:14;31043:22;31038:2;31027:9;31023:18;31016:50;31115:9;31107:6;31103:22;31097:3;31086:9;31082:19;31075:51;31143:32;31168:6;31160;31143:32;:::i;:::-;31135:40;30541:640;-1:-1:-1;;;;;;;;30541:640:1:o;31186:245::-;31265:6;31273;31326:2;31314:9;31305:7;31301:23;31297:32;31294:52;;;31342:1;31339;31332:12;31294:52;-1:-1:-1;;31365:16:1;;31421:2;31406:18;;;31400:25;31365:16;;31400:25;;-1:-1:-1;31186:245:1:o;31793:125::-;31858:9;;;31879:10;;;31876:36;;;31892:18;;:::i;32612:287::-;32741:3;32779:6;32773:13;32795:66;32854:6;32849:3;32842:4;32834:6;32830:17;32795:66;:::i;:::-;32877:16;;;;;32612:287;-1:-1:-1;;32612:287:1:o;32904:716::-;33207:6;33199;33195:19;33184:9;33177:38;33251:3;33246:2;33235:9;33231:18;33224:31;33158:4;33278:45;33318:3;33307:9;33303:19;33295:6;33278:45;:::i;:::-;-1:-1:-1;;;;;33363:6:1;33359:31;33354:2;33343:9;33339:18;33332:59;33439:9;33431:6;33427:22;33422:2;33411:9;33407:18;33400:50;33473:32;33498:6;33490;33473:32;:::i;:::-;33459:46;;33554:9;33546:6;33542:22;33536:3;33525:9;33521:19;33514:51;33582:32;33607:6;33599;33582:32;:::i;34336:112::-;34368:1;34394;34384:35;;34399:18;;:::i;:::-;-1:-1:-1;34433:9:1;;34336:112::o;36429:837::-;36778:6;36770;36766:19;36755:9;36748:38;36822:3;36817:2;36806:9;36802:18;36795:31;36729:4;36849:45;36889:3;36878:9;36874:19;36866:6;36849:45;:::i;:::-;36942:9;36934:6;36930:22;36925:2;36914:9;36910:18;36903:50;36976:32;37001:6;36993;36976:32;:::i;:::-;-1:-1:-1;;;;;37082:15:1;;;37077:2;37062:18;;37055:43;37135:15;;37129:3;37114:19;;37107:44;37188:22;;;37035:3;37167:19;;37160:51;36962:46;-1:-1:-1;37228:32:1;36962:46;37245:6;37228:32;:::i;:::-;37220:40;36429:837;-1:-1:-1;;;;;;;;;36429:837:1:o;37271:727::-;37593:3;37588;37584:13;37575:6;37570:3;37566:16;37562:36;37557:3;37550:49;37628:6;37624:1;37619:3;37615:11;37608:27;37532:3;-1:-1:-1;;;;;37658:3:1;37654:28;37734:2;37725:6;37720:3;37716:16;37712:25;37707:2;37702:3;37698:12;37691:47;37768:6;37763:2;37758:3;37754:12;37747:28;37827:2;37818:6;37813:3;37809:16;37805:25;37800:2;37795:3;37791:12;37784:47;;37860:6;37854:13;37876:75;37944:6;37939:2;37934:3;37930:12;37923:4;37915:6;37911:17;37876:75;:::i;:::-;37971:16;;;;37989:2;37967:25;;37271:727;-1:-1:-1;;;;;;;37271:727:1:o;38351:889::-;38671:4;38700:3;38742:6;38734;38730:19;38719:9;38712:38;38786:2;38781;38770:9;38766:18;38759:30;38812:44;38852:2;38841:9;38837:18;38829:6;38812:44;:::i;:::-;-1:-1:-1;;;;;38892:31:1;;38887:2;38872:18;;38865:59;38955:2;38940:18;;38933:34;;;-1:-1:-1;;;;;39004:32:1;;38998:3;38983:19;;38976:61;39024:3;39053:19;;39046:35;;;39118:22;;;39112:3;39097:19;;39090:51;38798:58;-1:-1:-1;39158:32:1;38798:58;39175:6;39158:32;:::i;:::-;39150:40;;;39227:6;39221:3;39210:9;39206:19;39199:35;38351:889;;;;;;;;;;;:::o;39245:382::-;39446:2;39435:9;39428:21;39409:4;39466:44;39506:2;39495:9;39491:18;39483:6;39466:44;:::i;:::-;-1:-1:-1;;;;;39546:31:1;;;;39541:2;39526:18;;39519:59;-1:-1:-1;39609:2:1;39594:18;39587:34;39458:52;39245:382;-1:-1:-1;39245:382:1:o;41362:245::-;41429:6;41482:2;41470:9;41461:7;41457:23;41453:32;41450:52;;;41498:1;41495;41488:12;41450:52;41530:9;41524:16;41549:28;41571:5;41549:28;:::i
Swarm Source
ipfs://4495807a73f54df216e7031f0d93c92bdc992182a5b4b976b789686dedbed272
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.